1. 全局安裝create-vite-app
yarn global add create-vite-app@1.18.0
2.創(chuàng)建項(xiàng)目目錄
cva vue3-ui
或者
create-vite-app vue3-ui
Vue 2 和 Vue 3 的區(qū)別
90% 的寫法完全一致,除了以下幾點(diǎn)
- Vue 3 的 Template 支持多個(gè)根標(biāo)簽,Vue 2 不支持
- Vue 3 有 createApp(),而 Vue 2 的是 new Vue()
- createApp(組件),new Vue({template, render})
3.引入Vue Router4
3.1. 使用命令行查看vue-router 所有版本號(hào)
npm info vue-router versions

安裝最新的vue-router@4.0.0-beta.6
yarn add vue-router@4.0.0-beta.6
3.2. 初始化vue-router
1). 新建 history 對(duì)象
import {createWebHashHistory, createRouter} from 'vue-router'
const history = createWebHashHistory()
2). 新建 router 對(duì)象
const router = createRouter()
3). 引入 TypeScript
把main.js文件改為main.ts,我們會(huì)發(fā)現(xiàn)有很多報(bào)錯(cuò)
報(bào)錯(cuò)1:createRouter里面需要傳入一個(gè)參數(shù),但我們卻傳入了0個(gè)
解決:
const router = createRouter({
history,
routes: [
{ path: '/', component: Lifa }
]
})
報(bào)錯(cuò)2:.vue類型的文件提示cannot find module xxx.vue
原因ts只能理解.ts為后綴的文件,無法理解.vue文件
解決方法:
- Google 搜索 Vue 3 can not find module
- 創(chuàng)建 xxx.d.ts,告訴 TS 如何理解 .vue 文件
- src/shims-vue.d.ts
declare module '*.vue' {
import { Component } from 'vue'
const component: Component
export default component
}
這里要注意如果我們用的是vscode這時(shí)報(bào)錯(cuò)已經(jīng)沒了,但是如果我們用的是webstrom編輯器它還是會(huì)報(bào)同樣的錯(cuò)誤,我們需要再額外的安裝ts,然后初始化ts配置
yarn add typescript -D
tsc --init
這樣報(bào)錯(cuò)就會(huì)解決了
4). 使用router
const app = createApp(App)
app.use(router)
app.mount('#app')
5). 添加 <router-view>
- App.vue
<template>
<div>hi</div>
<router-view/>
</template>
<script>
export default {
name: 'App'
}
</script>
6). 添加 <router-link>
<div>導(dǎo)航欄 |
<router-link to="/">lifa</router-link>
<router-link to="xxx">lifa2</router-link>
</div>
4. 安裝sass
yarn add sass
發(fā)現(xiàn)控制臺(tái)報(bào)錯(cuò)

解決方法:
4.1 打開package.json
4.2. 把dependencies里的sass這一行,移到devDependencies

4.3. 重新運(yùn)行yarn install
5. 使用provide和inject實(shí)現(xiàn)父子組件通信
5.1. 在父組件里使用provide提供一個(gè)變量值,provide第一個(gè)參數(shù)是變量名,第二個(gè)是對(duì)應(yīng)的值
- App.vue
<script lang="ts">
import { ref, provide } from 'vue'
export default {
name: 'App',
setup() {
const menuVisible = ref(false)
provide('xxx', menuVisible)
}
}
5.2. 在子組件里通過inject使用這個(gè)變量,括號(hào)里的就是你設(shè)置的provide的key值
- topnav.vue
import { inject, Ref } from 'vue'
export default {
name: 'TopNav',
setup() {
const menuVisible = inject<Ref<boolean>>('xxx')
console.log(menuVisible.value, 'topNav menuvisible')
}
}
6. 路由間切換
- Doc.vue
<li>
<router-link to="/doc/switch">Switch 組件</router-link>
</li>
<main>
<router-view></router-view>
</main>
- mian.ts
const router = createRouter({
history,
routes: [
{ path: '/', component: Home },
{ path: '/doc', component: Doc, children: [
{ path: 'switch', component: SwitchDemo }
]
}
]
})
router.afterEach(() => {
console.log('路由切換了')
})
實(shí)現(xiàn)點(diǎn)擊菜單跳轉(zhuǎn)關(guān)閉左側(cè)菜單欄
我們需要在路由離開的時(shí)候?qū)enuVisible的值設(shè)為false,但是我們?cè)趍ain.ts里拿不到menuVisible這個(gè)變量,那如果我們把router.afterEach放在App里就可以訪問這個(gè)變量了,但是這樣的話App里又訪問不到我們的router了,所以我們需要單獨(dú)構(gòu)建一個(gè)router.ts文件
- router.ts
import {createWebHashHistory, createRouter} from 'vue-router'
import Home from './views/Home.vue'
import Doc from './views/Doc.vue'
import SwitchDemo from './views/SwitchDemo.vue'
const history = createWebHashHistory()
export const router = createRouter({
history,
routes: [
{ path: '/', component: Home },
{ path: '/doc', component: Doc, children: [
{ path: 'switch', component: SwitchDemo }
]
}
]
})
- App.vue
import { router } from "./router";
setup() {
const width = document.documentElement.clientWidth
const menuVisible = ref(width > 500 ? true : false)
provide('xxx', menuVisible)
+ router.afterEach(() => {
+ menuVisible.value = false
+ })
}
- main.ts
import {router} from './router'
const app = createApp(App)
app.use(router)