ts+vue3+vite+pinia+vue-router 踩坑合集

前言

抽空整理練手項(xiàng)目升級后的一些坑點(diǎn); 各位項(xiàng)目中有問題遇到困難也可以留言;我會(huì)盡快回復(fù)! 后續(xù)還會(huì)繼續(xù)更新問題點(diǎn)!

1. 預(yù)處理器

安裝sass以及配置全局scss

npm install node-sass
npm install sass-loader

node 版本不能過高; 目前成功版本為10.15.0; 可通過安裝"n"來管理node版本

配置全局mixin.scss

根目錄找到vite.config.js

// vite.config.js
 import{defineConfig}from'vite';
importvuefrom'@vitejs/plugin-vue';
import{resolve}from'path';
// https://vitejs.dev
/config/exportdefaultdefineConfig({
plugins:[vue(),],
resolve:{
// 配置別名
alias:[{find:'@',replacement:resolve(__dirname,'./src')},
{find:'views',replacement:resolve(__dirname,'./src/views')},],},
css:{
// 添加全局
mixin.scsspreprocessorOptions:{scss:{additionalData:'@import "@/style/libs.scss";',},},},});

css參與計(jì)算 (內(nèi)置模塊)

原來的寫法直接計(jì)算是不行的, 需要使用內(nèi)置模塊math.div()方法參與計(jì)算

libs.scss使用math 需要先聲明使用; 添加在文件頂部@use"sass:math" 原來的寫法border-width:$w/2; 新寫法border-width:math.div($w/2)

新寫法; 切記math需要聲明使用(https://sass-lang.com/documentation/modules); 不然就會(huì)提示:

Error: There is no module with the namespace "math".

2. require 使用

問題: 想引入某個(gè)目錄下的所有文件?

constfile=require.context('@/views/',true,/\.vue$/)

結(jié)果提示找不到名稱“require”宣旱。是否需要為節(jié)點(diǎn)安裝類型定義? 請嘗試使用npm i --save-dev @types/node盛杰,然后將 “node” 添加到類型字段聂薪。

解決辦法:

按照提示安裝庫

npm i --save-dev @types/node

然后在tsconfig.jsontypes字段中添加node; 然后重啟一下; 就行了

// tsconfig.json{"compilerOptions":{"target":"esnext","module":"esnext","strict":false,"jsx":"preserve","moduleResolution":"node","types":["vite/client","node",],...}}}

3.別名配置

問題: 當(dāng)你使用別名@, 你會(huì)發(fā)現(xiàn)別名框架并沒有配置 會(huì)出現(xiàn)提示找不到模塊“@/router/index”或其相應(yīng)的類型聲明

import router from '@/router/index';

解決辦法:

vite.config.js配置別名

// vite.config.js import{defineConfig}from'vite';importvuefrom'@vitejs/plugin-vue';import{resolve}from'path';// https://vitejs.dev/config/exportdefaultdefineConfig({plugins:[vue(),],resolve:{// 配置別名alias:[{find:'@',replacement:resolve(__dirname,'./src')},{find:'views',replacement:resolve(__dirname,'./src/views')},],},css:{// 添加全局mixin.scsspreprocessorOptions:{scss:{additionalData:'@import "@/style/libs.scss";',},},},});

很多人以為這樣就結(jié)束了;在js 文件中確實(shí)就已經(jīng)可以用了; 但是在.vue 文件中還是不行,其實(shí)還需要在tsconfig.json里面配置對應(yīng)的別名; 詳情見http://www.reibang.com/p/1477b68b2d69

// tsconfig.json {"compilerOptions":{..."paths":{"@/*":["./src/*"],"views/*":["./src/views/*"],}}}
4.動(dòng)態(tài)路由

問題:Invalid route component at extractComponentsGuards?這個(gè)問題不陌生吧!! 有倆個(gè)因素;

1. 如果你用JSON.stringify()轉(zhuǎn)為string 后存儲(chǔ); 因?yàn)?code>JSON.stringify()在序列化的過程中function晚胡、undefined喂链、symbol這幾種類型是不可枚舉屬性; 序列化后這個(gè)鍵值對會(huì)消失;addRoute()的時(shí)候就會(huì)發(fā)現(xiàn)沒有這個(gè)component.

2. 使用component:()=>import('views/Order/index.vue')懶加載方式引入;也會(huì)提示Invalid route component;

tips: 調(diào)試路由時(shí)可通過router.getRoutes(); 查看動(dòng)態(tài)路由是否已經(jīng)完整注入進(jìn)去

解決辦法1. 使用Glob Import 動(dòng)態(tài)導(dǎo)入

// src/mockjs/mock.routes.tsexportdefaultroutes=[{path:'/',name:'home',component:'views/Home/index.vue',meta:{// 頁面標(biāo)題title:'首頁',// 身份認(rèn)證userAuth:false,},},]
// src/router/index.ts
importroutesfrom"@/mockjs/mock.routes"
// 路由元信息
constmodules=import.meta.golb("../views/**/**.vue")
//使用golb ++
routes.forEach(item=>{router.addRoute("home",{path:item.path,name:item.name,meta:...item.meta,component:
//本地能使用添谊,上生產(chǎn)直接GG//
()=>import(/* @vite-ignore */ `/@views/${itemRouter.component}`),
//使用modulesmodules
[/* @vite-ignore */`../views/${item.component}`],})})
解決辦法2 : 在聲明路由數(shù)據(jù)時(shí)使用 RouteRecordRaw; 下面是RouteRecordRaw`的注解

當(dāng)用戶通過routes option或者router.addRoute()來添加路由時(shí),可以得到路由記錄侄榴。 有三種不同的路由記錄:

單一視圖記錄:有一個(gè) component 配置

多視圖記錄 (命名視圖) :有一個(gè) components 配置

重定向記錄:沒有 componentcomponents配置,因?yàn)橹囟ㄏ蛴涗浻肋h(yuǎn)不會(huì)到達(dá)网沾。

// src/mockjs/mock.routes.ts 
exportdefaultroutes:RouteRecordRaw[]=[{
path:'/',
name:'home',
component:component:()=>import("views/Home/index.vue"),
meta:{
// 頁面標(biāo)題
 title:'首頁',
// 身份認(rèn)證 
userAuth:false,
},
},
]
// src/router/index.ts importroutesfrom"@/mockjs/mock.routes"
// 路由元信息  確保自己的地址是否正確
routes.forEach(item=>{router.addRoute(item})})
5.pinia 使用以及動(dòng)態(tài)路由持續(xù)存儲(chǔ)踩坑

注釋: piniavuex一樣也是一個(gè)基于vue的狀態(tài)管理庫; 使用pinia時(shí),可以理解為它每一個(gè)store都是動(dòng)態(tài)的癞蚕、獨(dú)立的; 不像vuex 一樣可嵌套,因?yàn)闆]有modules!

pinia 使用:
npm install pinia
or
yarn add pinia
// src/store/index.ts 
import{createPinia}from"pinia"
constpinia=createPinia()exportdefaultpinia
//main.ts ....importpiniafrom"./store/index"
createApp(App).use(router).use(pinia).mount('#app')
定義單個(gè)store
// src/store/createRouteInfo.ts
 import{defineStore}from"pinia"importrouterfrom"
@/router/index"
// 封裝的路由
// defineStore的第一個(gè)參數(shù)是應(yīng)用程序中 store 的唯一id;這些注解官網(wǎng)都有 
constuseStore=defineStore('useStore',{state:()=>({
routeModules:[],menu:[].....
}),
getterL:{routeModules:state=>
state.routeModules,menu:state=>
state.menu},
// 上面那倆個(gè)參數(shù)沒變; 沒有mutations!! actions類似于組件中methods,也可以定義一些業(yè)務(wù)邏輯; 
actions:{addAsyncRoutes(routes){
// 業(yè)務(wù)邏輯
//設(shè)置動(dòng)態(tài)路由
routes.forEach(el=>{router.addRoute(el)})}}})exportdefaultuseStore

使用useStore

// src/components/menu.vue
<scriptlang="ts"setup>
import useStore from "@/store/createRouteInfo" 
 import {storeToRefs} from "pinia" 
 const store = useStore() 
 // 使參數(shù)變?yōu)轫憫?yīng)式 
 const {routeModules,menu} = storeToRefs(store)  
onMounted(()=>{ getMenu() }) 
 const getMenu = ()=>{ let result = getMenuData(params) 
// set store value
  store.$patch(state=>{ state.menu = result.data.menu }) }
</script>
<template>
<divclass="menu">
<ul><liv-for="li in menu":key="li.id">{{li.text}}</li></ul>
</div>
</template>
動(dòng)態(tài)路由權(quán)限踩坑

很多人做動(dòng)態(tài)路由時(shí) 數(shù)據(jù)存在store;頁面刷新后頁面空白或者進(jìn)入404頁面; 并且使用router.getRoutes() 查看新增的路由已經(jīng)消失; 是因?yàn)閟tore是存在瀏覽器的堆棧內(nèi)存里面; 刷新后頁面數(shù)據(jù)被釋放掉; 那么如何解決呢? 想一想 頁面刷新后我們的框架是會(huì)重新掛載的! so! main.js? 試試就試試!!!!

// src/store/asyncRoute.ts importroutesfrom"@/mockjs/mock.routes"
// 路由元信息 
import useStorefrom"@/store/createRouteInfo"
// 封裝的路由
 conststore=useStore()const{role}=localStorage.getItem('user')||{}
// 是否已經(jīng)登陸, 初級判斷 可增加路由權(quán)限判斷
if(role==='admin'){
// 此方法在 上面“定義單個(gè)store” createRouteInfo.ts 文件中定義了
store.addAsyncRoutes(routes)
}
// main.js.....import"./store/asyncRoute".....
createApp(App).use(router).use(pinia).mount('#app')

頁面更新后提示報(bào)錯(cuò)信息:

問題: Uncaught Error: [??]: getActivePinia was called with no active Pinia. Did you forget to install pinia?

什么意思呢? 你當(dāng)前正在使用pinia; 但是pinia 還沒有掛載成功!!!! what? 我使用vuex就不會(huì)這樣呀!!!! 戲精

解決方案:

無意間在廖雪峰的官網(wǎng)看到過一句評論!!所謂的對象、函數(shù)在瀏覽器內(nèi)存中就是一個(gè)地址;找個(gè)地址只想某個(gè)函數(shù)或者對象或者方法辉哥、誰拿到這個(gè)地址就擁有操作的權(quán)利; 所謂的函數(shù)作為參數(shù)傳入別的函數(shù); 其實(shí)就是把地址給了它; 讓它擁有的操作的權(quán)利! 我覺得挺精辟!!

使用時(shí)引入pinia

// src/store/index.ts 
import{createPinia}from"pinia"
constpinia=createPinia()exportdefaultpinia
//_______________分割線__________________ // 
//src/store/asyncRoute.ts 
importroutesfrom"@/mockjs/mock.routes"
// 路由元信息
 importuseStorefrom"@/store/createRouteInfo"
// 封裝的路由 importpiniafrom"./index"
// 引入pinia 
conststore=useStore(pinia)
// 把pinia 傳進(jìn)去 就可以任意任意使用里面的屬性了
const{role}=localStorage.getItem('user')||{}
// 是否已經(jīng)登陸, 初級判斷 可增加路由權(quán)限判斷
 if(role==='admin'){
// 此方法在 上面“定義單個(gè)store” createRouteInfo.ts 文件中定義了
store.addAsyncRoutes(routes)}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桦山,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子醋旦,更是在濱河造成了極大的恐慌恒水,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浑度,死亡現(xiàn)場離奇詭異寇窑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)箩张,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門甩骏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人先慷,你說我怎么就攤上這事饮笛。” “怎么了论熙?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵福青,是天一觀的道長。 經(jīng)常有香客問我,道長无午,這世上最難降的妖魔是什么媒役? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮宪迟,結(jié)果婚禮上酣衷,老公的妹妹穿的比我還像新娘。我一直安慰自己次泽,他們只是感情好穿仪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著意荤,像睡著了一般啊片。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玖像,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天紫谷,我揣著相機(jī)與錄音,去河邊找鬼捐寥。 笑死碴里,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的上真。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼羹膳,長吁一口氣:“原來是場噩夢啊……” “哼睡互!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起陵像,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤就珠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后醒颖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妻怎,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年泞歉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逼侦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腰耙,死狀恐怖榛丢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挺庞,我是刑警寧澤晰赞,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響掖鱼,放射性物質(zhì)發(fā)生泄漏然走。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一戏挡、第九天 我趴在偏房一處隱蔽的房頂上張望芍瑞。 院中可真熱鬧,春花似錦增拥、人聲如沸啄巧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秩仆。三九已至,卻和暖如春猾封,著一層夾襖步出監(jiān)牢的瞬間澄耍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工晌缘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留齐莲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓磷箕,卻偏偏與公主長得像选酗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子岳枷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容