计算属性
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了0bjcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
代码样例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="../js/vue.js"></script>
</head>
<body><div id="root">性:<input type="text" v-model="name1"><br/><br/>名:<input type="text" v-model="name2"><br/><br/>全名<span>{{fullName}} </span></div><script type="text/javascript">//Vue.config,Vue.config.productionTip = false//阻止 vue 在启动时生成生产提示。//创建vue实例const x = new Vue({el:'#root',//e1用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。data: {//data中用于存储数据,数据供e1所指定的容器去使用,值我们暂时先写成一个对象。name1:"张",name2:"三"},computed:{fullName:{get(){console.log('get');return this.name1+'-'+this.name2},set(value){console.log('set',value);const arr=value.split('-');this.name1=arr[0];this.name2=arr[1];}}}})</script>
</body>
</html>
只考虑读取不考虑修改可以简写成如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="../js/vue.js"></script>
</head>
<body><div id="root">性:<input type="text" v-model="name1"><br/><br/>名:<input type="text" v-model="name2"><br/><br/>全名<span>{{fullName}} </span></div><script type="text/javascript">//Vue.config,Vue.config.productionTip = false//阻止 vue 在启动时生成生产提示。//创建vue实例const x = new Vue({el:'#root',//e1用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。data: {//data中用于存储数据,数据供e1所指定的容器去使用,值我们暂时先写成一个对象。name1:"张",name2:"三"},computed:{fullName(){console.log('get');return this.name1+'-'+this.name2}}})</script>
</body>
</html>
监视属性watch
1.当被监视的属性变化时,回调函数自动调用,进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="../js/vue.js"></script></head>
<body><div id="root"><h1>今天天气{{tq}}</h1><button @click="isHot=!isHot">切换天气</button></div><script type="text/javascript">//Vue.config,Vue.config.productionTip = false//阻止 vue 在启动时生成生产提示。//创建vue实例const vm = new Vue({el:'#root',data: {isHot: true},computed:{tq(){if(this.isHot){return '炎热'}else{return '凉爽'}}},watch: {isHot:{handler(newValue,oldValue){console.log(newValue,oldValue);}}}})</script>
</body></html>
(2).通过vm.$watch监视
vm.$watch('isHot',{//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}
})
深度监视
(1).Vue中的watch默认不监测对象内部值的改变(一层)
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
computed和watch之间的区别
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2,所有不被vue所管理的函数(定时器的回调函数、aiax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm或组件实例对象。
绑定样式
1.class样式
写法:class="xxx”xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2.style样式
:style="{fontSize:xxx}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象。
条件渲染
1.v-if
写法:
(1).v-if="表达式”
(2).v-else-if="表达式"
(3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”
2.v-show
写法:v-show="表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
v-for指令
1.用于展示列表数据
2.语法:v-for="(item, index)in xxx" :key="yyy"
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
面试题:vue中的key有什么作用?(key的内部原理)
1.虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
@.若虚拟DOM中内容没变,直接使用之前的真实DOM!
@.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM.
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。
3.用index作为key可能会引发的问题:
1.若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新==>界面效果没问题,但效率低
2.如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==>界面有问题。
4.开发中如何选择key?:
1.最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示
使用index作为key是没有问题的。