computed有缓存,data不变不会重新计算
watch如何深度监听
什么是深度监听呢?
如我们在选择省/市/县 等这些信息时,他们在data选项中是层层嵌套的一个关系,我们要监听到县就必须使用一个deep属性
data(){
return {
info:{
city:'上海';
}
}
}
watch(){
info:{
handler(oldVal,val){
console.log(oldVal,val);//引用类型拿不到,要加deep
},
deep:true;//深度监听
}
}
watch监听引用类型要深度监听,否则监听不到oldVal
v-for和v-if不能一起使用
- 在vue2中 v-for的优先级是高于v-if的,也就是说当我们渲染元素(即使是一小部分)每次执行循环都会判断一次,所以造成性能浪费
- 在vue3中 v-if的优先级是高于v-for的,所以v-if调用时v-for并未循环可能导致元素不存在.
v-for中的key属性作用
为了更加高效的更新虚拟 DOM,在进行 diff 时, 判断新旧节点是否是相同节点,会通过标签名和 key 进行比较。相同节点会更新属性,和比较子节点,不同节点则直接删除替换, 使用 key 标识可以优化比较过程
组件间的通讯
props和$emit
props父传子数据
$emit子组件调用父组件事件
生命周期
- 挂载阶段
- 更新阶段
- 销毁阶段
created页面实例初始化完成还未渲染
mounted页面已经渲染完了
创建是有外到内的,渲染是从外到内的
自定义v-model 双向数据绑定
自定义v-model$nextTick
vue是异步渲染
data改变之后,dom不会立即渲染
$nextTick会在dom渲染之后触发,以获取最新的dom节点
可以理解为批处理更新,把所有的update操作放到任务队列中,等主线程中执行栈的所有同步任务执行完毕,系统就会读取任务队列。
this.$nextTick(()=>{
const rr = this.$refs.ur;
})
异步组件
直接写组件名是同步加载
import()函数 按需加载,异步加载大组件
image.png
keep alive 用于tab页面切换
缓存组件,频繁切换不需要重复渲染,vue性能优化
如我们有三个页面,a b c,当我们点击b是切换b页面,点c切c.这时我们需要v-if来进行组件间的切换.
但这样来回切换是频繁的被渲染被摧毁的.所以利用缓存包裹起来性能更好
<button @click="changestate('A')">a页面按钮</button>
<button @click="changestate('B')">b页面按钮</button>
<button @click="changestate('C')">c页面按钮</button>
<keep-alive>
<A v-if="state=='A' ">
<A v-if="state=='B' ">
<A v-if="state=='c' ">
</keep-alive>
data(){
return{
state:'A'
}
}
methods:{
changestate(state){
this.state = state
}
}
mixin
多个组件有相同逻辑的抽离出来
vuex
- state vuex的基本数据,用来存储变量
- getter 从基本数据(state)派生的数据,相当于state的计算属性
- action 异步操作
- mutation 同步提交更新数据的方法,唯一可以修改state数据的场所
- disptach
- commit
- mapState
- mapGetters
- mapActions
- mapMutations
vue-router
hash模式:http://abc.com/#/user 警号后面是路由
h5 history模式:http://abc.com/user
后者需要server端支持
动态路由 :id
懒加载 :import引入
vue组件如何通讯
1 父子组件通讯 属性和触发事件
2 自定义事件方式(组件间没有关系)
3 vuex的通讯
mvvm模型 (mode view view-model)
之前组件只是静态渲染,更新需要操作dom,所以那时候的jquery很火,因为可以用很少的代码去操作dom,而现在数据驱动视图,只需要修改数据视图就改变了
mvvm
Vue响应式
组件data数据发生变化立刻触发视图的更新
原理:
核心apiObject.defineProperty vue3采用Proxy更新了vue2的局限性,如数组下标
缺点:Object.defineProperty深度监听需递归到底,无法监听新增和删除属性(vue.set和vue.delete来实现)
虚拟dom和diff算法
用js模拟dom结构,计算最小的变更,操作dom
xml语言可以用json对象来表示,所以dom结构可以使用js来表示
v-node模拟dom
将新旧node进行对比,找出最小范围进行更新
对比的过程就是diff算法
所以diff算法优化时间复杂度,
如tag不相同,直接删掉重建,不再深度比较
如tag个key都相同,则认为是相同节点,不再深度比较
所以为什么for循环中为什么要加key属性
diff算法通过tag和key判断是否为相同节点,减少渲染次数,提升渲染性能
模板编译
with语法
模板到render函数,再到vnode,再到渲染和更新
vue组件可以使用render代替template
组件渲染、更新过程
响应式监听data属性 getter setter
模板编译到render函数再到vnode
vdom patch(ele,vnode)和patch(vnode,newvnode)
解析模板为render函数
触发响应式,监听data属性 getter setter
执行render函数,生成vnode,patch(ele,vnode)
<p>{{msg}}</p>
data(){
return {
msg:'张三'; //会触发get 执行render函数 模板用到了
age:55;//不会触发
}
}
更新过程
修改data,触发setter
重新执行render函数,生成newVnode
patch(vnode,newVnode)
异步渲染nextTick
汇总data的修改,一次性更新视图
减少dom操作次数,提高性能
前端路由原理
- hash
特点
hash变化会触发网页的跳转,浏览器前进后退
不会刷新页面,spa特点
hash不会提交到server端 -
h5 history
跳转时不刷新页面
history.pushState还有window.onpopstate方式实现
需要服务端支持
网页url
image.png
为何组件data是一个函数
实际上.vue文件是一个class类,当我在每个地方使用这个组件的时候相当于对class进行实例化,实例化执行data那么会形成共享的,所以定义为一个函数
ajax应该放在哪个生命周期
mounted中,整个渲染完成
因为js是单线程的,ajax异步获取数据
何时使用beforeDestory
解除自定义事件
清除定时器解绑自定义dom事件,如window scroll等
vuex中action和mutation的区别
action中处理异步,mutation不可以
mutation做原子操作(每次只能操作一个)
auction可以整合多个mutation
网友评论