- 使用jquery和使用vue的区别
- 数据与视图分离,解耦(开放封闭原则)
- 以数据驱动视图,只关心数据变化,dom操作被封装
todo-list
//jquery实现
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body>
<div>
<input type="text" name="" id="txt-title">
<button id="btn-submit">submit</button>
</div>
<div>
<ul id="ul-list"></ul>
</div>
</body>
</html>
<script>
var $txtTitle=$('#txt-title');
var $ulList=$('#ul-list');
var $btnSubmit=$('#btn-submit');
$btnSubmit.click(function(){//点击按钮触发事件
var title=$txtTitle.val();//获取input框的内容
var $li=$('<li>'+title+'</li>')//创建<li>
$ulList.append($li);//创建的<li>添加到<ul>中
$txtTitle.val('');//清空input框
})
</script>
//vue实现
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script> <div id="app">
<div>
<input v-model="title">
<button @Click="add()">submit</button>
</div>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
</body>
</html>
<script>
var vm=new Vue({
el:"#app",
data:{
title:'',
list:[]
},
methods:{
add:function(){
this.list.push(this.title);
this.title='';
}
}
})
</script>
- MVC—Model,View,Controller,应用在后端
- MVVM—Model,View,ViewModel,由MVC衍生而来用于前端
- ViewModel是连接Model和View的桥梁
- View通过事件监听改变Model,Model通过数据绑定更改View
/View
<div id="app">
<div>
<input v-model="title">
<button @Click="add()">submit</button>
</div>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
Model//
var data={
title:'',
list:[]
}
//
///ViewModel//
var vm=new Vue({
el:"#app",
data:data,
methods:{
add:function(){
this.list.push(this.title);
this.title='';
}
}
})
- MVVM三大要素
- 响应式:vue如何监听到data的每个属性变化
1.1 什么是响应式?
- 修改data属性后vue立刻监听到
- data属性被代理到vm上
1.2 Object.defineProperty实现响应式
var obj={};
var name="zhangsan"
Object.defineProperty(obj,'name',{
get:function(){
console.log('get'+name)//监听
return name
},
set:function(val){
console.log('set'+val)//监听
name=val
}
})
var vm={};
var data={
name:'zhangsan',
age:20
}
var key,value
for(key in data){
(function(key){
Object.defineProperty(vm,key,{
get:function(){
console.log('get',data[key])
return data[key]
},
set: function(val){
console.log('set',val)
data[key]=val
}
})
})(key)
}
2.模板引擎:vue的模板如何被解析,指令如何处理
- 本质:字符串
- 有逻辑:如v-for等
- 与html格式很像但有很大区别
- 最终还要转化为html来显示
- 模板最终转换为js代码,渲染成render函数
3. 渲染:vue的模板如何被渲染成html,以及渲染过程
render函数—模板中所有信息都包含在render函数中(在vue.js代码中查找code.render并将其打印出来就可以看见模板的render函数)
<div id="app">
<p>{{price}}</p>
</div>
with(this){
return _c('div',{attrs:{"id":"app"}},[_c('p',[_v(_s(price))])])
}
//this即vm
//price即this.price即vm.price
//_c即this._c即vm._c
_c创建dom元素,_v创建文本节点,_s相当于toString(),_l相当于for循环
///v-model双向数据绑定,既有get又有set
实现整体流程:
- 解析模板成render函数
- 响应式开始监听
- 首次渲染,显示页面并绑定依赖
初次渲染,执行updateComponent,执行vm.render();
执行render函数会访问到data中渲染需要的属性值(用不到的属性值不管),并被响应式的get方法监听到
执行updateComponent,会走到vdom的patch方法
patch将vnode渲染成dom,初次渲染完成
4.data属性变化,触发rerender
修改属性,被响应式的set监听到,set中执行updateComponent,重新执行render()
生成的vnode和preVnode通过patch对比,渲染到html中
vm._update(vnode){
const preVnode=vm.node;
vm._vnode=vnode;
if(!preVnode){
vm.$el=vm.__patch__(vm.$el,vnode)
}else{
vm.$el=vm.__patch__(preVnode,vnode)
}
}
function updateComponent(){
vm._update(vm.render())
//render函数返回vnode
}