- 说一下使用jQuery和框架(vue)的区别
- 说一下对MVVM的理解
- vue中如何实现响应式(vue如何检讨到data的每个属性的变化)
- vue如何解析模板(vue的模板如何被解析,指令如何处理)
- vue的整个实现流程(vue的模板如何被渲染成html,渲染过程)
一、jQuery实现todo-list
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<input type="text" name="" id="txt-title">
<button id="btn-submit">submit</button>
</div>
<div id="ul-list"></div>
<script src="jquery-1.12.4.min.js"></script>
<script type="text/javascript">
var $txtTitle = $('#txt-title')
var $btnSubmit = $('#btn-submit')
var $ulList = $('#ul-list')
$btnSubmit.click(function(){
var title = $txtTitle.val()
if(!title){
return
}
var $li = $('<li>' + title + '</li>')
$ulList.append($li)
$txtTitle.val('')
})
</script>
</body>
</html>
二、vue实现todo-list
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>
<input type="text" v-model="title">
<button id="btn-submit" v-on:click="add">submit</button>
</div>
<div id="ul-list">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.min.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
title:'',
list:[]
},
methods: {
add: function(){
this.list.push(this.title)
this.title = ''
}
}
})
</script>
</body>
</html>
vue实现的时候没有修改DOM结构,而jQuery实现的时候有操作DOM的结构。
三、jQuery和框架的区别
- 数据和视图的分离,解耦(开放封闭原则)
jQuery中数据处理的逻辑和数据已经混合在一起了。jQuery中数据视图并未分离,而vue数据试图分离了。
- 以数据驱动视图,只关心数据变化,DOM操作被封装
只改数据,试图怎么变我不管,jQuery完全违背了这个理念。vue用数据驱动了试图的变化。
四、MVC
五、MVVM
MVVM —— Model View ViewModel。ViewMode的理解,联系View和Model。
六、MVVM(vue)框架的三大要素
- 响应式:vue如何监听到data的每个属性变化
- 模板引擎:vue的模板如何被解析,指令如何处理
- 渲染:vue的模板如何被渲染成html,以及渲染过程
1、vue中如何实现响应式
什么是响应式?响应式就是data属性被修改之后,vue立刻监听到。data属性被代理到vm上。
2、Object.defineProperty
var obj = {
name: 'zhangsan',
age: 25
}
console.log(obj.name) //获取属性的时候,如何监听到
obj.age = 26 //赋值属性的时候,如何监听到
我们使用Object.defineProperty来监听
var obj = {}
var name = 'zhangsan'
Object.defineProperty(obj, "name", {
get: function(){
console.log('get')
return name
},
set: function(newVal){
console.log('set')
name = newVal
}
});
console.log(obj.name) //可以监听到
obj.name = 'lisi' //可以监听到
vue中实现监听的原理(vue响应式模拟)
var vm = {}
var data = {
name: 'zhangsan',
age: 20
}
var key, value
for(key in data){
(function(key){ //将data里面的值代理到了vm上面
Object.defineProperty(vm, key ,{
get: function(){
return data[key]
},
set:function(newVal){
data[key] = newVal
}
})
})(key)
}
3、模板是什么?
如下就是一个模板,就是上面doto-list里面的:
<div id="app">
<div>
<input type="text" v-model="title">
<button id="btn-submit" v-on:click="add">submit</button>
</div>
<div id="ul-list">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
</div>
模板本质上是字符串。但是模板有逻辑,因为它有v-for v-if等。它与HTML很像,但是有很大区别,因为HTML是静态的,模板是动态的。但是模板最终最转化成HTML来显示。模板是一串字符串,最终必须转化成JS代码,因为有逻辑,必须要JS才能处理逻辑,还有就是最后转换成HTML渲染页面,必须使用JS才能实现。因此,模板最重要的是转换成JS函数(render函数)
4、render函数 —— width的用法
5、render函数
左边的模板,生成右边的render函数,右边是render函数的函数体。右边的this就是vm 。模板中所有信息都包含在render函数中,this即vm,price即this,price即vm.price,即data中的price。
下面是一个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<p>{{price}}</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data: {
price: 10
}
})
//以下是手写的ppt中的render函数
//使用width
function render() {
with(this){ //这里的with就是vm
_c(
'div',
{
attrs:{'id': 'app'}
},
[
_c('p',[_v(_s(price))])
]
)
}
}
//不使用with
function render1() {
return vm._c(
'div',
{
attrs:{'id': 'app'}
},
[
vm._c('p',[vm._v(vm._s(vm.price))])
]
)
}
</script>
</body>
</html>
5、todo-list的模板的render函数
with(this){
return _c(
'div',
{
attrs:{"id":"app"}
},
[
_c(
'div',
[
_c(
'input',
{
directives:[
{
name:"model",
rawName:"v-model",
value:(title),
expression:"title"
}
],
attrs:{"type":"text"},
domProps:{
"value":(title)
},
on:{
"input":function($event){
if($event.target.composing)
return;
title=$event.target.value
}
}
}
),_v(" "),
_c(
'button',
{
attrs:{"id":"btn-submit"},
on:{
"click":add
}
},
[_v("submit")]
)
]
),
_v(" "),
_c(
'div',
{attrs:{"id":"ul-list"}},
[
_c(
'ul',
_l((list), function(item){return _c('li',[_v(_s(item))])})
)
]
)
]
)
}
v-modele是怎么实现的:双向数据绑定,既有get,又有set
v-click是怎么实现的:绑定click事件
v-for是怎么实现的:for循环遍历
6、模板生成html,也就是render函数和html之前的关系。
render函数返回vnode,_c和h函数是一样的,返回vnode。
7、题目解答
- 模板:字符串,有逻辑,嵌入JS变量
- 模板必须转换为JS代码(有逻辑,渲染html,JS变量)
- render函数是什么样子的
- render函数执行返回vnode
- updataComponent
七、vue的整个实现流程
- 第一步:解析模板成render函数
- with的函数
- 模板中的所有信息都被render函数包含
- 模板中用到的data中的属性,都变成了JS变量
- 模板中的v-model v-for v-on都变成了JS逻辑
- render函数返回vnode
- 第二步:响应式开始监听
- Object.definePrototype
- 将data的属性代理到vm上
- 第三步:首次渲染,显示页面,且绑定依赖
- 初次渲染,执行updateComponent,在执行vm._render()
- 执行render函数,会访问到vm.list和vm.title
- 会被响应式的get方法监听到(为何监听get,直接监听set不行吗?因为data中有很多属性,有些会被用到,有些可能不被用到,被用到的会走到get,不被用到的不会走get。未走到get中的属性,set的时候我们也无需关心。目的是避免不必要的重复渲染)
- 执行updateComponent,会走到vdom的patch方法
- patch将vnode渲染成DOM,初次渲染完成
- 第四步:data属性变化,触发rerender
- 修改属性,被响应式的set监听到
- set中执行updateComponent
- updateComponent重新执行vm._render()
- 生成的vnode和prevVnode,通过patch进行对比
- 渲染到HTML中
八、题目解答
- 说一下使用jQuery和使用框架的区别
解答:(1)数据视图的分离,解耦。(2)以数据驱动试图,只关心数据变化,DOM操作被封装。
- 说一下对MVVM的理解
解答:(1)Model View ViewModel。(2)三者之间的联系,以及如何对应到隔断代码。(3)ViewModel的理解,联系View和Model。
- vue中如何实现响应式
解答:(1)关键是理解Object.definePrototype。(2)将data的属性代理到vm上
- vue中如何解析模板
解答:(1)模板:字符串,有逻辑,嵌入JS变量。(2)模板必须转化为JS代码(有逻辑、渲染HTML、JS变量)。(3)render函数是什么样子。(4)render函数执行是返回vnode。(4)updateComponent。
- vue的整体实现流程
解答:(1)解析模板成render函数。(2)响应式开始监听。(3)首席渲染,显示页面,且绑定依赖。(4)data属性变化,触发rerender