一,使用jquery和使用vue的区别
二,对MVVM的理解
三,vue中如何实现响应式
四,vue如何解析模版
五,vue整个实现流程
 
一,使用jquery和使用vue的区别
jquery实现todo-list
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>todo-list-jquery</title>
</head> <body>
<div>
<input type="text" id="txt-title">
<button id="btn-submit">submit</button>
</div>
<ul id="ul-list"></ul>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
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>todo-list-vue</title>
<script src="./vue-2.5.13.js"></script>
</head> <body>
<div id="app">
<div>
<input v-model="title">
<button v-on:click="add">submit</button>
</div>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
title: '',
list: [],
},
methods: {
add: function() {
if (this.title) {
this.list.push(this.title);
this.title = '';
}
}
}
})
</script>
</body> </html> 
jquery和vue两者的区别:
数据和视图的分离-解耦(开放封闭原则)
以数据驱动视图-只关心数据变化,DOM操作被封装
 
二,对MVVM的理解
1,先说下MVC:
M-Model 数据
V-VIew 视图、界面
C-Controller 控制器、逻辑处理
两种场景:
2,MVVM
Model-模型、数据
View-视图、模版(视图和模型是分离的)
ViewModel-连接Model和View,“桥”
 
3,关于ViewModel
MVVM不算是一种创新-是微创新
但其中的ViewModel是一种创新
真正结合前端场景应用的创建

 
 
 
4,MVVM框架的三大要素(实现的三要素)
响应式:vue如何间听到data的每个属性变化?
模版引擎:vue的模版如何被解析,指令如何处理?
渲染:vue的模版如何被渲染成html?以及渲染过程
 
三,vue中如何实现响应式
1,什么是响应式
修改data属性之后,vue立刻监听到
data属性被代理到vm(this)上,data的属性,同时也变成了this的属性
例:
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>vue-demo</title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
</head> <body>
<div id="app">
<p>{{name}}</p>
<p>{{age}}</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
name:'zs',
age:20
}
})
console.log(vm.age)
</script>
</body> </html>

在控制台修改vm.age  或者vm.name,立刻会被监听渲染出来

2,Object.defineProperty:直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
语法:
Object.defineProperty(obj, prop, descriptor)

例子:

    var obj = {};
var _name = 'zs';
Object.defineProperty(obj,'name',{
get:function(){
console.log('get',_name);//监听
return _name;
},
set:function(newVal){
console.log('set',newVal);//监听
_name = newVal;
}
});
3,模拟实现(监听+代理)
    var vm = {};
var data = {
name: 'zs',
age: 20
};
var key, value;
for (key in data) {
// 命中闭包,新建一个函数,保证key的独立的作用域
(function(key) {
Object.defineProperty(vm, key, { //data属性代理到vm上
get: function() {
console.log('get', data[key]); //监听
return data[key];
},
set: function(newVal) {
console.log('set', newVal); //监听
data[key] = newVal;
}
})
})(key)
}
看下控制台中,此时打印的vm
 
四,vue如何解析模版
1,模版是什么
本质:字符串
有逻辑,如v-if,v-for等
与html格式很像,但有很大区别(html静态的,没有逻辑)
要转换为html来显示
 
模版最终必须要转换成js代码,原因如下:
有逻辑(v-if,v-for),前端必须用js才能实现(图灵完备)
转换为html渲染页面,前端必须用js才能实现
因此,模版最终要转换成一个js函数(render函数,即渲染函数)
 
2,render函数
render函数-with的用法(with可以了解下实现,但是实际开发中最好不要用,问题比较多)
先看下with的简单用法:
    var obj = {
name: 'xx',
age:20,
getAddress:function(){
console.log('bj');
}
}
// 不用with
function fn(){
console.log(obj.name);
console.log(obj.age);
obj.getAddress();
}
fn() // 使用with
function fn1(){
with(obj) {
console.log(name);
console.log(age);
getAddress();
}
}
fn1()
3,render函数
模版:
    <div id="app">
<p>{{price}}</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
price:100
}
})
</script>

render函数如下:

    // 以下是手写的 render 函数 使用 with ,代码简洁一些
function render() {
with(this) {
return _c(
'div', {
attrs: { "id", "app" }
}, [
_c('p', [_v(_s(price))])
]
)
}
}
// 不用 with 的改写的 render 函数
function render1() {
return vm._c(
'div', {
attrs: { "id", "app" }
}, [
vm._c('p', [_vm.v(vm._s(vm.price))])
]
)
} // 模版中所有信息都包含在了 render 函数中
// this === vm
// price 即 this.price 即vm.price, 即 data 中的 price
// _c 即 this._c , 即 vm._c

看下控制台:

问题:
从哪里可以看到render函数?
复杂一点的例子,render函数是什么样子的?
v-if, v-for, v-on都是怎么处理的?
 
回顾之前的demo
<div id="app">
<div>
<input v-model="title">
<button v-on:click="add">submit</button>
</div>
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>

对应的render函数:(通过在vue-2.5.13.js源码中 console.log(code.render)得出)

    with(this){
return _c(
'div',
{attrs:{"id":"app"}},
[_c('div',
[_c(
'input',
{
directives:[
{
name:"model",
rawName:"v-model",
value:(title),
expression:"title"
}
],
domProps:{"value":(title)},
on:{
"input":function($event){
if($event.target.composing)return;
title=$event.target.value
}
}
}
),
_v(" "),
_c(
'button',
{
on:{
"click":add
}
},
[_v("submit")]
)
]),
_v(" "),
_c(
'ul',
_l(
(list),function(item){
return _c(
'li',
[
_v(
_s(item)
)
]
)
}

)
]
)
}
根据todo-list demo的render函数:
v-model是怎么实现的?:双向数据绑定,既有get,又有set
v-on:click是怎么实现的?:渲染时绑定click事件
v-for是怎么实现的?:对数组进行遍历,li标签,最后归结为数组,作为ul的子元素
 
模版生成html  
vm.c其实就相当于snabbdom中的h函数
render函数执行之后,返回的是vnode
vm._update(vnode) {
const prevVnode = vm._vnode;
vm._vnode = vnode;
if (!prevVnode) {
// 初次渲染
vm.$el = vm.__patch__(vm.$el, vnode);
} else {
// re-render
vm.$el = vm.__patch__(prevVnode, vnode);
} } function updateComponent() {
// vm._render即上面的render函数,返回vnode
vm._update(vm._render())
} // updateComponent实现了vdom的patch
// 页面首次渲染执行updateComponent(执行第一个patch)
// data中每次修改属性,执行updateComponent,修改data,set中可以执行updateComponent
vue如何解析模版:
模版:字符串(本质),有逻辑,嵌入js变量...
模版必须转换为js代码(有逻辑,渲染html,js变量)前端中,只有js才能处理逻辑和渲染html等
render函数: with语法,就是snabbdom里h函数的样子
render函数执行是返回vnode
updateComponent 首次渲染,非首次渲染(data属性修改)
 
五,vue的整个实现流程
第一步:解析模版成render函数
with用法(了解即可,自己开发的时候,尽量避免使用)
模版中的所有信息都被render函数包含
模版中用到的data中的属性,都变成了js变量
模版中的v-model,v-for,v-on都变成了js逻辑
render函数返回vnode
 
第二步:响应式开始监听
Object.defineProperty中设置监听
将data的属性代理到vm上
 
第三步:首次渲染,显示页面,且绑定依赖
初次渲染,执行updateComponent,执行vm._render()
执行render函数,会访问到vm.list和vm.title
会被响应式的get方法监听到(后面详细讲)
执行updateComponent,会走到vdom的patch方法
patch将vnode渲染成DOM,初次渲染完成
疑问:
为何要监听get,直接监听set不行吗?
data中有很多属性,有些被用到,有些可能不被用到
被用到的会走到get,不被用到的不会走到get
未走到get中的属性,set的时候我们也无须关心
避免不必要的重复渲染
 
第四步:data属性变化,触发rerender
修改属性,被响应式的set监听到
set中执行updateComponent (这里是异步的)
updateComponent重新执行vm._render()
生成的vnode和prevVnode,通过patch进行对比
渲染到html中

附:Vue的生命周期

vue调试工具vue-devtools安装及使用

MVVM 和 VUE的更多相关文章

  1. MVVM 和 VUE三要素:响应式、模板引擎、渲染

    MVVM 和 VUE三要素:响应式.模板引擎.渲染:https://blog.csdn.net/weixin_37644989/article/details/94409430

  2. 简简单单的Vue1(MVVM与Vue的双向绑定原理)

    既然选择了远方,便只顾风雨兼程 __ HANS许 系列:零基础搭建前后端分离项目 系列:零基础搭建前后端分离项目 Vue 在此之前的文章我们讲述了前端开发的工具,语言的知识,接下来我们从头开始学习一个 ...

  3. MVVM以及vue的双向绑定

    原文:https://www.cnblogs.com/onepixel/p/6034307.html MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核 ...

  4. 【前端知识体系-JS相关】深入理解MVVM和VUE

    1. v-bind和v-model的区别? v-bind用来绑定数据和属性以及表达式,缩写为':' v-model使用在表单中,实现双向数据绑定的,在表单元素外使用不起作用 2. Vue 中三要素的是 ...

  5. Vue.js 和 MVVM 小细节

    MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...

  6. vue和mvvm的一些小区别

    Vue.js 和 MVVM 小细节   MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这 ...

  7. Vue.js 和 MVVM 的小细节

    Vue.js 和 MVVM 的小细节 转载 作者:流云诸葛 链接:www.cnblogs.com/lyzg/p/6067766.html MVVM 是Model-View-ViewModel 的缩写, ...

  8. 基于vue实现一个简单的MVVM框架(源码分析)

    不知不觉接触前端的时间已经过去半年了,越来越发觉对知识的学习不应该只停留在会用的层面,这在我学jQuery的一段时间后便有这样的体会. 虽然jQuery只是一个JS的代码库,只要会一些JS的基本操作学 ...

  9. Vue.js 是如何实现 MVVM 的?

    目录 框架到底为我们做了什么? 如何理解 MVVM ? 如何实现 MVVM - 以 Vue.js 为例 Vue 如何实现响应式 Vue 如何解析模板 Vue.js 运行机制 手写一个 Vue.js 框 ...

随机推荐

  1. 由百度 “PHP薪资” 引发的思考

    昨天晚上睡觉的时候百度了一下 “PHP薪资”,看到了各种各样的答案,从百度知道到知乎,再到各个论坛……答案也是从 2k-16k 不等(不过说实话,2k是吓到我了),其中一些答案说到了在中国从事某一行业 ...

  2. Tomcat 在 Linux 上的安装和配置

    一.文件上传 先上传tomcat安装文件到Linux服务器 二.解压安装 使用以下命令解压安装包 .tar.gz 解压成功会生成一个文件夹 tomcat服务器运行时是需要JDK支持的,所以必须先安装好 ...

  3. 关于hermes与solr,es的定位与区别

    Hermes与开源的Solr.ElasticSearch的不同 谈到Hermes的索引技术,相信很多同学都会想到Solr.ElasticSearch.Solr.ElasticSearch在真可谓是大名 ...

  4. 跨浏览器的javascript事件的封装

    一,跨浏览器的事件处理程序 1,DOM0级处理事件 将一个函数赋值给一个事件处理程序属性. 事件流:冒泡阶段. 使用: 为元素增加事件: var btn = document.getElementBy ...

  5. Windows Azure开发之Linux虚拟机

     Windows Azure是微软的云服务集合,用来提供云在线服务所需要的操作系统与基础存储与管理的平台,是微软的云计算的核心组成组件之一.其中windows azure提供的最重要的一项服务就是 ...

  6. 【sping揭秘】23、Spring框架内的JNDI支持

    JndiTemplate 经过jdbctemplate,transactionTemplate...的洗礼,想必大家看到template就知道是个什么尿性了吧 一样的,我们只需要调用jnditempl ...

  7. UFLDL 教程学习笔记(二)反向传导算法

    UFLDL(Unsupervised Feature Learning and Deep Learning)Tutorial 是由 Stanford 大学的 Andrew Ng 教授及其团队编写的一套 ...

  8. 课程四(Convolutional Neural Networks),第三 周(Object detection) —— 0.Learning Goals

    Learning Goals: Understand the challenges of Object Localization, Object Detection and Landmark Find ...

  9. python常用函数和方法 - 备忘

    语法语句篇 除法运算(精确运算和截断运算) 在python2中,除法运算通常是截断除法.什么是截断除法: >>> 3/4 0 # 自动忽略小数项 要是想 得到正确结果 怎么办呢? m ...

  10. Solidity中uint转bytes

    Solidity中uint转bytes方法如下: pragma solidity ^0.4.2; contract Test { function toBytesNickJohnson(uint256 ...