4步使用 vue3 路由

?路由的基本使用步驟分為以下4

?第一步:定義路由組件:略

?第二步:定義路由鏈接和路由視圖:

<template><div class="app-container"><h1>App根組件</h1><router-link to="/home">首頁</router-link><router-link to="/about">關于</router-link><hr><router-view></router-view></div>
</template>

我們演示項目的定義路由鏈接與路由視圖如下:

<template><div class="home_container"><el-container><!--頭部 start-->	<el-header class="top-header"><el-text class="home_title">東軟云醫院HIS系統</el-text><div class="home_userinfoContainer" ><el-dropdown  @command="handleCommand"><el-button type="primary"><el-avatar size="small" style="margin-right:10px ;"src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" />{{userStore.getUserInfo.value.realName}}<el-icon class="el-icon--right"><arrow-down /></el-icon>				</el-button><template #dropdown><el-dropdown-menu><el-dropdown-item command="" >我的設置</el-dropdown-item><el-dropdown-item command="logout">退出登錄</el-dropdown-item></el-dropdown-menu></template></el-dropdown>  </div></el-header><!--頭部 end-->	<el-container><!--左側邊欄 start  -->  <el-aside width="200px" ><el-menudefault-active="2"class="el-menu-vertical-demo"router  @select="addTab" style="height: 700px"><el-menu-item><el-icon><document /></el-icon><el-text class="mx-1" size="large">{{menus.meta.title}}</el-text></el-menu-item><el-menu-item  v-for="(menu,index) in menus.children" :index="menu.path"  :key="menu.path" ><el-icon><document /></el-icon>{{menu.name}}</el-menu-item></el-menu></el-aside><!--左側邊欄 end  --> <el-container><el-main class="main"><el-tabs v-model="editableTabsValue" type="card" editable @edit="handleTabsEdit" @tab-click="clickTag" ><el-tab-panealign="center":key="item.name"v-for="(item, index) in editableTabs":label="item.title":name="item.name":route="item.route"><router-view></router-view> </el-tab-pane></el-tabs>	</el-main>	</el-container>	</el-container></el-container></div>
</template><script setup>
import {computed, ref} from 'vue'
import { useRouter } from 'vue-router'
import { postReq } from '../utils/api'
import { useUserStore } from '../store/user.js'
//路由
const router = useRouter()
//獲取用戶倉庫對象
const userStore=useUserStore()
const menus=router.options.routes.find(m=>m.role==userStore.getUserInfo.value.useType);
const editableTabsValue=ref('')
const editableTabs=ref([])
const tabIndex=ref(0)//查找路徑對應的路由
function findCompontByPath(path){let a=menus.children.find(m=>m.path==path);if (a) {return a;}return null;
}//打開新窗口
function clickTag(tag,e){//console.log(tag.paneName)router.push(tag.paneName)
}
function addTab(path){if(path){let componet=findCompontByPath(path)if (componet) {if (!editableTabs.value.find(t => t.name == componet.path)) {editableTabs.value.push({title: componet.name,name: componet.path,route: componet.path});}editableTabsValue.value = componet.path;router.push(componet.path);}}	
}function handleTabsEdit(targetName, action) {if (action === 'remove') {let tabs = editableTabs.value;let activeName = editableTabsValue.value;if (activeName === targetName) {tabs.forEach((tab, index) => {// console.log(tab.name, targetName, tab.name === targetName);if (tab.name === targetName) {let nextTab = tabs[index + 1] || tabs[index - 1];if (nextTab) {activeName = nextTab.name;}}});}editableTabsValue.value = activeName;editableTabs.value = tabs.filter(tab => tab.name !== targetName);router.push(activeName);}
}function handleCommand(command){postReq("/user/logout").then(resp=>{if(resp.data.result){userStore.logOut();router.push("/login")}})}</script><style>
.home_container {height: 100%;position: absolute;top: 0px;left: 0px;width: 100%;
}
.top-header{background-color: #20a0ff;color: #333;text-align: center;display: flex;align-items: center;justify-content: space-between;
}
.left-aside{background-color: #ECECEC;
}.main{width: 100%;height: 100%;background-color: #fff;color: #000;text-align: left;
}
.home_title {color: #fff;font-size: 22px;display: inline;
}.home_userinfo {color: #fff;cursor: pointer;
}.home_userinfoContainer {display: inline;margin-right: 20px;text-align: right;
}
</style>

在 Vue Router 中,<router-view></router-view>?組件的內容變化是基于當前的路由匹配結果。

路由匹配與視圖渲染的工作原理

  1. 路由配置:Vue Router 的路由配置存儲在?router.options.routes?中,您的代碼通過?menus=router.options.routes.find(m=>m.role==userStore.getUserInfo.value.useType)?來獲取當前用戶角色對應的路由配置。

  2. 動態路由切換

    • 當用戶點擊左側菜單的菜單項時,addTab?方法會被觸發
    • 該方法會根據路徑找到對應的路由組件
    • 如果該路由尚未在標簽頁中打開,則添加一個新標簽頁
    • 然后通過?router.push(componet.path)?觸發路由切換
  3. 標簽頁點擊事件

    • 當用戶點擊標簽頁時,clickTag?方法會被觸發
    • 該方法同樣通過?router.push(tag.paneName)?觸發路由切換
  4. 標簽頁關閉事件

    • 當用戶關閉標簽頁時,handleTabsEdit?方法會被觸發
    • 如果關閉的是當前激活的標簽頁,會自動切換到下一個或上一個標簽頁
    • 同樣通過?router.push(activeName)?來更新當前路由
  5. 視圖更新

    • 當路由發生變化時,Vue Router 會自動查找與當前路徑匹配的組件
    • 然后將匹配到的組件渲染到?<router-view></router-view>?組件所在的位置
    • 這就是為什么您的代碼中,每個標簽頁的內容都是?<router-view></router-view>,但顯示的內容卻不同

關鍵邏輯分析

在您的代碼中,路由切換的核心邏輯是通過以下幾個方法實現的:

  • addTab(path):當用戶點擊左側菜單時,添加標簽頁并切換路由
  • clickTag(tag,e):當用戶點擊標簽頁時,切換到對應的路由
  • handleTabsEdit(targetName, action):當用戶關閉標簽頁時,更新當前激活的標簽頁并切換路由

這些方法都通過?router.push()?來觸發路由切換,而?<router-view></router-view>?會根據當前的路由自動渲染匹配的組件。

第三步:創建路由模塊:

import {createRouter, createWebHistory, createWebHashHistory} from 'vue-router'
import { defineAsyncComponent } from 'vue'
import { useUserStore } from '../store/user.js'const router = createRouter({ history: createWebHistory(),  // history 模式routes: [{path: '/',name: 'Login',role:0,component: defineAsyncComponent(() => import(`../components/Login.vue`)),meta: {title: 'Login'}},{path: '/login',name: 'Login',role:0,component: defineAsyncComponent(() => import(`../components/Login.vue`)),meta: {title: 'Login'}},{path:'/home',name:'系統信息',component:defineAsyncComponent(() => import(`../components/home.vue`)),role:170,meta: {title: '系統信息'},children:[{path:'/constant',name:'常數類別管理',component:defineAsyncComponent(() => import(`../components/neusys/Constant.vue`)),},{path:'/constantitem',name:'常數項管理',component:defineAsyncComponent(() => import(`../components/neusys/ConstantItem.vue`)),},{path:'/department',name:'科室管理',component:defineAsyncComponent(() => import(`../components/neusys/Department.vue`)),},{path:'/user',name:'賬戶管理',component:defineAsyncComponent(() => import(`../components/neusys/User.vue`)),},{path:'/registlevel',name:'掛號級別管理',component:defineAsyncComponent(() => import(`../components/neusys/RegistLevel.vue`)),},{path:'/settlecategory',name:'結算級別管理',component:defineAsyncComponent(() => import(`../components/neusys/SettleCategory.vue`)),},{path:'/disecategory',name:'疾病分類管理',component:defineAsyncComponent(() => import(`../components/neusys/DiseCategory.vue`)),},{path:'/disease',name:'診斷目錄管理',component:defineAsyncComponent(() => import(`../components/neusys/Disease.vue`)),},{path:'/expense',name:'費用科目表',component:defineAsyncComponent(() => import(`../components/neusys/ExpenseClass.vue`)),},{path:'/fmeditem',name:'非藥品收費項目',component:defineAsyncComponent(() => import(`../components/neusys/Fmeditem.vue`)),},{path:'/rule',name:'排班規則',component:defineAsyncComponent(() => import(`../components/neusys/Rule.vue`)),},{path:'/scheduling',name:'排班計劃',component:defineAsyncComponent(() => import(`../components/neusys/Scheduling.vue`)),}]},{path: '/home',name: '掛號收費',role:171,component: defineAsyncComponent(() => import(`../components/home.vue`)),meta: {title: '掛號收費'},children:[{path:'/customer',name:'用戶管理',component:defineAsyncComponent(() => import(`../components/neureg/Customer.vue`)),},{path:'/medicalcard',name:'電子就診卡',component:defineAsyncComponent(() => import(`../components/neureg/MedicalCard.vue`)),},{path:'/register',name:'現場掛號',component:defineAsyncComponent(() => import(`../components/neureg/Register.vue`)),},{path:'/refund',name:'退號',component:defineAsyncComponent(() => import(`../components/neureg/Refund.vue`)),}]},{path: '/home',name: '門診醫生',role:172,component: defineAsyncComponent(() => import(`../components/home.vue`)),meta: {title: '門診醫生'},children:[{path:'/docHome',name:'門診病歷',component:defineAsyncComponent(() => import(`../components/neudoc/DocHome.vue`)),}]},]
})// 全局路由守衛
router.beforeEach((to, from, next) => {// let userLogin =  sessionStorage.getItem("userLogin");const userStore = useUserStore()// let isAuth=userStore.getUserInfo.value.isAuth;let isAuth=userStore.getUserInfo.value.isAuth;//判斷路由的別名不是登錄且未進行登錄認證,就跳轉去登錄if(to.name !== 'Login' && !isAuth){next({ name: 'Login' })}else if(to.name=="Login" && isAuth){//已登錄,不允許退回到登錄頁面next({ path: '/home' })}else{next()}
})router.afterEach((to, from)=>{// console.log(to, from)//console.log('afterEach')
})export default router

上面我們是用懶加載的方式喲:

	{path: '/',name: 'Login',role:0,component: defineAsyncComponent(() => import(`../components/Login.vue`)),meta: {title: 'Login'}},

命名路由

{ path: '路由路徑', name: '路由名稱', component: 組件 }

在定義路由匹配規則時,使用name屬性為路由匹配規則定義路由名稱,即可實現命名路由。當路由匹配規則有了路由名稱后,在定義路由鏈接或執行某些跳轉操作時,可以直接通過路由名稱表示相應的路由,不再需要通過路由路徑表示相應的路由。

我們通過如下方式使用它:

router.push(activeName);  // activeName為路由名稱

而且還有路由嵌套。

第四步:導入且掛載路由模塊:

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router'
import ElementPlus from 'element-plus';
import 'element-plus/theme-chalk/index.css';
import App from './App.vue'
import Axios from 'axios'const app=createApp(App)
app.use(router)
app.use(createPinia())
app.use(ElementPlus)
app.mount('#app')

編程式導航

????????Vue Router提供了useRouter()函數,使用它可以獲取全局路由實例,該全局路由實例中提供了常用的push()方法replace()方法go()方法,獲取全局路由實例的示例代碼如下。

?push方法:

?????????push()方法會向歷史記錄中添加一個新的記錄,以編程方式導航到一個新的URL。當用戶單擊瀏覽器后退按鈕時,會回到之前的URLpush()方法的參數可以是一個字符串路徑,或者一個描述地址的對象,示例代碼如下。

router.push('/about/tab1')			// 字符串路徑
router.push({ path: '/about/tab1' })		// 帶有路徑的對象
router.push({ name: 'user', params: { userId: '123'} })	// 命名路由
router.push({ path: '/user', query: { id: '1' } })		// 帶查詢參數,如:/user?id=1
router.push({ path: '/user', hash: '#admin' })		// 帶有Hash值,如:/user#admin

我們項目中也用到的 push:

function addTab(path){if(path){let componet=findCompontByPath(path)if (componet) {if (!editableTabs.value.find(t => t.name == componet.path)) {editableTabs.value.push({title: componet.name,name: componet.path,route: componet.path});}editableTabsValue.value = componet.path;router.push(componet.path);}}	
}

導航守衛?

·導航守衛用于控制路由的訪問權限。例如,訪問后臺主頁時,需要用戶處于已登錄狀態,如果沒有登錄,則跳轉到登錄頁面。用戶在登錄頁面進行登錄操作,若登錄成功,則跳轉到后臺主頁;若登錄失敗,則返回登錄頁面。

這里我們只介紹全局守衛,包括全局前置守衛beforeEach()和全局后置守衛afterEach(),在路由即將改變前和改變后進行觸發。

// 全局路由守衛
router.beforeEach((to, from, next) => {// let userLogin =  sessionStorage.getItem("userLogin");const userStore = useUserStore()// let isAuth=userStore.getUserInfo.value.isAuth;let isAuth=userStore.getUserInfo.value.isAuth;//判斷路由的別名不是登錄且未進行登錄認證,就跳轉去登錄if(to.name !== 'Login' && !isAuth){next({ name: 'Login' })}else if(to.name=="Login" && isAuth){//已登錄,不允許退回到登錄頁面next({ path: '/home' })}else{next()}
})

全局路由守衛 beforeEach 詳解

一、導航守衛的基本概念

在 Vue Router 中,導航守衛是一種攔截路由導航過程的機制,允許你在路由切換前后執行自定義邏輯。beforeEach是全局前置守衛,會在每次路由切換前被調用,是實現權限控制、登錄驗證等功能的核心機制。

二、beforeEach 守衛的參數解析

router.beforeEach((to, from, next) => {// 守衛邏輯
})

  • to: 即將要進入的目標路由對象
  • from: 當前導航正要離開的路由對象
  • next: 導航控制函數,必須調用此函數才能繼續導航過程

三、next 函數的核心作用

next函數是導航守衛的關鍵控制接口,它的作用是決定路由導航的后續動作。必須調用 next () 才能讓路由導航繼續,否則導航會被阻塞

根據調用方式的不同,next () 可以實現三種導航控制:

  1. next(): 允許導航繼續,進入目標路由
  2. next(false): 阻止導航,返回當前路由(如果是從其他路由導航過來)
  3. next({ path: '/new-path' }): 重定向到新路由,中斷當前導航并開始新的導航過程

四、代碼中的 next 函數應用場景

1. 未登錄時重定向到登錄頁

if (to.name !== 'Login' && !isAuth) {next({ name: 'Login' })  // 重定向到登錄頁
}

  • 當目標路由不是登錄頁且用戶未認證時
  • 通過next({ name: 'Login' })重定向到登錄路由
  • 這會中斷當前導航,開始向登錄頁的新導航
2. 已登錄時禁止訪問登錄頁

else if (to.name === 'Login' && isAuth) {next({ path: '/home' })  // 重定向到首頁
}

  • 當用戶已登錄卻嘗試訪問登錄頁時
  • 通過next({ path: '/home' })重定向到首頁
  • 確保已登錄用戶不會看到登錄界面
3. 允許正常導航

else {next()  // 允許導航繼續
}

  • 當導航符合條件(如已登錄且訪問非登錄頁)時
  • 調用next()讓導航過程繼續,進入目標路由

五、next 函數的使用規則與注意事項

1. 必須調用 next ()
  • 無論你想允許導航、阻止導航還是重定向,都必須調用 next ()
  • 如果不調用 next (),導航將被永久阻塞,頁面不會有任何反應
2. next () 的參數類型
參數類型示例作用描述
無參數next()繼續導航到目標路由
布爾值next(false)阻止導航,返回原路由
路由對象next({ path: '/login' })重定向到指定路由
錯誤對象next (new Error (' 導航錯誤 '))導航失敗并觸發錯誤處理
3. 調用時機與順序
  • 在守衛中可以有多個條件判斷,但最終必須有一個 next () 被調用
  • 多個全局守衛會按照注冊順序依次執行,每個守衛都必須調用 next () 才能繼續
4. 異步場景處理
  • 如果守衛中需要異步操作(如 API 請求驗證),必須在異步操作完成后調用 next ()
  • 示例:

    router.beforeEach(async (to, from, next) => {try {const userData = await fetchUserInfo()if (userData.isAuth) {next()} else {next({ name: 'Login' })}} catch (error) {next(error)}
    })
    

六、實際開發中的最佳實踐

  1. 權限控制

    • 在 beforeEach 中校驗用戶權限
    • 對未授權用戶重定向到登錄頁或提示錯誤
  2. 登錄狀態維護

    • 檢查用戶登錄狀態(如 token 有效性)
    • 過期時強制重新登錄
  3. 頁面訪問記錄

    • 記錄用戶訪問路徑,用于歷史回溯或行為分析
  4. 資源預加載

    • 在導航前預加載目標頁面所需的數據或資源

next函數是 Vue Router 導航守衛的 "交通信號燈",通過控制它的調用方式,你可以精確管理路由導航的流程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83832.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83832.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83832.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

VScode使用npm啟動項目以及npm install ,npm start報錯問題處理

安裝啟動步驟 打開cmd 輸入指令 npm -v 查看npm是否安裝&#xff0c;需要先安裝node.js node.js安裝&#xff1a;node.js安裝 安裝包下載后&#xff0c;一直點擊next &#xff0c;安裝完成&#xff0c;打開cmd 輸入 node -v 查看安裝是否成功 使用VScode 打開項目&#xf…

《仿盒馬》app開發技術分享-- 回收金提現記錄查詢(端云一體)

開發準備 上一節我們實現了回收金提現的功能&#xff0c;并且成功展示了當前賬戶的支出列表&#xff0c;但是我們的提現相關的記錄并沒有很好的給用戶做出展示&#xff0c;用戶只知道當前賬戶提現扣款&#xff0c;并不知道回收金的去向&#xff0c;這一節我們就要實現回收金記…

芯片的起點——從硅到晶圓制造

第1篇&#xff1a;芯片的起點——從硅到晶圓制造 在討論汽車芯片如何“上車”之前&#xff0c;我們必須先回到源頭&#xff0c;從一顆芯片是如何從沙子一步步煉成講起。很多人知道芯片很復雜&#xff0c;卻未必清楚它的每一層結構、每一道工藝有何意義。本系列文章將從硅的提純…

vscode python debugger 如何調試老版本python

找到老版本資源&#xff1a; 找到老版本python debugger插件&#xff0c;現在官方github 都是24之后的release 了&#xff0c;調不了3.6 老項目 pdb&#xff1a; 太麻煩 debugpy vscode python debugger 的底層實現&#xff0c;我們可以指定老版本的debugger 來調試&#…

MVCC 怎么實現的

? 什么是 MVCC?它是怎么實現的?(適合基礎不牢固者) 一、MVCC 是什么? MVCC 全稱是:Multi-Version Concurrency Control,中文叫:多版本并發控制。 主要用于解決數據庫的讀寫并發沖突問題,它的作用是讓讀操作無需加鎖,也能讀到符合事務隔離要求的數據版本。 你可以…

深度解析企業風控API技術實踐:構建全方位企業風險畫像系統

引言 在當前的商業環境中&#xff0c;企業風險評估已成為各類商業決策的重要依據。本文將從技術實踐的角度&#xff0c;詳細介紹企業風控API的集成應用&#xff0c;重點關注API的調用方式、數據結構以及風險維度的劃分&#xff0c;幫助開發者快速構建企業風險畫像系統。 關鍵…

Mac 系統 Node.js 安裝與版本管理指南

Mac 系統 Node.js 安裝與版本管理指南 一、環境檢查 在終端執行以下命令驗證當前環境&#xff1a; node -v # 查看 Node.js 版本&#xff08;未安裝會提示命令不存在&#xff09; npm -v # 查看 npm 版本&#xff08;需 Node.js 安裝完成后生效&#xff09;二、安裝方法 …

設備健康管理系統搭建全技術解析:從架構設計到智能運維實踐

在工業 4.0 與智能制造深度融合的當下&#xff0c;設備健康管理系統已成為企業實現數字化轉型的核心基礎設施。據 Gartner 數據顯示&#xff0c;采用智能設備健康管理系統的企業&#xff0c;平均可降低 30% 的非計劃停機成本。如何基于現代技術棧構建一套高效、精準的設備健康管…

React-router 路由歷史的模式和原理

在現代Web開發中,React Router已成為管理React應用程序中路由的流行工具。它不僅簡化了在單頁應用程序(SPA)中導航的過程,還提供了多種路由歷史的模式來適應不同的開發需求和環境。了解這些模式及其背后的原理對于構建高效、可維護的Web應用程序至關重要。本文將深入探討Re…

C++題解(35) 2025年順德區中小學生程序設計展示活動(初中組C++) 換位(一)

題目描述 小明班上是n行m列的座位排列&#xff0c;座位按照行列順序編號&#xff0c;如6行7列&#xff0c;那么第1行第1列座位號為1號、第1行第7列為7號、第3行第4列為18號&#xff0c;如此遞推。 現在期中考剛結束要進行全班換座位。班主任剛剛公布了換位指令&#xff0c;指…

征程 6 Cache 使用場景

一、緩存機制基礎 1.1 緩存類型對比 1.2 典型應用場景 緩存緩沖區 &#xff1a;適用于高頻 CPU 訪問場景&#xff08;如 AI 推理中間數據&#xff09; 非緩存緩沖區 &#xff1a;適用于設備直傳場景&#xff08;如 DMA 數據流&#xff09; 二、數據一致性問題深度解析 2.1…

山東大學軟件學院項目實訓-基于大模型的模擬面試系統-個人博客(十)

開發博客&#xff1a;AI面試官個性化出題MCP功能最終完善 本周作為項目開發的最后沖刺階段&#xff0c;我們致力于進一步增強AI面試官在個性化題目生成方面的能力。核心工作是新增和優化了一系列MCP&#xff08;Multi-turn Conversation Protocol&#xff09;工具&#xff0c;…

Rabbitmq后臺無法登錄問題解決

rabbitmq pod正常運行&#xff0c;查看pod日志也沒有發現異常報錯。 我們進入容器查看插件是否正常啟用&#xff1a; $ kubectl exec -it rabbitmq-hitch-0 -n rabbitmq -- rabbitmq-plugins list Listing plugins with pattern ".*" ...Configured: E explicitly…

期權入門介紹

文章目錄 1.基本概念2.期權損益圖買入看漲期權賣出看漲期權買入看跌期權賣出看跌期權 3.買賣邏輯3.1 買賣邏輯買入看漲期權賣出看漲期權買入看跌期權賣出看跌期權 3.2 決策依據 4.行權方式美式期權 (American Style)歐式期權 (European Style)百慕大期權 (Bermudan Style)關鍵區…

useMemo vs useCallback:React 性能優化的兩大利器

文章目錄 什么是 useMemo&#xff1f;基本語法使用場景實際例子 什么是 useCallback&#xff1f;基本語法使用場景實際例子 核心區別對比什么時候使用它們&#xff1f;使用 useMemo 的時機使用 useCallback 的時機 常見誤區和注意事項誤區 1&#xff1a;過度使用誤區 2&#xf…

C++ 記錄

1. 字符串查找字符 bool findMap(char ch){string mapper "aeiouAEIOU";return mapper.find(ch) ! string::npos;} 2.substr函數 string substr(size_t pos 0, size_t len npos) const; 3.to_string && stoi 函數 iota 填充一個范圍&#xff0…

樸樸超市小程序 sign-v2 分析

聲明 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包內容、敏感網址、數據接口等均已做脫敏處理&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01; 部分python代碼 cp execjs.compile(…

Azure 機器學習初學者指南

Azure 機器學習初學者指南 在我們的初學者指南中探索Azure機器學習&#xff0c;了解如何設置、部署模型以及在Azure生態系統中使用AutoML & ML Studio。Azure 機器學習 &#xff08;Azure ML&#xff09; 是一項全面的云服務&#xff0c;專為機器學習項目生命周期而設計&am…

HTML 從入門到起飛 · 系列合集:一站式學習不掉線

一、&#x1f4bb;計算機基礎 &#x1f31f;艾倫麥席森圖靈&#x1f31f; ?? 二戰時期&#xff0c;破譯了德軍的戰爭編碼——英格瑪。 &#x1f54a;? 讓二戰提前2年結束&#xff0c;拯救了上千萬人的生命。 &#x1f3c6; 設立圖靈獎&#xff0c;被后人譽為&#xff1a;&qu…

NodeJS的yarn和npm作用和區別,為什么建議用yarn

一、yarn和npm作用和區別 yarn異步執行安卓&#xff0c;npm同步執行安裝 yarn會復用&#xff0c;已經安裝的不會再次安裝。不過新版npm已經解決了。 Yarn安裝信息干凈一點&#xff0c;npm會羅列包信息 下面是關于 Node.js 中 npm 和 yarn 的完整對比與說明&#xff0c;幫你…