npm i vue@latest
vue将ts的配置大多都隐藏了
如果想看: "extends": "@vue/tsconfig/tsconfig.web.json" 表示,tsconfig配置继承自里面的文件
vite.config.ts中的
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
是打包时解析别名
tsconfig.json中的
"paths": {
"@/*": ["./src/*"]
}
是用于代码路径提示
"references": [
{
"path": "./tsconfig.config.json"
}
]
如果想修改ts配置,建议在./tsconfig.config.json里修改
不建议在 **"extends": "@vue/tsconfig/tsconfig.web.json"**里修改
这些配置 最终都会汇总到tsconfig.json里
//tsconfig.config.json
"extends": "@vue/tsconfig/tsconfig.node.json" //ssr相关配置
引用了vite/client里的 文件声明
有助于不同IDE编辑器上处理同一项目的多个开发人员维护一致的编码风格
{
"useTabs": false,
"tabWidth": 2,
"printWidth": 80,
"singleQuote": false,
"semi": true
}
1.vite提供了一些接口来判断当前项目环境
import.meta.env.DEV //是否为开发环境 boolean
import.meta.env.PROD //是否为生产环境
import.meta.env.SSR //是否为服务器端渲染
import.meta.env.BASE_URL //
import.meta.env.MODE //当前模式 "production"/"development"
**2.**dotenv配置环境
变量必须以VITE开头
//.env
VITE_
//.env.production
VITE_URL=
//.env.development
VITE_URL=
快速开始 | Element Plus (element-plus.org)
npm install -D unplugin-vue-components unplugin-auto-import
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
重启项目
根目录会自动生成
auto-import.d.ts(声明文件)
components.d.ts
两个声明文件
//tsconfig.json
"include": [
"env.d.ts",
"src/**/*",
"src/**/*.vue",
"auto-imports.d.ts",
"components.d.ts"
],
在ts配置处声明两个文件,否则不会生效
panelAccount暴露登录方法 defineExpose({loginAction})
父组件可以直接选到子组件的根类名
vue-scoped
原理:
.father[data-v-7a7a37b1] father上有对应属性
子组件根的类名的data属性的值与父组件的一样
.father[data-v-7a7a37b1] .son[data-v-7a7a37b1]
1.基于角色的动态路由
const roles={
'superadmin':[所有路由]=>router.main.children
'admin':[部分路由]=>router.main.children
'user':[少部分路由]=>router.main.children
'mannager':[]=>后端返回路由表json
}
弊端:每增加一个角色,都要增加key,value
2.基于菜单的动态路由(推荐)
userMenus=>动态展示菜单
登录接口中请求的三个内容:
1.token
2.用户信息:角色(role)
3.菜单信息
刷新时数据会丢失,做持久化缓存
pinia中定义action获取本地数据
在pinia初始化完后,将本地数据都挂载到pinia上,并添加路由表
加载路由
app.use(pinia);
//pinia加载完后将本地数据都挂载到pinia上
const loginStore = useLoginStore();
loginStore.loadLocalData();
//再加载路由
app.use(router);
scoped.row
<div @click="increment" class="count">当前计数:{{count}}</div>
const count=ref(100)
function increment(){
count.value+=100
const countEl=document.querselector("count");
console.log(countEl?.textContent) //100,这里拿不到200
}
DOM已经更新为了200
但countEl?.textContent获取到的值仍为100
此时可以用nextTick(()=>{})
<div @click="increment" class="count">当前计数:{{count}}</div>
const count=ref(100)
function increment(){
count.value+=100
nextTick(()=>{
const countEl=document.querselector("count");
console.log(countEl?.textContent) //200
})
}
放到nextTick里时就可以获取到200了
NextTick是等待下一次 DOM 更新刷新的工具方法。
你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,
如:执行count.value+=100时,DOM并没有更新。
而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。
一次Tick: pre代码操作——》更新队列——》生命周期里的操作——》nextTick()里的操作
这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。
nextTick()
可以在状态改变后立即使用,以等待 DOM 更新完成。你可以传递一个回调函数作为参数,或者 await 返回的 Promise。
vue3中nextTick是微任务: 在Promise的.then里
vue2中nextTick是宏任务还是微任务发生了好几次变化
将nextTick放在promise的.then中
const promise=new Promise(()=>{
pre
queue
post
}).then( nextTick(()=>{}) )
1.登陆时,userMenus的第三层会带有permission属性(Array数组),用于存储不同页面下的不同权限:如下例
"system:users:create"
系统-用户-创建权限
在登陆Action时,将后台传过来的Menu过滤出permissions,并将permissions保存到state中。
为防止刷新后store数据丢失,在pinia加载完后,就将本地数据都挂载到pinia上(调用useLoginStore里的loadLocalData()方法)
这里,permisssion也需要做持久化缓存,所以loadLocalData()中也要加载permisssion
封装usePermission的Hook,根据传入的permissionId,返回是否有这个权限
在Table通用组件中使用Hook,再用v-if判断是否显示
useXXXStore暴露出了一个API,用于监听某Action,并在Action执行后的运行回调
$onAction(()=>{})
要放执行Action函数之前
const unsubscribe = someStore.$onAction(
({
name, // action 名称
store, // store 实例,类似 `someStore`
args, // 传递给 action 的参数数组
after, // 在 action 返回或解决后的钩子
onError, // action 抛出或拒绝的钩子
}) => {
// 为这个特定的 action 调用提供一个共享变量
const startTime = Date.now()
// 这将在执行 "store "的 action 之前触发。
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// 这将在 action 成功并完全运行后触发。
// 它等待着任何返回的 promise
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// 如果 action 抛出或返回一个拒绝的 promise,这将触发
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
// 手动删除监听器
unsubscribe()