一、揭秘Vue中的Virtual Dom
1、首先我们来了解一下模板转换成视图的过程如下图:
- Vue.js通过编译将template模板转换成渲染函数(Render),执行渲染函数就可以得到一个虚拟节点树
- 在对Model进行操作的时候,会触发对应Dep中的Watcher对象。Watcher对象会调用对应的update来修改视图。这个过程主要是将新旧虚拟节点进行差异对比,然后根据对比结果进行DOM操作来更新视图。
简单来说,在Vue的底层实现上,Vue将模板编译成虚拟DOM渲染函数。结合Vue自带的相应系统,在状态改变时,Vue能够智能地计算出重新渲染组件的最小代价并应到DOM操作上。
2、Virtual DOM 是什么?
(1)Virtual DOM其实是一颗以JS对象(VNode节点)作为基础的树,用对象属相来描述节点,实际上它只是一层对真实DOM的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。
简单来说,可以把 Virtual DOM 理解为一个简单JS对象,并且最少包含标签名(tag)、属性名(attrs)和子元素对象(children)三个属性。不同框架对这三个属性的命名会有点差别。
对于虚拟DOM,咱们来看个简单的实例,如下图所示,详细简述了模板-》渲染函数=》虚拟DOM树=>真实DOM的一个过程
3、Virtual DOM 作用是什么?
虚拟DOM的最终目标是将虚拟节点渲染到视图上。但是如果直接使用虚拟节点覆盖旧节点的话,会有很多不必要的DOM操作。例如,一个ul标签下很多个li标签,其中只有一个li有变化,这种情况下如果使用新的ul去替代旧的ul,因为这些不必要的DOM操作而造成了性能上的浪费。
为了避免不必要的DOM操作,虚拟DOM在虚拟节点映射到视图的过程中,将虚拟节点与上一次渲染视图所使用的旧虚拟节点(OldVnode)做对比,找出真正需要更新的节点来进行DOM操作从而避免操作无需改动的DOM.
其实虚拟DOM在Vue.js主要做了两件事:
- 提供与真实DOM节点所对应的虚拟节点vnode
- 将虚拟节点vnode和旧虚拟节点(OldVnode)进行对比,然后更新视图
4、为何需要Virtual DOM?
- 具备跨平台的优势
- 操作 DOM 慢,js运行效率高。我们可以将DOM对比操作放在JS层,提高效率。
- 提升渲染性能
二、组件间的通信
答案:https://blog.csdn.net/qq_41149508/article/details/84985177
三、对Vuex的理解和使用
https://blog.csdn.net/qq_41149508/article/details/85067327
四、$nextTick的使用
1、什么是Vue.nextTick()?
定义:在下次DOM更新循环结束之后延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM
理解:nextTick(),是将回调函数延迟在下一次DOM更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数。
2、什么时候需要用的 Vue.nextTick()??
- Vue生命周期的created钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中,原因是在函数执行的时候DOM其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放在Vue.nextTick()的回调函数中,与之对应的就mounted钩子函数,因为该钩子函数执行时所有的DOM挂载已完成。
created(){
let that=this;
that.$nextTick(function(){ //不使用this.$nextTick()方法会报错
that.$refs.aa.innerHTML="created中更改了按钮内容"; //写入到DOM元素
});
}
2、当项目中你想在改变 DOM 元素的数据后基于新的 dom 做点什么,对新 DOM 一系列的 js 操作都需要放进 Vue.nextTick()的回调函数中;通俗的理解是:更改数据后当你想立即使用 js 操作新的视图的时候需要使用它
正确的用法是:vue 改变 dom 元素结构后使用 vue.$nextTick()方法来实现 dom 数据更新后延迟执行后续代码
changeTxt:function(){
let that=this;
that.testMsg="修改后的文本值"; //修改dom结构
that.$nextTick(function(){ //使用vue.$nextTick()方法可以dom数据更新后延迟执行
let domTxt=document.getElementById('h').innerText;
console.log(domTxt); //输出可以看到vue数据修改后并没有DOM没有立即更新,
if(domTxt==="原始值"){
console.log("文本data被修改后dom内容没立即更新");
}else {
console.log("文本data被修改后dom内容被马上更新了");
}
});
}
3、在使用某个第三方插件时 ,希望在 vue 生成的某些 dom 动态发生变化时重新应用该插件,也会用到该方法,这时候就需要在 $nextTick 的回调函数中执行重新应用插件的方法。
五、Vue组件中的data为什么必须是函数?
在 new Vue() 中,data 是可以作为一个对象进行操作的,然而在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它,这并非是 Vue 自身如此设计,而是跟 JavaScript 特性相关,我们来回顾下 JavaScript 的原型链
var Component = function() {};
Component.prototype.data = {
message: "Love"
};
var component1 = new Component(),
component2 = new Component();
component1.data.message = "Peace";
console.log(component2.data.message); // Peace
以上两个实例都引用同一个对象,当其中一个实例属性改变时,另一个实例属性也随之改变,只有当两个实例拥有自己的作用域时,才不会互相干扰 !!!!!这句是重点!!!!!
六、父组件和子组件生命周期钩子执行顺序是什么?
- 加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted - 子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated - 父组件更新过程
父beforeUpdate->父updated - 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
七、路由跳转的方式和区别
1、router-link (声明式路由)
(1)不带参数
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">
(2)带参数
<router-link :to="{name:'home,params:{id:1}'}">
// params传参数 (类似post)
// 路由配置 path: "/home/:id" 或者 path: "/home:id"
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
<router-link :to="{path:'/home'}",query:{id:1}>
2、this.$router.push() (函数里面调用)
(1)不带参数
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
(2)query传参
this.$router.push({path:'/home',query: {id:'1'}})
//script 取参 this.$route.query.id
(3)params传参
this.$router.push({name:'home',params: {id:'1'}})
// 只能用 name
// script 取参 this.$route.params.id
注意:query和params区别
- query类似 get, 跳转之后页面 url后面会拼接参数,类似?id=1, 非重要性的可以这样传, 密码之类还是用params,因为刷新页面id还在
- params类似 post, 跳转之后页面 url后面不会拼接参数 , 但是刷新页面id 会消失
八、vue重置数据为data中的初始状态
第一种:常见比较臃肿的写法是逐个重新复制,这种针对数据少的可以要是有很多就很麻烦了
...
data() {
return {
name: '',
age: '',
sex: ''
}
}
...
// 逐个赋值
this.name = ''
this.age= ''
this.sex = ''
第二种:当数据了很大时第一种方法就不好用了
...
data() {
return {
param:{//搜索列表需要的参数 当点击重置按钮时需要复原
type:null,
source:null,
tagVal:'',
examineStatus:null,
depositType:null,
level:null,
startTime:null,
endTime:null,
auctionId:'',
realName:'',
phone:'',
cardNo:'',
signNo:null,//牌号
current: 1,//页码
size : 10,//页数
}
}
}
...
vue中:
this.$data
获取当前状态下的data
this.$options.data()
获取该组件初始状态下的data
上面想重置搜索的条件就可以一行代码搞定
this.form = this.$options.data().param