‘壹’ Vue基础篇
内容简介:
1)Vue指令
2)computed和watch
3)生命周期钩子
4)组件间的传参
5)插槽
6)修饰符
7)nextTick()
前端三大框架:
Vue:尤雨溪开发
React:Facebook主导开发
Angular:谷歌主导开发
为什么选择Vue?
1.国内Vue的市场份额占比多
2.简单易上手,非常适合前端开发初学者学习
前置知识:
1.HTML、CSS和JS基础
2.了解Node和npm
3.webpack(可选,vue-cli已经封装了打包功能)
使用Vue的两种方式:
1.直接script标签引入vue.js文件
2.基于Node环境创建Vue项目(使用vue-cli初始化一个Vue项目)
前端框架与库的区别
• jquery 库 -> DOM(操作DOM) + 动画+ ajax请求
• 框架 -> 全方位功能
一、指令
指令(Directives)是带有 v- 前缀的特殊属性。
插值表达式和v-text指令被直接解析为字符串;元素绑定 v-html 指令后,解析了msg 变量值里面的html标签,输出真正的html元素。
v-model也可用在自定义组件上。
5.v-for(列表渲染)
使用v-for时应绑定key属性,key属性可以用来提升v-for渲染的效率
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
由于 JavaScript 的限制,Vue 不能检测数组、对象的以下变化:1. 利用索引直接设置数组的某一项 2. 对象属性的添加或删除
二、computed和watch
三、生命周期钩子
什么是Vue生命周期?
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程。
总共分为8个阶段:创建前/后,挂载前/后,更新前/后,销毁前/后。
1)beforeCreate
此时实例上只有一些生命周期函数和默认的事件,此时data computed watch methods上的方法和数据均不能访问。
2)created
此时可以读取data的值,并可以对其进行操作,把方法、计算属性也都挂载到了实例。但是依旧不能访问el,不能获取到DOM元素。
在这个钩子函数中,我们可以进行http请求,把请求到的数据储存在data中。
3)模板编译,把data里面的数据和vue语法写的模板编译成HTML
4)beforeMount
将编译完成的HTML挂载到对应虚拟DOM,此时还未挂载到页面上
5)mounted
编译好的HTML已挂载到页面上
6)beforeUpdate和updated
数据更新时调用,通常使用计算属性或侦听器取而代之
7)beforeDestroy
销毁所有观察者、组件及事件监听
8)destroyed
组件已经完全销毁,组件中的数据、方法、计算属性、过滤器等都已不可用。
四、组件间的通信
1.父子组件间的通信
父子组件通信可以总结为props向下传递,事件向上传递。
单向数据流:父级 prop 的更新会向下流动到子组件中,但反过来不行。
每个Vue实例都实现了事件接口:子组件使用 this.$emit(eventName,optionalPayload) 触发自定义事件。父组件在使用子组件的地方直接用v-on来监听子组件触发的事件。
父组件通过ref直接调用子组件中的方法。
子组件调用父组件中的方法:
1)子组件中通过 this.$parent.fatherMethod() 来调用父组件的方法
2)子组件用$emit向父组件触发一个事件,父组件监听这个事件
3)父组件通过props把方法传入子组件中(type: Function),在子组件里直接调用这个方法
2.兄弟组件间的通信
其中一种方法是让父组件充当两个子组件之间的中间件(中继);
另一种就是使用EventBus(事件总线),它允许两个组件之间直接通信,而不需要涉及父组件:
Vue原型上的方法:
五、插槽
3)作用域插槽
使用场景:
在使用ElementUI组件库的el-table组件时,表格的编辑和删除操作要用到作用域插槽。因为el-table组件,就是当前组件的子组件。通过作用域插槽很容易拿到当前表格行的索引和内容,这样就可以很方便地进行编辑、删除的操作。v-slot指令是Vue2.6之后,作用域插槽的新语法,旧语法(slot-scope)现在还保留,但3.0之后会移除。
六、修饰符
2.事件修饰符
vue提倡的是在方法中只有纯粹的数据逻辑,而不是去处理 DOM 事件细节,所以提供了事件修饰符用于DOM的事件处理。
3.按键修饰符
七、nextTick()
定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。(当数据更新了,在dom中渲染后,自动执行nextTick的回调)
应用场景:需要在视图更新之后,基于新的视图进行操作。
‘贰’ 理解VUE2双向数据绑定原理和实现
1.vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
2.核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法;
3.介绍一下Object.defineProperty()方法
(1)Object.defineProperty(obj, prop, descriptor) ,这个语法内有三个参数,分别为 obj (要定义其上属性的对象) prop (要定义或修改的属性) descriptor (具体的改变方法)
(2)简单地说,就是用这个方法来定义一个值。当调用时我们使用了它里面的get方法,当我们给这个属性赋值时,又用到了它里面的set方法;
这样我们就能实现js的双向数据绑定,也对这个方法有初步的了解 ;
这个例子实现的效果是:随着文本框输入文字的变化,span中会同步显示相同的文字内容;这样就实现了 model => view 以及 view => model 的双向绑定。
通过添加事件监听keyup来触发set方法,而set再修改了访问器属性的同时,也修改了dom样式,改变了span标签内的文本。
1.实现效果
先来看一下vue双向数据绑定是如何进行的,以便我们确定好思考方向
2.任务拆分
拆分任务可以让我们的思路更加清晰:
(1)将vue中的data中的内容绑定到输入文本框和文本节点中
(2)当文本框的内容改变时,vue实例中的data也同时发生改变
(3)当data中的内容发生改变时,输入框及文本节点的内容也发生变化
3.开始任务1——绑定内容
我们先了解一下 DocuemntFragment(碎片化文档) 这个概念,你可以把他认为一个dom节点收容器,当你创造了10个节点,当每个节点都插入到文档当中都会引发一次浏览器的回流,也就是说浏览器要回流10次,十分消耗资源。
而使用碎片化文档,也就是说我把10个节点都先放入到一个容器当中,最后我再把容器直接插入到文档就可以了!浏览器只回流了1次。
注意:还有一个很重要的特性是,如果使用appendChid方法将原dom树中的节点添加到DocumentFragment中时,会删除原来的节点。
举个例子:
可以看到,我的app中有两个子节点,一个元素节点,一个文本节点
但是,当我通过DocumentFragment 劫持数据一下后
注意:我的碎片化文档是将子节点都劫持了过来,而我的id为app的div内已经没有内容了。
同时要主要我while的判断条件。判断是否有子节点,因为我每次appendChild都把node中的第一个子节点劫持走了,node中就会少一个,直到没有的时候,child也就变成了undefined,也就终止了循环。
来实现内容绑定
我们要考虑两个问题,一个是如何绑定要input上,另一个是如何绑定要文本节点中。
这样思路就来了,我们已经获取到了div的所以子节点了,就在DocumentFragment里面,然后对每一个节点进行处理,看是不是有跟vm实例中有关联的内容,如果有,修改这个节点的内容。然后重新添加入DocumentFragment中。
首先,我们写一个处理每一个节点的函数,如果有input绑定v-model属性或者有{{ xxx }}的文本节点出现,就进行内容替换,替换为vm实例中的data中的内容
然后,在向碎片化文档中添加节点时,每个节点都处理一下。
创建Vue的实例化函数
效果图如下:
我们成功将内容都绑定到了输入框与文本节点上!
4、实现任务2——【view => model
对于此任务,我们从输入框考虑,输入框的问题,输入框如何改变data。我们通过事件监听器keyup,input等,来获取到最新的value,然后通过Object.defineProperty将获取的最新的value,赋值给实例vm的text,我们把vm实例中的data下的text通过Object.defineProperty设置为访问器属性,这样给vm.text赋值,就触发了set。set函数的作用一个是更新data中的text,另一个等到任务三再说。
首先实现一个响应式监听属性的函数。一旦有赋新值就发生变化
然后,实现一个观察者,对于一个实例 每一个属性值都进行观察。
改写编译函数,注意由于改成了访问器属性,访问的方法也产生变化,同时添加了事件监听器,把实例的text值随时更新
实例函数中,观察data中的所有属性值,注意增添了observe
最终我们改变input中的内容能改变data中的数据,单页面却没有刷新
4、实现任务3——【model => view】
通过修改vm实例的属性 该改变输入框的内容 与 文本节点的内容。
这里涉及到一个问题 需要我们注意,当我们修改输入框,改变了vm实例的属性,这是1对1的。
但是,我们可能在页面中多处用到 data中的属性,这是1对多的。也就是说,改变1个model的值可以改变多个view中的值。
这就需要我们引入一个新的知识点:
订阅/发布者模式
订阅发布模式(又称观察者模式)定义了一种一对多的关系,让多个观察者同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察者对象。
发布者发出通知 => 主题对象收到通知并推送给订阅者 => 订阅者执行相应操作
1
举个例子:
之前提到的set函数的第二个作用 就是来提醒订阅者 进行noticy操作,告诉他们:“我的text变了!” 文本节点变成了订阅者,接到消息后,立马进行update操作
回顾一下,每当 new 一个 Vue,主要做了两件事:第一个是监听数据:observe(data),第二个是编译 HTML:nodeToFragement(id)。
在监听数据的过程中,我们会为 data 中的每一个属性生成一个主题对象 dep。
在编译 HTML 的过程中,会为每个与数据绑定相关的节点生成一个订阅者 watcher,watcher 会将自己添加到相应属性的 dep 容器中。
我们已经实现:修改输入框内容 => 在事件回调函数中修改属性值 => 触发属性的 set 方法。
接下来我们要实现的是:发出通知 dep.notify() => 触发订阅者的 update 方法 => 更新视图。
这里的关键逻辑是:如何将 watcher 添加到关联属性的 dep 中。
注意: 我把直接赋值的操作改为了 添加一个 Watcher 订阅者
那么,Watcher又该做些什么呢?
首先,将自己赋给了一个全局变量 Dep.target;
其次,执行了 update 方法,进而执行了 get 方法,get 的方法读取了 vm 的访问器属性,从而触发了访问器属性的 get 方法,get 方法中将该 watcher 添加到了对应访问器属性的 dep 中;
再次,获取属性的值,然后更新视图。
最后,将 Dep.target 设为空。因为它是全局变量,也是 watcher 与 dep 关联的唯一桥梁,任何时刻都必须保证 Dep.target 只有一个值。
最终我们就实现了这个双向数据绑定功能,虽然很繁琐,但我相信,你多打几遍,一定会对你有所帮助,加油吧!!
‘叁’ vue2响应式原理总结
vue组件实例化时,会对data属性深度遍历(遇到数组或者对象)为每一个属性添加数据劫持。数据劫持就是使用Object.defineProperty(de fai in pro pu tei)方法添加get/set方法。
在这个过程中会实例化一个Dep类。
1.在get拦截器里触发dep实例的depend方法,进行依赖收集,实质是在dep的实例属性sub数组中添加依赖这个属性的watcher实例。
2.在set拦截器里触发dep实例的notify方法,对收集到的所有依赖派发更新,(watcher的update方法)
vue组件实例化时会实例化一个渲染watcher,渲染watcher实例化过程会做两件事情。
1.创建vnode,在这个过程中,访问了data属性,触发了get方法,完成了依赖收集。
2.触发了子组件的实例化,子组件实例化又会重复上述数据劫持的过程。
这个过程就是对组件树的深度遍历。
结合组件生命周期来看整个过程,父组件会先触发created钩子,子组件后触发created钩子。而子组件mouted钩子会先执行,父组件的mouted钩子后执行。
分步骤记忆
1、实现页面不刷新的原理
2、页面视图刷新的原理
实现页面不刷新
1.hash
2.history
3.abstract:支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。
1.hash(哈希模式),#符号后边是浏览器行为,在改变的时候不对页面进行刷新(重新请求URL)(监听hashChange事件)
2.history模式,H5新增了pushState,replaceState连个新API,可以修改历史记录却不会使浏览器刷新页面。
视图更新原理
其原理就是vue的响应式更新dom的原理,m => v
m是数据,也就是在vue-router install时在根组件(root vue component)添加了_route属性,在匹配到对应路由后更新了_route属性值,继而触发了该属性值的渲染watcher,在继而触发dom更新。
两种模式的不同
1.部署时,history模式需要服务端处理所有可能的路径(例如配置nginx的配置文件),防止出现404。哈希模式则不需要。
2.URL表示不同。
v-model指令就是 v-bind:value 和 @input 的语法糖。
它即可以支持原生表单元素,也可以支持自定义组件
在自定义组件中其实际是这样的:
它的实现通过自定义render函数, 缓存了 vnode
Vue 在更新 DOM 时是异步执行的,只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
如果同一个 watcher 被多次触发,只会被推入到队列中一次。在缓冲时会去除重复数据避免不必要的计算和 DOM 操作。
$nextTick(cb) 目的是在DOM 更新完成后传入的回调函数再被调用。
‘肆’ vue怎么学习(网营作业)
Vue基础部分
第一章:内部指令
1.v-if v-else v-show
2.v-for指令 :解决模板循环问题
3.v-text & v-html
4.v-on:绑定事件监听器
5.v-model指令
6.v-bind 指令
7.v-pre & v-cloak & v-once
第二章:全局API
1.Vue.directive 自定义指令
2.Vue.extend构造器的延伸
3.Vue.set全局操作
4.Vue的生命周期(钩子函数)
5.Template 制作模版
6.Component 初识组件
7.Component 组件props 属性设置
8.Component 父子组件关系
第三章:选项
1.propsData Option 全局扩展的数据传递
2.computed Option 计算选项
3.Methods Option 方法选项
4.Watch 选项 监控数据
5.Mixins 混入选项操作
6.Extends Option 扩展选项
第四章:实例和内置组件
1.实例入门-实例属性
2.实例方法
3.实例事件
4.内置组件 -slot讲解
Vue全家桶部分
第五章:Vue-cli
1.Vue-cli安装和初始化
2.Vue-cli项目结构讲解
3.解读Vue-cli的模板
第六章:Vue-router
1.Vue-router入门
2.vue-router配置子路由
3.vue-router如何参数传递
4.单页面多路由区域操作
5.vue-router 利用url传递参数
6.vue-router 的重定向-redirect
7.alias别名的使用
8.路由的过渡动画
9.mode的设置和404页面的处理
10.路由中的钩子
11.编程式导航
第七章:Vuex
1.初出茅庐 来个小Demo
2.state访问状态对象
3.Mutations修改状态
4.getters计算过滤操作
5.actions异步修改状态
6.mole模块组
‘伍’ vue基础知识简述(v-if&v-for&v-show&v-model)
条件渲染主要有两个指令:v-if v-show
有v-if 相应会有 v-else v-else-if
v-if指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回truthy值的时候被渲染
v-if为true的表达式会显示
v-if为false的表达式不会显示
示例需要用到的data部分:
利用data变量进行判断使用
类似于if-else条件语句判断
在template上使用 v-if 条件渲染分组
利用上面提供的data变量和下面的template结合,启动网页后查看源码可知
v-show与v-if区别:
v-show 只是简单的切换元素的display CSS propertity,带有 v-show 元素始终会被渲染并保存在 dom 中
v-if:后面若为false,标签直接消失,控制dom元素的创建和销毁
v-if是一个编译、卸载的过程,创建和销毁子组件
v-show是控制css property
v-for用于循环遍历数据
示例需要用到的data部分:
用v-for把一个数组映射为一组元素
v-for基于一个数组来渲染一个列表
v-for使用数组,item代表数组中每个元素,index表示数组元素下标
两种分隔符:in of
item标识键值,key表示键名,index表示索引
注意观察上面循环标签的最后都有 :key
为什么要添加key?
key作为唯一标识
为了给vue一个提示,以便它能跟踪每一个节点的身份,重而重用和重新排序现有元素
官方解释:
你可以用v-model 指令在表单<input> 、 <textarea>及<select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model本质上不过是语法糖。它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。
v-model会 忽略所有表单元素的value 、checked 、 selected attribute 的初始值。 它将始终将当前活动实例的数据作为数据来源。你应该通过JavaScript在组件的 data选项中声明初始值。
v-bind (:value="msg")负责将data变量显示页面input框
v-on (@input="changeValue) 负责利用函数中事件对象获取页面input框的值传data变量使其发生改变
缺陷:v-model数据中每一次改变都会触发试图更新,特别消耗性能
因此官方为v-model设定了一些修饰符
lazy ,当输入框失去焦点,再去同步输入框中的数据
trim:自动过滤用户输入的首尾空白字符
如果想自动将用户的输入值转为数值类型,可以给v-model添加number修饰符
‘陆’ 10《Vue 入门教程》Vue 双向绑定指令
本小节我们将介绍 Vue 中数据的双向绑定指令 v-model 。 v-model 的学习相对简单。我们可以用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
2. 木子解释用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。— 官方定义
v-model 是 vue 提供的用来对表单控件做数据双向绑定的指令。它可以根据用户的输入动态改变其绑定的值,同样可以根据绑定值的改变来操作页面 DOM 的更新。
3. 基本用法接下来我们将详细介绍 v-model 在不同表单元素上的使用。
3.1 单行文本 input实例演示
Document名称是: {{ name }}
"运行案例" 可查看在线运行效果
代码解释: 上述代码,我们通过 v-model 给输入框 input 和 name 形成双向绑定,当 input 中数据发生改变时 name 也会发生改变。同理,我们在控制台通过 vm.name = "" 给 name 赋值时输入框的内容也会发生改变。
3.2 多行文本 textarea实例演示
Document描述是: {{ desc }}
"运行案例" 可查看在线运行效果
代码解释: 上述代码,我们通过 v-model 给输入框 textarea 和 desc 形成双向绑定,当 textarea 中数据发生改变时 desc 也会发生改变。同理,我们在控制台通过 vm.desc = "" 给 desc 赋值时输入框的内容也会发生改变。
实例演示
"运行案例" 可查看在线运行效果
代码解释: 上述代码,我们通过 v-model 给单个选择框 checkbox 和 isDelivery 形成双向绑定,当 checkbox 改变选中状态时 isDelivery 也会发生改变。同理,我们在控制台通过 vm.isDelivery = true 给 isDelivery 赋值时 checkbox 的选中状态也会发生改变。
实例演示
"运行案例" 可查看在线运行效果
代码解释: 上述代码,我们通过 v-model 给多个选择框 checkbox 和 types 形成双向绑定,当任意 checkbox 改变选中状态时 types 也会发生改变。同理,我们在控制台通过 vm.types = [] 给 types 赋值时对应 checkbox 的选中状态也会发生改变。
实例演示
"运行案例" 可查看在线运行效果
代码解释: 上述代码,我们通过 v-model 给单选按钮 radio 和 isFree 形成双向绑定,当 radio 改变选中状态时 isFree 也会发生改变。同理,我们在控制台通过 vm.isFree = 0 给 isFree 赋值时 radio 的选中状态也会发生改变。
实例演示
"运行案例" 可查看在线运行效果
代码解释: 上述代码,我们通过 v-model 给选择框 select 和 company 形成双向绑定,当 select 改变选项时 company 也会发生改变。同理,我们在控制台通过 vm.company = 0 给 company 赋值时 select 的选中项也会发生改变。
对于单选按钮、复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值):
但是有时我们可能想把值绑定到 Vue 实例的一个动态属性上,这时可以用 v-bind 实现,并且这个属性的值可以不是字符串。
代码解释: 上述代码中,我们通过 true-value 和 false-value 给 复选框指定来选中和非选中的值,当选中时 vm.isDelivery === 'yes' ,当没有选中时 vm.isDelivery === 'no'
代码解释: 上述代码中,我们通过 v-bind:value 给 randio 指定选中的值,当 radio 选中时 vm.pick === vm.a 。
代码解释: 上述代码中,我们通过 v-bind:value 给 option 指定 value 值,当 该 option 选中时 vm.selected 的值为 { number: 123 } 。
在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步:
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:
本小节我们介绍了 Vue 数据双向绑定 v-model 的使用,主要包括以下知识点:
‘柒’ Vue移动端项目搭建: 手把手从零开始搭建
为什么要写这篇文章?
安装lib-flexible
引入lib-flexible
安装px2rem-loader
配置px2rem-loader
项目里使用设计稿标注的px,编译或者打包后会自动转化为rem
在Vue-cli中使用lang="less"时报错: Mole build failed: TypeError: this.getOptions is not a function at Object.loader
出现这个问题的原因是less-loader版本过高,降级到5.0.0即可
main.js添加
main.js
router/index.js
src文件夹下新建http文件夹,并在文件夹内新建request.js
request.js
main.js
使用方法:
然后就可以在项目中以 this.$axios 来进行请求
static文件夹下新增config.js
使用
(1) router/index.js
给每个路由新增一个auth字段来判断是否需要登录
(2) main.js
移动端项目调式怎么可以少了这个神器.
static 文件夹下新建 vconsole.js ,
再去git上拷贝源码下来,在 index.html 里引入, vconsole 地址: 点这里
index.html
main.js
App.vue
谷歌下不支持小于12px,当字体小于12px时 会变成12px 这个时候我们设置的rem及=就没有效果了 设置text-size-adjust会解决这个问题 禁用Webkit内核浏览器的文字大小调整功能
src / components 下新建index.js
main.js
使用: 直接使用不需要import
main.js中路由的前置守卫里添加这句:
本模板框架gitee地址: https://gitee.com/apple0515/vue_h5_project
持续更新~~
‘捌’ 如何阅读Vuejs源码,学习笔记
# 下载最新的vue$ npm install vue
js 引用 vue.js
开始代码,感受vue强大的双向数据绑定
实战代码:
<divid="app"><inputv-model="newTodo"v-on:keyup.enter="addTodo"><ul><liv-for="todointodos"><span>{{todo.text}}</span><buttonv-on:click="removeTodo($index)">X</button></li></ul></div>newVue({el:'#app',data:{newTodo:'',todos:[{text:'Addsometodos'}]},methods:{addTodo:function(){vartext=this.newTodo.trim()if(text){this.todos.push({text:text})this.newTodo=''}},removeTodo:function(index){this.todos.splice(index,1)}}})Vue整个生命周期示意图:
‘玖’ 面试中的网红Vue源码解析之虚拟DOM,你知多少呢深入解读diff算法
众所周知,在前端的面试中,面试官非常爱考dom和diff算法。比如,可能会出现在以下场景
滴滴滴,面试官发来一个面试邀请。接受邀请📞
我们都知道, key 的作用在前端的面试是一道很普遍的题目,但是呢,很多时候我们都只浮于知识的表面,而没有去深挖其原理所在,这个时候我们的竞争力就在这被拉下了。所以呢,深入学习原理对于提升自身的核心竞争力是一个必不可少的过程。
在接下来的这篇文章中,我们将讲解面试中很爱考的虚拟DOM以及其背后的diff算法。 请认真阅读本文~文末有学习资源免费共享!!!
虚拟DOM是用JavaScript对象描述DOM的层次结构。DOM中的一切属性都在虚拟DOM中有对应的属性。本质上是JS 和 DOM 之间的一个映射缓存。
要点:虚拟 DOM 是 JS 对象;虚拟 DOM 是对真实 DOM 的描述。
diff发生在虚拟DOM上。diff算法是在新虚拟DOM和老虚拟DOM进行diff(精细化比对),实现最小量更新,最后反映到真正的DOM上。
我们前面知道diff算法发生在虚拟DOM上,而虚拟DOM是如何实现的呢?实际上虚拟DOM是有一个个虚拟节点组成。
h函数用来产生虚拟节点(vnode)。虚拟节点有如下的属性:
1)sel: 标签类型,例如 p、div;
2)data: 标签上的数据,例如 style、class、data-*;
3)children :子节点;
4) text: 文本内容;
5)elm:虚拟节点绑定的真实 DOM 节点;
通过h函数的嵌套,从而得到虚拟DOM树。
我们编写了一个低配版的h函数,必须传入3个参数,重载较弱。
形态1:h('div', {}, '文字')
形态2:h('div', {}, [])
形态3:h('div', {}, h())
首先定义vnode节点,实际上就是把传入的参数合成对象返回。
[图片上传失败...(image-7a9966-1624019394657)]
然后编写h函数,根据第三个参数的不同进行不同的响应。
当我们进行比较的过程中,我们采用的4种命中查找策略:
1)新前与旧前:命中则指针同时往后移动。
2)新后与旧后:命中则指针同时往前移动。
3)新后与旧前:命中则涉及节点移动,那么新后指向的节点,移到 旧后之后 。
4)新前与旧后:命中则涉及节点移动,那么新前指向的节点,移到 旧前之前 。
命中上述4种一种就不在命中判断了,如果没有命中,就需要循环来寻找,移动到旧前之前。直到while(新前<=新后&&旧前<=就后)不成立则完成。
如果是新节点先循环完毕,如果老节点中还有剩余节点(旧前和旧后指针中间的节点),说明他们是要被删除的节点。
如果是旧节点先循环完毕,说明新节点中有要插入的节点。
1.什么是Virtual DOM 和Snabbdom
2.手写底层源码h函数
3.感受Vue核心算法之diff算法
4.snabbdom之核心h函数的工作原理
1、零基础入门或者有一定基础的同学、大中院校学生
2、在职从事相关工作1-2年以及打算转行前端的朋友
3、对前端开发有兴趣人群
‘拾’ vue入门 | 使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
项目首页由顶部导航栏,左侧导航栏,中间内容区构成,如图
在app.vue引入element-ui,然后就可以在其他任何页面中使用了
将app.vue改为以下内容