vite2.x 初始化項目
配置說明: https://cn.vitejs.dev/guide/#%E6%90%AD%E5%BB%BA%E7%AC%AC%E4%B8%80%E4%B8%AA-vite-%E9%A1%B9%E7%9B%AE
兼容性注意
Vite 需要 Node.js 版本 >= 12.0.0。
下面項目使用 ts, 初始化項目:
cnpm create @vitejs/app my-vue-app --template vue-ts
引入 vant , 實現按需加載+修改主題
需要安裝的一依賴包:cnpm install less sass vite-plugin-imp -D
關鍵代碼上圖圈住的,具體vite.config.ts配置文件如下:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vitePluginImp from 'vite-plugin-imp' const { resolve } = require('path') // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), // 按需引入 vitePluginImp({ libList: [ { libName: 'vant', style(name) { if (/CompWithoutStyleFile/i.test(name)) return false return `vant/es/${name}/index.less` } }, ] }) ], css: { preprocessorOptions: { // 重置vant的樣式變量:https://github.com/youzan/vant/blob/dev/src/style/var.less less: { modifyVars: { 'button-primary-color': 'red', 'button-primary-border-color': 'red' }, }, scss: { additionalData: ` @import "./src/styles/_var.scss"; @import "./src/styles/_mix.scss"; ` } } }, base: '/ybs', alias: [ { find: '/@', replacement: resolve(__dirname, 'src') }, { find: '/@ser', replacement: resolve(__dirname, 'src/services') }, { find: '/@comp', replacement: resolve(__dirname, 'src/components') } ], server: { port: 8080, proxy: { '/api': { target: 'http://10.9.129.13', changeOrigin: true, secure: false, } } } })
附加上vant的樣式變量:https://github.com/youzan/vant/blob/dev/src/style/var.less
其他配置基本和1.x版本一樣,可以參考下面說明
vite1.x 初始化項目
git地址: https://github.com/vitejs/vite
npm init vite-app <project-name> cd <project-name> npm install npm run dev
安裝常用插件:
{ "name": "xxx", "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build" }, "dependencies": { "@types/axios": "^0.14.0", "axios": "^0.21.0", "dayjs": "^1.9.7", "element-plus": "^v1.0.1-beta.14", "vue": "^3.0.4", "vue-router": "^4.0.1", "vuex": "^4.0.0-rc.2" }, "devDependencies": { "@vue/compiler-sfc": "^3.0.4", "sass": "^1.30.0", "typescript": "^4.1.3", "vite": "^1.0.0-rc.13" } }
添加配置文件:shims.d.ts(2.x版本會自動添加在src/shims-vue.d.ts)

declare module '*.vue' { import { ComponentOptions } from 'vue' const componentOptions: ComponentOptions export default componentOptions }
添加tsconfig.json
{ "compilerOptions": { "target": "esnext", "module": "esnext", "strict": true, "jsx": "preserve", "moduleResolution": "node", "allowSyntheticDefaultImports": true, /* 用來指定編譯時是否生成.map文件 */ "declarationMap": false, "sourceMap": false, "paths": { "/@/*": ["./src/*"], "/@ser/*": ["./src/services/*"], "/@comp/*": ["./src/components/*"] } }, "exclude": ["node_modules", "dist"] }
引入Vue Router4
安裝: cnpm i vue-router@next -S
使用命令行查看vue-router 所有版本號: npm info vue-router versions
route/index.ts:
import { RouteRecordRaw, createRouter, createWebHashHistory } from 'vue-router'; const routes: RouteRecordRaw[] = [ { path: '/home/:id', name: 'Home', component: () => import('../test/Home.vue'), }, { path: '/user', name: 'User', component: () => import('../views/User.vue'), }, ]; const router = createRouter({ history: createWebHashHistory(), routes, }); export default router;
添加UI插件 element-plus,main.ts 文件如下:
文檔: https://element-plus.gitee.io/#/zh-CN/component/i18n
element-ui 目前不支持vue3; 使用 element-plus,用法UI基本一樣
import { createApp } from 'vue' import App from './App.vue' import store from './store/index' import router from './router/index' import ElementPlus from 'element-plus' import zhLocale from 'element-plus/lib/locale/lang/zh-cn' // 國際化 import 'element-plus/lib/theme-chalk/index.css' import './styles/index.scss' createApp(App) .use(router) .use(store) .use(ElementPlus, { locale :zhLocale }) .mount('#app')
配置文件:vite.config.ts(vue2的vue.config.js,2.x 版本參考上面說明)
//git地址 https://github.com/vitejs/vite/blob/master/src/node/config.ts const path = require('path'); module.exports = { // 配置別名 alias: { '/@/': path.resolve(__dirname, './src'), '/@comp/': path.resolve(__dirname, './src/components'), }, // 端口,默認3000 port: '8080', // 是否自動在瀏覽器打開 open: true, // 配置部署基礎路徑 base: 'admin', // 引用全局 scss cssPreprocessOptions: { scss: { additionalData: ` @import "./src/styles/_var.scss"; @import "./src/styles/_mix.scss"; ` } }, // 為開發服務器配置自定義代理規則 proxy: { '/api': { target: 'http://10.110.52.28:8081', changeOrigin: true, secure: false, } } }
問題1: v-on="$listeners" 不能使用,v-bind="$attrs" 代替;
問題2:slot-scope="scope" 被廢棄, 使用 v-slot="scope"
問題3: scss 的 /deep/ 不能使用(至少在我寫這個博客時)
解決:使用 ::v-deep或者:deep(控制台會報警告,但總比不能使用好)
deep報錯:
問題4:修改全局的樣式,例如重置element樣式,保存可以立即生效,不過刷新還是原來一樣,需要重啟才生效;(2.x 版本已經解決)
問題5:import dayjs from 'dayjs' 報錯;
解決方法1:import * as dayjs from 'dayjs';
解決方法2:tsconfig.json,添加配置文件:
問題6: element-plus 默認英文,需要使用中文如下配置:
element-plus 版本在 v1.0.1-beta.14 時,還可以使用上面方法,后面不知道什么版本開始,就不能使用了 會報錯:
作者的解決方法:先在 node_nodules/element-plus/lib/locale/lang/zh-cn.js 找到配置,然后直接拿出來使用;
問題7:使用別名后,vetur報錯 Cannot find module
解決:tsconfig.json 文件添加路徑配置
{ "compilerOptions": { "target": "esnext", "module": "esnext", "sourceMap": true, "strict": true, "jsx": "preserve", "moduleResolution": "node", "paths": { "/@/*": ["./src/*"] } } }
問題8:import echarts from 'echarts' 報錯
解決:import * as echarts from 'echarts';
路由相關:
獲取當前路由:const route = useRoute(); 或者:
路由跳轉(之前一致):
監聽路由變化:
路由鈎子:
home頁面的鈎子:
404路由配置:
{
path: '/404',
name: '404',
component: () => import('/@/views/404.vue')
},
{
path: '/:pathMatch(.*)*',
redirect: '/404'
}
別名:
表示訪問url
時自由命名,不受約束,router
會自動進行別名匹配,就像我們設置/
的別名為/home
,相當於訪問/
const routes = [{ path: '/', component: Homepage, alias: '/home' }] // alias是別名的key
重定向:
// 路徑寫法 const routes = [{ path: '/home', redirect: '/' }] // 命名寫法 const routes = [{ path: '/home', redirect: { name: 'homepage' } }] // 函數寫法 const routes = [ { path: '/search/:searchText', redirect: to => { return { path: '/search', query: { q: to.params.searchText } } } }
路由插槽:
append、
event、
tag、
exact
上面列舉的4個屬性已經不再使用,改為作用域插槽:
<router-link to="/" v-slot="{ href, navigate, isActive }"> <li :class="{ 'active': isActive }"> <a :href="href" @click="navigate"> <span>Home</span> </a> </li> </router-link>
<router-view> <keep-alive> <transition>
現在必須通過v-slot API在router-view
內部使用transition
和keep-alive
<router-view v-slot="{ Component }"> <transition> <keep-alive> <component :is="Component" /> </keep-alive> </transition> </router-view>
動態路由:router.addRoute()
和router.removeRoute()
// addRoute 添加路由 router.addRoute({ name: 'about', path: '/about', component: About }) // removeRoute是刪除路由,刪除后對應的子路由和別名都會刪掉 router.removeRoute('about') // 路由嵌套 router.addRoute('about', { path: 'profile', component: Profile}) //等價於 router.addRoute({ name: 'about', path: '/about', component: About, children: [{ path: 'profile', component: Profile}], })
vuex 相關:
const store = useStore(); // state const list = computed(() => store.state.foodList); // getters const userInfo = store.getters.userInfo; // 觸發mutations,改變值: store.commit('setFoodList', resList); // 觸發actions異步操作,改變值: store.dispatch(`login`)
對於復雜的業務可以封裝一個hook,例子:
function useContentData(store: Store<IGlobalState>) { let cityList = computed(() => store.state.home.cityList) let accessControlList = computed(() => store.state.home.accessControlList) onMounted(() => { if (cityList.value.length === 0) store.dispatch(`xxx`) if (accessControlList.value.length === 0) store.dispatch(`xxxx`, { communityId: 13 }) }) return { cityList, accessControlList } }
vue3使用說明:
拋棄data, 使用 setup
數組,字符串,數字,布爾使用 ref
const name = ref<string>('0');
計算屬性:
const nameComputed = computed(() => name.value + ' computed');
復雜對象使用reactive
const msg = reactive<any>({ obj: 123 });
Teleport 傳送門
組件可以任意地丟到html中的任一個DOM下。在react中也有相同功能的組件——Portal;
子組件:
<teleport to="#endofbody"> <div v-if="modalOpen"> teleport content </div> </teleport>
上層組件:
<div id="endofbody"></div>
使用后,子組件的內容,會填充到上層組件中;
Suspense異步組件
方便地控制異步組件的一個掛起和完成狀態,簡單來說:
1. Suspense
將異步組件包起來;
2. template #default
中展示加載完成的異步組件;
3. template #fallback
中則展示異步組件掛起狀態時需要顯示的內容;
例子:
// AsyncComponent.vue <template> <h2>AsyncComponent</h2> </template> <script lang="ts"> import {defineComponent} from "vue" export default defineComponent({ async setup(props) { const sleep = (timeout: number) => { return new Promise(resolve => { setTimeout(resolve, timeout) }) } await sleep(5000) } }) </script> // Suspense.vue <template> <h1>Suspense</h1> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <p class="loading">loading</p> </template> </Suspense> </template> <script lang="ts"> import {defineComponent} from "vue" import AsyncComponent from "./AsyncComponent.vue" export default defineComponent({ components: { AsyncComponent } }) </script>
script setup 語法糖
vue3.0.3 推出了setup 語法糖,下面是例子
樣式使用變量v-bind語法糖
其他
目前第三方庫都是測試版本,附帶各個版本的說明:
參考:
vue: https://vue3js.cn/docs/zh/guide/introduction.html
vuex: https://next.vuex.vuejs.org/
vue-router: https://next.router.vuejs.org/api/
element-plus: https://github.com/element-plus https://element-plus.org/#/zh-CN/component/installation