Vue的生命周期
- 创建前后
- beforeCreate:Vue实例已经创建,但数据观测和初始化事件还未开始,不能访问data、computed、watch、methods上的数据方法。
- created:可以访问data、computed、watch、methods上的数据方法,但此时渲染节点还未挂在到DOM上。
- 挂载前后
- beforeMount:组件已经完成了其响应式状态的设置,但Vue实例还未挂在到页面HTML上,还没有创建 DOM 节点。
- mounted:Vue实例已经挂载完毕,可以操作DOM。
- 更新前后
- beforeUpdate: 数据更新之前调用,还未渲染页面
- updated:DOM重新渲染,此时数据和界面都是新的。
- 销毁前后
- beforeDestorye:Vue实例销毁前调用,这时候能够获取到this,组件实例依然还保有全部的功能。
- destoryed:函数实例已经销毁,所有数据和方法均不可用。
常见属性和指令
- 属性
– data:用于定义组件的初始数据。
– props:用于传递数据给子组件。
– computed:用于定义计算属性。
– methods:用于定义组件的方法。
– watch:用于监听组件的数据变化。
– components:用于注册子组件。可以通过 components 属性将其他组件注册为当前组件的子组件,从而在模板中使用这些子组件。 - 指令
– v-if:条件渲染指令,根据表达式的真假来决定是否渲染元素。
– v-show:条件显示指令,根据表达式的真假来决定元素的显示和隐藏。
– v-for:列表渲染指令,用于根据数据源循环渲染元素列表。
– v-bind:属性绑定指令,用于动态绑定元素属性到 Vue 实例的数据。
– v-on:事件绑定指令,用于监听 DOM 事件,并执行对应的 Vue 方法。
– v-model:双向数据绑定指令,用于在表单元素和 Vue 实例的数据之间建立双向绑定关系。
– v-text:文本插值指令,用于将数据插入到元素的文本内容中。
– v-html:HTML 插值指令,用于将数据作为 HTML 解析并插入到元素中。
watch()和computed()的区别
watch()是监听数据的变化,并在数据源变化时调用所给的回调函数。如果要监听一个对象的变化而不是它的某个属性,可以增加一个deep参数,将其设为true
computed()是计算属性,通过对已有的值进行计算获取新的值。计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。
常见的事件修饰符及其作用
- .stop:阻止冒泡
- .prevent:阻止默认事件
- .capture :与事件冒泡的方向相反,事件捕获由外到内;
- .self :只会触发自己范围内的事件,不包含子元素;
- .once:只会触发一次。
v-if和v-show的区别
- v-if元素不可见,是直接删除DOM,有更高的切换消耗。
- v-show通过设置元素display: none控制显示隐藏,更高的初始渲染消耗。
路由的hash和history模式的区别
- hash模式:开发中默认的模式,地址栏URL后携带#,后面为路由。
原理是通过onhashchange()事件监听hash值变化,在页面hash值发生变化后,window就可以监听到事件改变,并按照规则加载相应的代码。hash值变化对应的URL都会被记录下来,这样就能实现浏览器历史页面前进后退。 - history模式:history模式中URL没有#,这样相对hash模式更好看,但是需要后台配置支持。
history原理是使用HTML5 history提供的pushState、replaceState两个API,用于浏览器记录历史浏览栈,并且在修改URL时不会触发页面刷新和后台数据请求。
router和route的区别
$route 是路由信息,包括path、params、query、name等路由信息参数
$router 是路由实例,包含了路由跳转方法、钩子函数等
Vue.nextTick()
Vue是用来异步更新DOM的,为了能操作更新后的DOM,引入了Vue.nextTick()方法。
当在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。
nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。可以传递一个回调函数作为参数,或者 await 返回的 Promise。
//示例:
<script>
import { nextTick } from 'vue'
export default {
data() {
return {
count: 0
}
},
methods: {
async increment() {
this.count++
// DOM 还未更新
console.log(document.getElementById('counter').textContent) // 0
await nextTick()
// DOM 此时已经更新
console.log(document.getElementById('counter').textContent) // 1
}
}
}
</script>
<template>
<button id="counter" @click="increment">{{ count }}</button>
</template>
v-for和v-if避免同时使用的原因
在vue2中,v-for的优先级比v-if高,这意味着每次迭代都要执行一次v-if中的判断条件,造成不必要的计算,影响性能。
在vue3中,v-if比v-for的优先级更高,v-if的条件无法访问到v-for作用域内的变量名,会导致报错。
Vue为v-model指令提供了哪些修饰符?
(1) .lazy修饰符能将同步输入值的事件从input替换成change,只有当修改其值并失去焦点时,才会更新数据对象的属性
(2) .number修饰符能让输入值自动转换成数字,常与number类型的文本框配合使用。
(3) .trim修饰符能过滤输入值的首尾空格。
Vue中key的原理及作业
在Vue中,key是用来帮助Vue识别和跟踪虚拟DOM的变化的特殊属性。当Vue更新渲染真实DOM时,使用key属性可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,减少DOM操作量,提高性能。
key的工作原理如下:
- 当Vue更新渲染真实DOM时,对新旧节点进行比较,找出它们之间的差异。
- 如果两个节点具有相同的key值,则Vue认为它们是相同的节点,会尝试复用已存在的真实DOM节点。
- 如果节点具有不同的key值,Vue会将其视为不同的节点,并进行适当的更新、移动或删除操作。
注意:
不推荐使用随机数作为key,因为每次更新时都会生成新的key,导致所有节点都重新渲染,无法复用已有的节点,降低性能。
不建议用index作为key,因为如果将数组下标作为key值,那么当列表发生变化时,可能会导致key值发生改变,从而引发不必要的组件重新渲染,甚至会导致性能问题。例如,当删除列表中某个元素时,其后面的所有元素的下标都会发生改变,导致Vue重新渲染整个列表。
KeepAlive
<KeepAlive> 是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。
默认情况下,一个组件实例在被替换掉后会被销毁。这会导致它丢失其中所有已变化的状态——当这个组件再一次被显示时,会创建一个只带有初始状态的新实例。默认情况下,组件切换状态会重置 <component :is="activeComponent" /> 要想使非活跃的组件被缓存 <KeepAlive> <component :is="activeComponent" /> </KeepAlive>
<KeepAlive> 默认会缓存内部的所有组件实例,它能够将不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中,也不会出现在父组件链中。可以通过 include 和 exclude prop 来定制该行为,也可以通过传入 max prop 来限制可被缓存的最大组件实例数。
- include 字符串或正则表达式,只有名称匹配的组件会被匹配;
- exclude 字符串或正则表达式,任何名称匹配的组件都不会被缓存;
- max 数字,最多可以缓存多少组件实例。
当一个组件实例从 DOM 上移除但因为被 缓存而仍作为组件树的一部分时,它将变为不活跃状态而不是被卸载。当一个组件实例作为缓存树的一部分插入到 DOM 中时,它将重新被激活。
一个持续存在的组件可以通过 activated 和 deactivated 选项来注册相应的两个状态的生命周期钩子:export default { activated() { // 在首次挂载、 // 以及每次从缓存中被重新插入的时候调用 }, deactivated() { // 在从 DOM 上移除、进入缓存 // 以及组件卸载时调用 } }
注意:activated 在组件挂载时也会调用,并且 deactivated 在组件卸载时也会调用。
这两个钩子不仅适用于 <KeepAlive> 缓存的根组件,也适用于缓存树中的后代组件。