【Vue2】computed和watch

83 阅读1分钟

计算属性 computed

计算属性

new Vue({
    data...
	computed:{
        计算属性: {		// 对象形式
            get(){	//getter
				return ...
            } set(value){	// setter
				
            } 	
        }
    }
})

确定不需要写setter 的时候,可以简写↓

new Vue({
    data...
	computed:{	
    	计算属性(){//函数形式 	这个就相当于getter
			return 	...			// 必须写return
		}
    }
})

计算属性(){ 这里面不能开启异步任务 如setTimeout定时器 }

例:

<div>
        {{fullname}}
    </div>

<script>
    Vue.config.productionTip = false

    const vm =  new Vue({
        el:'div',
        data() {
            return {
                firstname:'张',
                lastname:'三'
            }
        },
        computed: {
            fullname: {
                get() {
                    return this.firstname+this.lastname
                },
                set(value) {
                    console.log('调用了计算属性的setter,value为:', value);
                    this.firstname = value.substring(0,1)
                    this.lastname = value.substring(1)
                }
            }
        }
    })
</script>

初始状态: 在这里插入图片描述 修改firstname,fullname也会变: 在这里插入图片描述 修改fullname,自动调用setter : 在这里插入图片描述

监视属性 watch

const vm = new Vue({
    data...
	watch:{		// Vue的watch默认不监视 对象 内部值的改变(默认只看一层)
        监视的变量(也可以是对象中的变量'obj.a'要加单引号):{
    		// deep:true	// 监视多级结构(如对象)中任意属性的变化,不写则是监视一整个对象的变化。单个变量不用deep:true
    		immediate:true 	// 打开页面时立即执行一次handler 默认false
        	handler(newValue,oldValue){	// 只写一个参数默认是newValue
        		
        	}
        }
    }
})

不需要配置deep、immediate 等时,可以简写为↓

const vm = new Vue({
	watch:{
		监视的东西(newValue,oldValue){
			...
		}
	}
})
// 或写在Vue({})外面的写法
    vm.$watch('监视的东西',function(newValue,oldValue){...})	// 这里不能写成箭头函数

例:

    <div>
        <input type="text" v-model="keyword">
        <ul v-for="item in filpersons" :key="item.id">
            <li>{{item.name}}  {{item.age}}  {{item.sex}}</li>
        </ul>
    </div>

    <script type="text/javascript">
            Vue.config.productionTip = false
        const vm = new Vue({
            el: 'div',
            data: {
                keyword:'',
                persons: [
                    { id: '001', name: '马冬梅', age: 18, sex: '女' },
                    { id: '002', name: '周冬雨', age: 19, sex: '女' },
                    { id: '003', name: '周杰伦', age: 21, sex: '男' },
                    { id: '004', name: '温伦', age: 22, sex: '男' }
                ],
                filpersons: []
            },
            watch: {
                keyword: {      // 监视输入框的v-model="keyword"
                    immediate: true,    // 默认先执行一次handler
                    handler(val) {      // val一开始是空的字符串'' 所以persons全部都能查出来
                        this.filpersons = this.persons.filter((p)=>{    // p 是persons里面每一个对象
                            return  p.name.indexOf(val) !== -1  // 返回-1表示查不到val值,val值是输入框获取的keyword
                        })
                    }
                }
            }
            /*
            如果是computed 则可以这样写
            computed:{
            	filpersons(){
            		return this.persons.filter((p)=>{
            			return p.name.indexOf(this.keyword) !== -1
            		})
            	}
            }
            */
        })
    </script>

在这里插入图片描述


下面用computed方式,添加三个按钮 按年龄升序降序原顺序排序↓

    <div>
        <input type="text" v-model="keyword">
        <ul v-for="item in filpersons" :key="item.id">
            <li>{{item.name}}  {{item.age}}  {{item.sex}}</li>
        </ul>
        <button @click = "sortType=1">按升序排序</button>
        <button @click = "sortType=2">按降序排序</button>
        <button @click = "sortType=0">恢复原顺序</button>
    </div>

    <script>
        Vue.config.productionTip = false

    new Vue({
        el:'div',
        data:{
            keyword:'',
            persons: [
                { id: '001', name: '马冬梅', age: 18, sex: '女' },
                { id: '002', name: '周冬雨', age: 21, sex: '女' },
                { id: '003', name: '周杰伦', age: 19, sex: '男' },
                { id: '004', name: '温兆伦', age: 22, sex: '男' }
            ],
            sortType: 0
        },
        computed:{
            filpersons(){
                const arr =  this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyword) !== -1
                })
                if(this.sortType){
                    arr.sort((p1,p2)=> {
                        console.log(this.sortType);
                        return this.sortType === 1 ? p1.age-p2.age : p2.age-p1.age
                    })
                }
               return arr
            }
        }
    })
    </script>

在这里插入图片描述 模糊查询: 在这里插入图片描述


Tip:Vue中用到定时器都要用箭头函数,如果用普通函数,this指向的是window,则不能用this.来调用Vue中data中的东西