11.vue 虚拟DOM的理解
Web界面由DOM树(树的意思是数据结构)来构建,当其中一部分发生变化时,其实就是对应某个DOM节点发生了变化,
虚拟DOM就是为了解决浏览器性能问题而被设计出来的。如前,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量。所以,用JS对象模拟DOM节点的好处是,页面的更新可以先全部反映在JS对象(虚拟DOM)上,操作内存中的JS对象的速度显然要更快,等更新完成后,再将最终的JS对象映射成真实的DOM,交由浏览器去绘制。
采用了新旧DOM的对比,获取差异的DOM,最后一次性的更新到真实DOM上。
12.动态组件
有时候在不同组件之间进行动态切换是非常有用的,比如在一个多标签的界面里,可以将多个子组件都挂载在同一个位置,通过变量来切换组件,实现tab菜单这样的效果。
可以通过Vue的<component></component>元素加一个特殊的is特性来实现
在示例中,currentTabComponent 可以包括
已注册组件的名字,或
一个组件的选项对象
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>
13.vue的kepp-alive
是vue的一个内置组件,可以使被包含的组件保留状态,避免重新渲染。
包含动态组件是,会缓存不活动的组件实例,而不是销毁他们,
keep-alive是一个抽象组件,它自身不会渲染一个DOM元素,也不会出现在父组件链中,
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
include:字符串或正则表达式,只有名称匹配的组件会被缓存
exclude:字符串或正则表达式,名称匹配的不会被缓存
max:数字,最多可缓存多少实例
1)搭配动态组件使用
将会缓存is成立时匹配到的zu'jian
<kepp-alive>
<component v-bind:is="currentTabComponent"></component>
</kepp-alive>
2)include
将会缓存name名为a、b的组件
<kepp-alive include="a, b">
<component v-bind:is="currentTabComponent"></component>
</kepp-alive>
3)exclude
将会缓存name名为**非**a、b的组件
<kepp-alive exclude="a, b">
<component v-bind:is="currentTabComponent"></component>
</kepp-alive>
4)使用$route.meta的keepAlive属性
将会缓存满足if条件的组件
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
14.watch和计算属性
计算属性:
*用于简单场合,比如计算,合并字符串等;
*计算属性会依赖于他使用的data中的属性,只要是依赖的属性值有改变,则自动重新调用一下计算属性;
*如果他所依赖的这些属性值没有发生改变,那么计算属性的值是从缓存中来的,而不是重新编译,那么性能要高一些,所以vue中尽可能使用computed替代watch。
1)计算属性基于依赖进行缓存。
watch属性:
*用于耗时的,可以异步的获取远程服务上的数据这样的操作。
1)对基本属性进行监听 watch: { str: function (newValue, oldValue) {} }
2)对对象进行监听watch: {obj: {handle: (){}, deep: true}
3)对对象某一个属性监听 watch : { 'obj.prop': {} }
4)route监听watch: { '$route': function(){} }
15.自定义指令
全局指令:Vue.directive()
Vue.directive('foucs',{
inserted(el){
}
}),
第一个参数foucs是指令名,第二个参数是一个对象,对象内部有个inserted的函数,函数里有el这个参数,el表示绑定了这个指令的dom元素。
Vue.directive('gqs',{
bind() {
// 当指令绑定到 HTML 元素上时触发.**只调用一次**
console.log('bind triggerd')
},
inserted() {
// 当绑定了指令的这个HTML元素插入到父元素上时触发(在这里父元素是 `div#app`)**.但不保证,父元素已经插入了 DOM 文档.**
console.log('inserted triggerd')
},
updated() {
// 所在组件的`VNode`更新时调用.
console.log('updated triggerd')
},
componentUpdated() {
// 指令所在组件的 VNode 及其子 VNode 全部更新后调用。
console.log('componentUpdated triggerd')
},
unbind() {
// 只调用一次,指令与元素解绑时调用.
console.log('unbind triggerd')
}
})
16.组件之间的通信
1)父组件-->子组件
父向子传递数据通过props,通过设置标签的属性传递数据,在子组件用props接受。
**父组件代码**
<template>
<header-box :title-txt="showTitleTxt"></header-box> //在子组件上v-bind:title-text绑定一个showTitleTxt
</template>
<script>
import Header from './header'
export default {
name: 'index',
components: {
'header-box': Header
},
data () {
return {
showTitleTxt: '首页'
}
}
}
</script>
**子组件代码**
<template>
<header>
{{thisTitleTxt}}
</header>
</template>
<script>
export default {
name: 'header-box',
props: {
titleTxt: String //接受的数据类型
},
data () {
return {
thisTitleTxt: this.titleTxt
}
}
}
</script>
2)子组件-->父组件
**在子组件中创建一个按钮,给按钮绑定一个点击事件,在该事件的的函数中使用$emit来触发一个自定义事件,并传递一个参数。
<button v-on:click="sendMsg"></button>
methods:{
sendMsg:function(){
this.$emit("listenToChild","传递的数据");
}
}
**在父组件引入子组件的标签内监听该自定义事件,并添加一个处理该事件的方法。
<child v-on:listenToChild="showMsg"></child>
methods:{
showMsg:function(msg){
console.log(msg);//传递来的数据
}
}
3)非父子组件通信(中央事件总线eventBus)
全局注册,在main.js
let EventBus = new Vue();
Vue.prototype.bus=bus;
局部使用
新建EventBus.js
import Vue from 'vue'
export const EventBus = new Vue()
在需要的组件中引用
import EventBus from "../EventBus.js";
注册之后,在firstChild组件中,import引入js,接着在firstChild组件添加按钮并绑定一个点击事件
<button v-on:click="sendMsg"></button>
methods:{
sendMsg:function(){
EventBus.$emit("userEvent","转递的数据")
}
}
在secondChild组件中,引入时间总线
mounted(){
EventBus.$on("userEvent",function(msg){
console.log(msg);//传递过来的数据
});
}
17.过滤器
18.vue-loader的作用
太深入的还没用到,只是简单的了解过。
vue-loader:解析和转换.vue文件,提取出其中的逻辑代码,script、style、template,再分别把他们交给对应的loader去处理。
css-loader:加载由vue-loader提取出来的style代码。
vue-template-compiler:把vue-loader提取出来的HTML模板编译成对应的可执行的script代码。
vue-loader的作用就是提取。
19.vue组件中data为什么必须是函数?
在nue Vue()中data是可以作为一个对象进行操作的,然而在component中,data只能用函数的方式存在,不能直接让对象赋值给他。
当data是一个函数时,每个实例可以维护一份被返回对象的独立的拷贝,这样各个实例中的data就不会相互影响,是独立的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。