*1、vue2数据绑定的原理*
vue2数据绑定是通过****数据劫持*和*观察者模式****的方式实现的
****1、数据劫持:****使用Obiect.defineProperty()
当你把一个普通的JavaScript对象 (ison)传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用Obiect.defineProperty 把这些属性全部转为 getter/setter。
****2、观察者模式(发布订阅模式) 😗***目的:当属性发生变化时,所有使用(直接使用和间接使用)该数据地方(订阅)跟着变化
vue2框架会把模板使用该数据的所有dom元素做订阅。当数据发生变化时,然后,发布给所有的订阅者
数据绑定:涵盖了:数据绑定,响应式。
*2、什么是MVVM模式*
是Model-View-ViewModel的简写
****M-*Model是数据模型(data中的数据),*V*是浏览器视图模型View,*VM****是new出来的Vue实例对象,将数据模型和视图模型进行绑定
*3、什么是指令*
和属性名差不多,是vue自定义的属性
*4、内容指令*
1、插值表达式
2、v-text:和插值表达式用法相同,语法不同
3、v-html:不能直接通过插值表达式或v-text拼接页面,因为必须保证代码都是程序员写的,防止xss攻击
*5、条件渲染v-if和v-show的区别*
相同点:都是用来控制页面dom元素的显示和隐藏的
不同点:
1、原理不同:
v-if是通过dom元素的删除和添加,来完成显示隐藏的
v-show是通过修改display属性的值,来控制显示和隐藏的
2、性能消耗不同:
v-if的性能消耗体现在切换时
v-show的性能消耗体现在第一次加载时(特别时首次显示的情况)
3、使用场景不同:
v-if用在元素不频繁切换时
v-show用在元素频繁切换时
4、安全性:
v-if的安全性好
v-show的安全性不好
*6、**什么是虚拟dom和diff算法*
vue在页面渲染时并不是直接操作dom的,因为频繁的回流和重绘操作会降低页面渲染的性能
页面在渲染的时候会产生虚拟的dom树,虚拟的dom树有oldVdom和newVdom,oldVdom永远和页面真实dom保持一致
当页面首次渲染的时候会生成一个真实的页面,并且产生一张表,就是虚拟oldVdom。根据vue规则,当data中的数据发生改变时,就会重新渲染页面。但并不会直接修改页面dom元素,而是生成一个newVdom,将oldVdom和newVdom通过key值进行diff比较,如果key一致则表明这个元素没有发生改变,如果在newVdom中产生新的元素则为增,当遍历完oldVdom时发现有多余的元素则为删
*7、**单向绑定和双向绑定的区别*
单向绑定:只能由data传递到页面-----v-bind:简写为:“:”
双向绑定:data和页面可以相互传递数据-----v-model:简写为:“v-model”
双向绑定一般用于表单元素
*8、**v-if和v-for问题*
建议不要连用,或者说,在循环时,通过if只能拿到少部分数据时,建议不要使用
*原因*:v-for比v-if优先级高,如果遍历的数组元素个数比较多,但是满足v-if条件比较少的情况下。会浪费性能。而且,每次刷新页面时,都会执行这样性能不高的代码。
*解决*:可以在computed里循环数组,通过filter的方式,过滤出需要的数据。v-for直接循环计算属性的结果(不用v-if)。而computed是有缓存的,所以,在原始数据没有变化时,不会多次过滤数据,这样,就提高了效率。
*9、class属性的三种写法及使用场景*
1、字符串写法,使用场景:类名不确定,需要动态选择
2、数组写法,使用场景:类名不确定,个数不确定
3、对象写法,使用场景:类名确定,个数确定,动态决定是否使用
*10、计算属性*
计算属性:通过计算获得的属性,一定是依赖于其他已经存在的属性
计算属性必须有return,只能用来读,用于显示数据
计算属性的变量名等于return后面的值
计算属性不要有赋值的想法,不要考虑set
计算属性的渲染时间点:
a.页面第一次渲染的时候
b.当依赖的任意一个属性发生变化是,则重新渲染vw模板
模板中多次使用计算属性时,会将数值保存在缓冲区中
*11、监听watch*
1.当被监听的属性发生改变时,自动调用回调函数 handler
2.监听的属性必须是存在的
3.当监听的属性为对象时,不能直接监听对象里的属性,只能监听对象本身
解决方案:
deep:true 深度监听
4.如果需要页面一打开就立刻执行监听的回调函数
immediate:true
监听和计算属性唯一的不同在于异步,不考虑异步问题,监听和计算属性都能实现相同的功能
计算属性不支持异步
*12、计算属性、函数(方法)、属性检测异同*
*13、自定义属性*
关键字:directives
什么是自定义属性:本质就是一种指令,自己定义的指令
钩子函数:bind:页面一打开就执行的函数,此时dom元素还没有绑定在根节点上
inserted:当dom元素插入至根节点后,页面已经渲染
update:该dom元素发生了更新,从新渲染时触发
都有统一的形参:el和binding
el:被自定义指令绑定的dom元素
*14、混入*
关键字:mixins
意义在于分发 Vue 组件(对象)中的可复用功能,混入对象就是一个json对象,json对象的属性就是 Vue对象的配置项(data,methods等等,但是没有el)
*15、组件*
什么是组件:组件是继承HTML、CSS、JS的一个文件,后缀为vue
语法:1、定义 2、注册 3、使用
注意事项:子组件只能有一个跟标签
组件没有el属性
组件必须使用函数试的data
*16、为什么组件必须使用函数式data*
一个组件的 data 选项必须是一个函数,且要有返回object(就是vue对象的data),只有这样,每个实例(vue组件对象)就可以维护一份被返回对象的独立的拷贝,否则,组件复用时,数据相互影响。即:组件的作用域(应该)是独立的。
简单回答:如果不是函数,那么,复用的组件的data共享同一块内存空间。
*17、组件的数据传递*
*正传(父传子)*
如何传:<子组件标签 key1=v1 key2=v2>
如何收:1、数组接收props-----props[‘x’,‘y’]
2、props验证:类型,是否必须,默认值
props: { x: { // 描述接收的类型 type: String }, y: { type: String, // 必须得传 required: true } }, //b.条件接收 data() { return { stuName: “老王” } }
*逆传(子传父)*
<template>
<div class="mycom2">
<button @click="fun">子传父</button>
</div>
</template>
<script>
// 注意事项: 1.子元素定义一个函数fun // 2.该函数通过$emit定义自定义事件 // 3.调用fun,触发自定义事件的传值 // (谁传谁触发) export default { methods: { fun(){ // this.$emit("自定义事件的名字","传递的参数1","传递的参数2..."); this.$emit("hello","哈哈哈哈哈"); } }, }
</script>
<style scoped> </style>
*18、* *vue的生命周期是怎么理解的?*
一、vue生命周期是什么
就是vue对象从创建,到使用,到销毁的过程。vue对象从创建,到数据挂载,模板渲染,更新,销毁的整个过程。
二、vue对象生命周期经历了四个核心阶段,同时有八个钩子函数:
*实例创建*
实例创建之前-----beforeCreate 数据的观测与事件的初始化 属性的创建 还没有进行
实例创建之后-----created 在此时vue实例已经创建完毕 所以 数据的观测 属性 方法等内容都已经创建完毕(el属性还没有挂载)
*模板渲染*
模板渲染之前-----beforeMount 在页面挂载前调用的 所以在此阶段 页面还没有进行渲染与模板的编译 程序在此时会把数据绑定到页面上 但是页面并没有显示
模板渲染之后-----mounted 页面已经渲染出来了 html的内容会在dom中进行加载展示
*数据更新*
数据更新之前-----beforeUpdate 在此时数据会不停的在dom中进行修改
数据更新之后-----updated 把修改之后的dom内容已经在页面成功的展示了
*实例销毁*
实例销毁之前-----beforeDestory 此时vue实例还能用
实例销毁之后-----destoryed 什么都没有了 vue实例等内容都没了