1.引入vue(练习使用,没有使用cli脚手架创建环境)
<script src="js/vue.js"></script>
2.底层实现原理
vue拦截原理:在object.defindPropety拦截 里面当你调用了一个对象的值会被get监听到,修改一对象值,会被set所监听到
每次数据更改都有一个setter拦截通知watcher进行触发和更新,watcher观察者收集了很多相关的依赖和发布者和订阅者,触发订阅者进行一个调用
3.动态绑定:
<div :class="whichcolor">切换背景色</div>
动态绑定动作:
<button @click="handleChagne()">change</button>
4.v-show和v-if 指令
v-show:<div v-show="isShow">我是动态隐藏</div>
只要这个isshow为真就显示
v-show 显示和隐藏和v-if 创建和删除区别
用法都类似
但是v-show创建就是直接创建,只不过是存在display:none;而v-if还没创建
所以v-if比v-show更懒惰
5。v-for遍历
v-bind:src 动态绑定属性 简写:src
v_on:click 动态绑定 简写@click
6.v-model双向绑定
实现原理:v-model本质上是 :value和v-on的结合体,就是绑定他的value,通过v-on触发,从而更新数据
双向绑定得的实现主要依赖于Object.defineProperty(),通过这个函数可以监听到get,set事件
7. v-show和v-if区别
1.展示形式不同
v-show是display:none、blcok
v-if:创建新的dom节点
2.使用场景不同
1.v-show:适合频繁切换的;v-if的话会开销太大
2.首次加载:v-if会比v-show好 因为如果没有触发v-show的条件,v-show的盒子就会白加载了。
v-if和v-for优先级
v-for的优先级要比v-if高 因为Vue.js源码文件体现的’
8.ref:
来获取dom节点元素。
9.观察则模式和订阅发布者模式
观察者模式:
简单来说,观察者模式就是,一个对象(被观察者)的状态发生改变时,会通知所有依赖它的对象(观察者),这两者是直接关联的。
举个例子:
我们去餐厅吃饭的时候,经常会遇到需要排队的时候。我们可以把餐厅看作时被观察者,把排队的客人(拿号排队)看作是观察者。当餐厅有位置的时候,餐厅会出来通知排队的客人,到100号桌吃饭啦。这时排队的客人们都会看看自己手上的号,确定是否到自己吃饭了。
const Subject = (() => {
const observers = [];
const addOb = (ob) => {
observers.push(ob);
};
const notify = () => {
for (let ob of observers) {
if (typeof ob.update === 'function') {
ob.update();
}
}
};
return {addOb, notify};
})();
let subA = {
update: () => {
console.log('updateSubA');
}
},
subB = {
update: () => {
console.log('updateSubB');
}
};
Subject.addOb(subA); //添加观察者subA
Subject.addOb(subB); //添加观察者subB
Subject.notify(); //通知所有观察者
订阅发布模式
发布者状态更新时,发布某些类型的通知,只通知订阅了相关类型的订阅者。发布者和订阅者之间是没有直接关联的。
举个例子:
还是以餐厅排队吃饭为例。这次我们拿了号后,不再傻傻地在餐厅门口等待。我们扫了一下排队二维码,我们在排队的过程中就可以去干其他事情了,因为到我们的号时,餐厅会发送一个通知给我们。
const PubSub = (() => {
const topics = {}; //保存订阅主题
const subscribe = (type, fn) => { //订阅某类型主题
if (!topics[type]) {
topics[type] = [];
}
topics[type].push(fn);
};
const publish = (type, ...args) => { //发布某类型主题
if (!topics[type]) {
return;
}
for (let fn of topics[type]) { //通知相关主题订阅者
fn(args);
}
};
return {subscribe, publish};
})();
let subA = {type: 'event1'},
subB = {type: 'event2'},
subC = {type: 'event1'};
PubSub.subscribe(subA.type, () => console.log(`update eventType: ${subA.type} subA`)); //订阅者A订阅topic1
PubSub.subscribe(subB.type, () => console.log(`update eventType: ${subB.type} subB`)); //订阅者B订阅topic2
PubSub.subscribe(subC.type, () => console.log(`update eventType: ${subC.type} subC`)); //订阅者C订阅topic1
PubSub.publish(subA.type); //发布topic通知,通知订阅者A、C
总结:
观察者模式中,被观察者(可理解为发布者)与观察者(可理解为订阅者),这两者之间是直接关联、互相依赖的。而发布-订阅模式中,发布者与订阅者是不直接关联的,它们之间多了一个事件通道,通过这个事件通道把发布者和订阅者关联起来。观察者模式中,被观察者发布通知,所有观察者都会收到通知。发布-订阅模式中,发布者发布通知,只有特定类型的订阅者会收到通知。观察者模式中,被观察者发出状态更新通知后,观察者调用自身内部的更新方法。发布-订阅模式中,订阅者的更新是通过事件通道进行细节处理和响应更新的。
10.动态组件:
让多个组件使用同一个挂载点,并动态进行切换。这就是动态组件通过保留元素,动态的绑定它的 is 特性,可以实现动态组件
11.keep-alive:
keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 transition 相似,keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中
作用:在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性
当使用了 keep-alive 内置组件后组件会增加两个生命周期函数:
(1)activated:当组件为活跃状态的时候触发(活跃状态:进入页面的时候)
(2)deactivated:缓存状态的时候触发
12.slot插槽:
官方定义:
Vue 实现了一套内容分发的 API,将 <slot> 元素作为承载分发内容的出口;
插槽实质是对子组件的扩展,通过<slot>插槽向子组件内部指定位置传递内容;<slot> 的出现是为了父组件可以堂而皇之地在子组件中加入内容
13.指令
1.自定义指令---directives
对普通的dom元素进行底层的操作 复用性
14.diff算法:
虚拟dom:
虚拟dom就是一个普通的js对象。是一个用来描述真实dom结构的js对象,因为他不是真实dom,所以才叫虚拟dom。
虚拟dom作用:
虚拟dom可以很好的跟踪当前dom状态,因为他会根据当前数据生成一个描述当前dom结构的虚拟dom,然后数据发送变化时,又会生成一个新的虚拟dom,而这两个虚拟dom恰恰保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验
而这个算法就是diff算法
diff算法就是用于比较新旧两个虚拟dom之间差异的一种算法
diff 比较规则
diff 比较两个虚拟dom只会在同层级之间进行比较,不会跨层级进行比较。而用来判断是否是同层级的标准就是
是否在同一层;
是否有相同的父级;
比较两个节点是否是相同节点,判断是否是相同节点的条件是,key和sel(选择器)必须都相同(那有的人可能会说了,那我标签没有key怎么办啊,没有key那就是undefined,undefined === undefined 始终为true,所以没有key只需要保证sel相同就行)。如果不相同,那么执行替换操作(即新增新虚拟dom上的元素,删除旧虚拟dom上的元素
15.&nextTick:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码;
理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,
用处:
当项目中你想在改变DOM元素的数据后基于新的dom做点什么,对新DOM一系列的js操作都需要放进Vue.nextTick()的回调函数中;通俗的理解是:更改数据后当你想立即使用js操作新的视图的时候需要使用它