Vue知识点汇总

Vue知识点汇总

vue双向绑定原理vue数据双向绑定原理图

vue.js是采用了数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty来劫持各个属性的setter和getter,在数据变动的时候发布消息给订阅者,触发相应的监听回调

具体步骤:

第一步:需要observe的数据对象来进行递归遍历,包括子属性对象的属性,都加上setter和getter,这样的话,给这个对象的某个值赋值时,就会触发setter,那么就能监听到数据的变化

第二步:compile解析模板指令,将模板中的变量替换成数据 ,然后初始化渲染页面的视图,并将每个指令的对应的节点绑定的更新函数,添加监听数据的订阅者,一旦数据发生变化,就收到通知,更新视图。

第三步:watcher订阅者是observer和compile之间通讯的桥梁,主要做的事情就是1.自身实例化的时候向属性订阅器(dep)中添加自己,2.自己必须要有一个update()的方法,3.待属性变动dep.notice()通知时,能调用自身的update()方法,并触发compile中绑定的回调函数,则功成身退

第四步:MVVM作为数据绑定函数入口,整合Observer、complie和watcher三者,通过Observer来监听自己的model数据变化,通过complie来解析编译模板的指令,最终利用Watcher搭起Observer和Complie之间的通讯桥梁,达到数据变化==>视图变化,视图变化==>数据响应的变化的双向绑定效果

method watch和computed的区别

  1. methods:事件调用的钩子
  2. computed: 计算属性是根据他依赖的值计算的,当依赖值发生变化,其跟着改变,计算属性是有缓存的
    计算属性调用的时机:
    • 初次渲染的时候
    • 所依赖的值发生变化
  3. watch:
    watch 和 computed 区别:
    watch 强调的是 观测某个状态,根据状态的改变而做事情
    而computed 强调的是 根据状态返回一个新的状态 。 另外computed能实现的,watch肯定能实现,但watch能实现的,computed不一定能实现(比如说在watch里面执行一个异步操作)
    //watch里面使用异步操作,可正确返回数据
    watch:{
    		firstName(value){
    			setTimeout(()=>{
    				this.fullName = value + this.lastName
    			})
    		}
    		lastName(value){
    			setTimeout(()=>{
    				this.fullName =  this.firstName + value
    			})
    		}
    }  
    
  //computed里面使用异步操作,不可以  正确返回数据
   computed:{
   		fullName(){
   			setTimeout(()=>{
   				return this.firstName + ' - ' + this.lastName
   			})
   		}

this.$nextTick()

this.$nextTick()的使用场景

使用场景:适用于在随数据改变而改变的DOM的应用场景中,vue中数据和DOM渲染是异步的,所以,要让DOM结构随数据改变这样的操作都应该放在this.$nextTick( )中。
created()中使用方法是,DOM还没渲染,如果此时在该钩子函数中进行DOM赋值数据(或者其他的DOM操作),都是徒劳,所以,此时this.$nextTick()就会被大量使用,而与created()对应的是mounted()的钩子函数则是在dom完全渲染后才开始渲染数据,所以mounted()中操作DOM,基本上不会存在渲染的问题

this.$set()

vue中的data中的数据都是响应式的,也就是说,如果操作data中的数据,视图也会实时的更新,但实际开发中,遇到过一个坑就是:若data中,数据类型较为复杂,方法methods中改变对象的属性,视图也就是页面并不会改变。
原因是vue监听不到数据类型特别复杂的属性,这个时候就可以用this.$set()来进行强制更新,进而解决问题

Vue.use(plugin)

参数 :{object | Function} plugin

用法: 安装Vue.js插件。如果插件是一个对象,必须提供install方法。如果插件是一个函数,它会被作为install方法。install 方法调用是,会将Vue 作为参数传入。
该方法需要在调用new Vue() 之前被调用,当 install方法被同一个插件多次调用,插件将只会被安装一次

Vue.use ()什么时候使用?

​ 它在使用时实际是调用该插件的install方法,所以引入的当前插件如果含有install 方法,我们就是需要使用Vue.use( ),例如在vue中引入Element

import Vue from 'vue'
import Element from 'element-ui'
vue.use(ELement)

Vue父子组件生命周期执行顺序

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

vue优化方案

Object.freeze() 冻结一个对象。一个被冻结的对象再也不能被修改;
​ vue请求的数据中存在不会被修改的数据,只是作为展示,未避免vue给这些数据添加get和set方法,影响性能,可以使用Object.freeze()这个方法!!!!

Vue 生命周期

vue生命周期就是指vue实例从创建到销毁的整个过程。既是指从创建、初始化数据、编译模板、挂载DOM到渲染页面,更新渲染、和销毁这些过程。它主要分为8个阶段,创建前后,载入前后,更新前后、和卸载前后。另外还有两个特殊的路由组件钩子函数:activedh和deactived(是配合keep-alive使用的,如果没有keep-alive是不会触发这两个钩子,actived相当与created ,deactived相当于destory)
真实开发的时候,我们会在created 中发送给ajax请求,在created之前我们是没有办法使用this的,mounted 之前是无法获取DOM元素的

keep-alive 组件缓存

vue 内置组件,能在组件切换的过程中奖状态保留在内存中,防止重复渲染DOM

路由文件:

exprot defalult new Router({
    routes:[
        {
            path:'/',
            name:'index',
            component:index
        },
        {
            path:"/A",
            name:"A",
            component:B
        },
        {
            path:"/B",
            name:'B',
            component:B
        },
         {
            path:"/C",
            name:'C',
            component:C,
             meta:{
                 keepAlive:false
             }
        },
        {
            path:"/D",
            name:'D',
            component:D,
             meta:{
                 keepAlive:true
             }
        }
    ]
})
  • 利用include、exclude属性:(注意是组件的名字,不是路由的名字)

    include属性表示只有name属性为A,B的组件会被缓存,其它组件不会被缓存

    exclude属性表示除了name属性为C的组件不会被缓存,其它组件都会被缓存

<template>
  <div id="app">
    <!-- 表示只有name属性为A,B的组件会被缓存,其它组件不会被缓存 -->
    <keep-alive include="A,B">
      <router-view></router-view>
    </keep-alive>
    <!-- //除了name属性为C的组件不会被缓存,其它组件都会被缓存 -->
    <keep-alive exclude="C">
      <router-view></router-view>
    </keep-alive>
  </div>
</template>
  • 利用meta属性
<template>
  <div id="app">
    <!--这里是会被缓存的组件-->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <!--这里是会被缓存的组件-->
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

vue — 插槽

默认插槽

插槽里面可以又默认值,父组件传递值的时候,会覆盖子组件插槽里面的值,不传,就使用默认的值

父组件:

<template>
	<div>
        <h1>{{msg}}</h1>
        <children>
    		<h3>我是子组件里面的传递的插槽</h3>
    	</children>
    </div>
</template>

<script>
	import children from './children'
    export default {
        name:'index',
        data(){
            return {
                msg:'vue 插槽slot - 父组件'
            }
         components:{children}
        }
    }
</script>

子组件:

<template>
	<div>
        <h1>{{msg}}</h1>
        <slot>我是插槽里面的默认值</slot>
    </div>
</template>

<script>
export default{
    name:'children',
    data(){
        return {
            msg:'我是子组件'
        }
    }
}
</script>

具名插槽

有名字的插槽,可以将v-slot简写为#

父组件:

<template>
	<div>
        <h1>{{msg}}</h1>
        <children>
    		<template v-slot:top>
                <p>插槽name为top的插槽 </p>
			</template>
			<template v-slot:center>
				<p>插槽name为center的插槽 </p>
			</template>
			<template v-slot:bottom>
				<p>插槽name为bottom的插槽 </p>
			</template>
    	</children>
    </div>
</template>

<script>
	import children from './children'
    export default {
        name:'index',
        data(){
            return {
                msg:'vue 插槽slot - 父组件'
            }
         components:{children}
        }
    }
</script>

简写:

<template>
	<div>
        <h1>{{msg}}</h1>
        <children>
    		<template #top>
                <p>插槽name为top的插槽 </p>
			</template>
			<template #center>
				<p>插槽name为center的插槽 </p>
			</template>
			<template #bottom>
				<p>插槽name为bottom的插槽 </p>
			</template>
    	</children>
    </div>
</template>

<script>
	import children from './children'
    export default {
        name:'index',
        data(){
            return {
                msg:'vue 插槽slot - 父组件'
            }
         components:{children}
        }
    }
</script>

子组件:

<template>
	<div>
        <h1>{{msg}}</h1>
        <slot name='top'></slot>
        <slot name='center'></slot>
        <slot name='bottom'></slot>
    </div>
</template>

<script>
export default{
    name:'children',
    data(){
        return {
            msg:'我是子组件'
        }
    }
}
</script>

作用域插槽

父组件在子组件的插槽里面用子组件的数据

父组件:

<template>
	<div>
        <h1>{{msg}}</h1>
        <children>
    		<template v-slot:age='perspmProps'>
                <p>{{perspmProps.person.age}} </p>
			</template>
			<template v-slot:name='perspmProps'>
				<p>{{perspmProps.person.name}} </p>
			</template>
			
    	</children>
    </div>
</template>

<script>
	import children from './children'
    export default {
        name:'index',
        data(){
            return {
                msg:'vue 插槽slot - 父组件'
            }
         components:{children}
        }
    }
</script>

子组件:

<template>
	<div>
        <h1>{{msg}}</h1>
        <slot v-bind:str='person' name='age'>
             {{person.age}}
   		</slot>
        <slot v-bind:str='person' name='name'>
            {{person.name}}
    	</slot>
    </div>
</template>

<script>
export default{
    name:'children',
    data(){
        return {
            msg:'我是子组件'
            person:{
            	age:12,
            	name:'wy'
        	}
        }
    }
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值