计算属性 - computed
定义:要用的属性不存在,要通过已有的属性计算得来的
原理:底层借助了Object.defineproperty方法提供的getter和setter
如下案例:通过以下的姓和名,计算得到全名
方法一:可以直接使用 methods 函数的返回式实现其功能
<body> <div id="root"> 姓:<input type="text" v-model="firstName"><br /><br /> 名:<input type="text" v-model="lastName"><br /><br /> 全名:<span>{{fullname()}}</span> </div> </body> <script> Vue.config.productionTip = false new Vue({ el: '#root', data: { firstName: '张', lastName: '三' }, methods: { fullname() { //this此时指向的是Vue实例 //当vue里面的数据一旦发生变化,模版会重新调用一下 return this.firstName +'-'+ this.lastName } } }) </script>
方法二: 利用计算属性 computed ,实现
注意简写的时候,是只读属性,不能修改,也就是说不能实现setter功能
<body> <div id="root"> 姓:<input type="text" v-model="firstName"><br /><br /> 名:<input type="text" v-model="lastName"><br /><br /> 全名:<span>{{fullname}}</span><br /><br /> </div> </body> <script> Vue.config.productionTip = false new Vue({ el: '#root', data: { firstName: '张', lastName: '三' }, computed: { //完整代码 // fullname: { // // get有什么作用?当有人读取fullastName时,get就会被调用,且返回值就作为fullastName的值 // //get什么时候调用?当初次读取fullname时,2】所依赖的数据发生变换时 // get() { // console.log(this); // return this.firstName + '-' + this.lastName // }, // //set什么时候调用?当fullname被修改时 // set(value) { // console.log('set', value) // const arr = value.split('-') // this.firstName = arr[0] // this.lastName = arr[1] // } // }, //只读属性,简写方式 fullname() { console.log(this); return this.firstName + '-' + this.lastName } } }) </script>
对于两种方法:
以上方法可以通过已有属性,得到全名,直接用函数的方法和计算属性的方法区别:
- 函数------- 当data里面的数据发生变化的时候,fullname()会调用,如果当输入的内容一样的时候,同样也会调用fullname()函数,每一次都要执行的话,效率很低
- 计算属性---------计算属性内部是有缓存机制的:就是将计算出来的属性,缓存起来,当下一次计算的时候,如果缓存里面有该值,就直接拿来使用,就不用每次都来计算一边,大大的提高了效率,调试更方便
如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变
监视属性 - watch
通过下面的实例来看看什么是监视属性
<div id="root"> <h1>今天天气{{info}}</h1> <button @click='changeWheate'>切换天气</button> </div> <script> Vue.config.productionTip = false const vm = new Vue({ el: '#root', data: { isHot: true }, //计算属性 computed: { info() { return this.isHot ? '很炎热' : '凉爽' } }, //事件函数 methods: { changeWheate() { this.isHot = !this.isHot } }, //监视属性写法一 watch: { isHot: { immediate: true,//初始化时让hander调用一次 handler(newValue, oldValue) { console.log('被修改了', newValue, oldValue); } } }, }) //监视属性写法二 vm.$watch('isHot', { immediate: true,//初始化时让hander调用一次 handler(newValue, oldValue) { console.log('被修改了', newValue, oldValue); } }) </script>
当监视属性isHot发生变化了,就会触发handler函数,执行里面的语句
我们知道Vue自身可以监视对象内部置的改变,但Vue提供的watch默认是不可以的
但是没关系:可以通过一种方法让watch能够深度监视
t通过添加deep:true可以让watch实现深度监视
const vm = new Vue({ el: '#root', data: { isHot: true, numbers: { a: 1, b: 1 } }, watch: { numbers:{ immediate: true,//初始化时让hander调用一次 deep:true,//深度监视 handler(){ console.log("numbers改变了"); } } } })
总结:
- 当监视的属性变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视
监视的两种写法:
- new Vue 时传入watch配置
- vm.$watch监视
immediate:true ----------表示初始化时让hander调用一次,默认值是false
deep:true ----------表示深度监视 可以监视对象内部值改变-多层
handler函数,写到监视属性的里面
computed和watch的区别
区别:
- computed能完成的功能,watch都可以完成
- watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
两个重要的小原则:
- 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象
- 所有不被Vue管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数)、filter、最好写成箭头函数,这样this的指向才是vm或组件实例对象
比如定时器的函数里面写普通函数的话,this指向的就是window