前言

编码方面

编码规范

建议编码习惯

vue生命周期钩子函数

官方针对组件的生命周期钩子函数执行顺序已经讲解得足够透彻了,具体见官方生命周期钩子说明
这里主要是针对此生命周期钩子函数的执行顺序进行一个验证,另外,再结合组件中存在属性的监听时,这个生命周期的执行情况又会变得如何, 👇 的截图是自己在对应的例子中提供的一个结果:
vue3组件生命周期钩子函数执行结果

这里是对应的例子:

组件的生命周期钩子函数

👆 从上面的例子我们可以看出,组件中的变量的监听动作是在组件created之前完成的,然后在组件mounted之前,需要拿到组件的变量来进行渲染,因此,会在mounted之前触发到这个renderTracked动作!

🤔 而当组件中的数据发生变化的时候,数据对应的watch中的onTrigger(数据级别的监听)将第一时间触发,然后收集需要的变化值,触发renderTriggered,然后收集变量,继续触发变量的监听onTrack,接着准备更新组件,进入beforeUpdate,接着渲染页面,进入renderTracked,最后触发组件的updated,整个过程的执行如下图所示:
钩子函数的执行顺序

vue最佳实践

vue3+的api

以下整理关于在vue3中所提供的公共API,可作为日常编码工具!

toValue()

获取refsgetters的值。这与 unref() 类似,不同的是此函数也会规范化 getter 函数。如果参数是一个 getter,它将会被调用并且返回它的返回值。
这可以在组合式函数中使用,用来规范化一个可以是值、ref 或 getter 的参数。
关于此方法的定义如下:

1
2
3
export function toValue<T>(source: MaybeRefOrGetter<T> | ComputedRef<T>): T {
return isFunction(source) ? source() : unref(source)
}

vue-router最佳实践

404错误捕获

🌝vue-router4.x版本中,不再接受使用*通配符的方式来处理项目中的404错误了,而是必须使用自定义的regex参数来定义所有的路由,一般是通过 👇 的方式来配置的

1
2
3
4
5
6
7
8
import { createRouter } from 'vue-router'
const router = createRouter({
routes: [
{ path: '/', component: Home },
// ...这里省略其他路由的定义
{ path: '/:catchAll(.*)', component: NotFound }
]
})

🤔 这里的:catchAll(.*)代表的是什么呢?

👉 首先,这个:catchAll(.*)是一个正则表达式,它是一个路由参数配合正则表达式使用的,主要用来匹配所有无法被之前定义的路由规则捕获的路径,一般用来定义404页面,也就是用户尝试访问不存在的页面时所显示的页面, 关于这个表达式, 👇 将拆分为几个部分来分析一下:

  1. :: 表示接下来的部分是一个动态路由参数;
  2. catchAll: 是参数的名称,可以随意命名,但应该清晰地表明这个参数的用途;
  3. (.*): 是一个正则表达式,()表示一个捕获组,.表示匹配除换行符之外的任意单个字符,*表示匹配前面的那个字符0次或者多次,因此,这个表达式所含义就是匹配任意长度、任意内容的字符串

:disguised_face: 将 的组合起来,整个表达式/:catchAll(.*)就是匹配除了之前定义的所有路由之外的任何路径,因此,在路由配置的最后加上这个规则,可以确保所有未被识别的路由都会导向到我们所指定的component!!

对于动态路由的处理

🧑🎓 在实际的项目中,对于一些基于权限控制的项目,需要根据角色加载对应的路由,因此需要动态的创建路由, :face_with_spiral_eyes: 但是上面又提及到需要将这个404的路由定义放在所有的路由的最后处,因此, 👉 需要在加载完成所有其他的路由之后,才将这个404路由给push进去!
而且,我们在push最后的这个404路由的时候,可以先检测是否已经存在,那么, 🤔 可以通过什么方式来判断呢?

1
2
3
4
5
6
7
// 这里是动态路由的添加
dynamicRoutes.forEach(route => {
router.addRoute(route)
})
// 然后添加最后的404,在添加之前,可以先移除,然后再添加
router.removeRoute('not-found')
router.addRoute({ path: '/:catchAll(.*)', name: 'not-found', component: NotFound })

离开已编辑数据页面的二次弹窗确认

在项目的coding过程中,难免会需要涉及到表单类的数据编辑,特别是当编辑的很多的信息的时候, 😵 所维护的信息并没有及时地保存下来,如果这个时候,我们一不小心按了其他的按钮进入或者退出当前页面,那么已维护的数据没有被保存下来,这个时候需要重新去编辑才可以,为了解决这种场景,可以利用组件级别的beforeRouteLeave守卫来处理!!
onBeforeRouteLeave是一个导航守卫,不论当前组件何时离开时,都会触发的一个函数,当组件被卸载时,该守卫会被移除!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { ref, computed } from 'vue'
import { onBeforeRouteLeave } from 'vue-router'
const unsavedChange = ref(false)
onBeforeRouteLeave((to, from, next) => {
if(unsavedChange.value){
const answer = window.confirm('您有未保存的更改,确定要离开吗?')
if(answer){
// 继续导航,放弃已编辑的数据
next()
}else{
// 中断当前路由导航
next(false)
}
}else{
// 并没有未保存的更改,正常进行路由导航
next()
}
})

pinia最佳实践

全局项目配置响应式

一般情况下,如果项目需要前端的系统配置的自动化响应式处理操作的话,可考虑将相关的配置与本次存储、以及pinia结合,实现配置的本地化管理操作,并通过自定义的composition API来对外提供API!关于此功能,需要准备以下相关的文件来实现:

1.