vue基础(三):computed&watch&methods对比及案例

86 阅读2分钟
computed计算属性 案例 conputed:{ fullName :{ get() set()} }
  • 插值语法实现 复杂计算不适合写在{{}}里面
  • computed计算属性实现(要用的属性不存在,要通过已有属性计算得来)
复杂 所以要写成一个对象
理解:
1.computed里写了个对象,但是vm身上并不是fullName.get() data中写啥vm身上是啥 method写啥vm身上是啥
2.fullName往vm身上放的时候自动去找到get并调用拿到get返回值并放到vm身上,名字叫做fullName
get函数啥时候执行
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
优势:与methods相比,内部有缓存机制,效率高,方便调试
1.计算属性最终会出现在vm身上,直接读取使用
2.如果计算属性要被修改,必须写set函数去响应修改,且set中要引起计算时以来的数据发生改变(first last3.底层借助了Objcet.defineproperty方法提供的getter和setter
/* 当对象的属性是一个函数就是简写形式 */
computed: {
    filterPerson() {
        // 只调用了get() 简写的形式
        // 返回数组
        return this.persons.filter((item) => {
            return item.name.indexOf(this.keyWord) !== -1;
        })
    }
}
 <div id="demo">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <span>{{fullName}}</span>
</div>
<script type='text/javascript'>
    //阻止vue在启动时生成生产提示
    Vue.config.productionTip = false
    //创建Vue实例
    const vue = new Vue({
        el: '#demo',    
        data: {
            firstName: '肖',
            lastName: '战'
        },
        computed: {
            fullName: {
                //get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
                //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
                get() {
                    console.log('get被调用了')
                    // console.log(this) //此处的this是vm
                    return this.firstName + this.lastName
                },
                //set什么时候调用? 当fullName被修改时。vue.fullName = '新名字'
                set(value) {
                    console.log('set', value);//去控制台给一个 vue.fullName = '李-四'
                    const arr = value.split('-')
                    this.firstName = arr[0]
                    this.lastName = arr[1]
                }
            }
        }
    })
    console.log(vue)
</script>
watch监视属性 案例 watch: {isHot:{}}
对一个数据进行检测,对比,写一个什么逻辑
immediate:true, //初始化时让handler调用一下
deep:true; // 深度监听 监听多级结构里所有属性的变化 
hanler(){} //handler什么时候调用?当isHot发生改变时。
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
    (1)new Vue时传入watch配置
    (2)通过vm.$watch监视
watch里面的对象其实是key value 简写去掉引号 应该是'isHot':{}
深度监视:
    (1).Vue中的watch默认不监测对象内部值的改变(一层)。
    (2).配置deep:true可以监测对象内部值改变(多层)。
备注:
    (1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
    (2).使用watch时根据数据的具体结构,决定是否采用深度监视。
<!-- 准备好一个容器 -->
<div id="demo">
    今天天气很{{weather}}
    <button @click="changeWeather">切换天气</button>
</div>
<script type='text/javascript'>
    //阻止vue在启动时生成生产提示
    Vue.config.productionTip = false
    //创建Vue实例
    const vm = new Vue({
        el: '#demo',
        data: {
            isHot: true
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot;
            }
        },
        computed: {
            weather() {
                return this.isHot ? '炎热' : '凉爽'
            }
        },
        watch: {
            isHot: {
                immediate: true, //默认触发
                handler(newValue, oldValue) {
                    console.log(newValue, oldValue)
                }
            }
        }
    })
    // 用vm来监视
    vm.$watch('isHot', {
        immediate: true, //默认触发
        handler(newValue, oldValue) {
            console.log(newValue, oldValue, '$watch来监视')
        }
    });
    //简写
    /* vm.$watch('isHot',function (newValue,oldValue) {
    	console.log('isHot被修改了',newValue,oldValue,this); // 不能写成箭头函数 否则会改变this指向去window
    }) */
</script>
watch深度监听 deep:true 属性
 <!-- 准备好一个容器 -->
 <div id="demo">
     {{number.a}} {{number.b}}
     <button @click="number.a++">点击+1</button>
     <button @click="number.b--">点击-1</button>
 </div>
 <script type='text/javascript'>
     //阻止vue在启动时生成生产提示
     Vue.config.productionTip = false
     //创建Vue实例
     const vm = new Vue({
         el: '#demo',
         data: {
             number: {
                 a: 1,
                 b: -1
             }
         },
         // watch: {
         //     number: {
         //         immediate:true, // 立即执行一次
         //         deep: true, // 每个属性改变的时候都监听
         //         handler(newValue, oldValue) {
         //             console.log(newValue, oldValue, this)
         //         }
         //     }
         // }
     })
     // 另一种写法
     vm.$watch('number', {
         deep:true,
         handler(newValue, oldValue) {
             console.log(newValue, oldValue, this)
         }
     })
 </script>
watch跟computed对比 (姓名案例,含watch的三个点以及简写)
  • computed 的属性可以不存在data
  • watch 要监视的属性需要存在data
  • computed能完成的功能,watch都可以完成。
  • watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作 (延迟逻辑操作 在watch里面写一个setTimeout)
<!-- 需求:获取全名 并 等1s钟再实现 -->
<div id="demo">
    computed计算属性去计算一个不存在的属性 <br><input type="text" v-model="firstName"><input type="text" v-model="lastName">
    全名 <input type="text" v-model="fullName">
    <hr>
    watch监听一个已经存在的属性,并且延迟1s再显示 <br>
    全名<input type="text" v-model="watchName">
</div>
<script type='text/javascript'>
    //阻止vue在启动时生成生产提示
    Vue.config.productionTip = false
    //创建Vue实例
    new Vue({
        el: '#demo',
        data: {
            firstName: '小猪',
            lastName: '佩奇',
            watchName: '煎饼姐姐'
        },
        // 计算属性去计算一个不存在的属性实现全名拼写
        computed: {
            fullName() {
                return this.firstName + this.lastName;
            }
        },
        // 监听属性监听一个已经存在的属性实现全名拼写
        watch: {
            // 监听姓改变的时候
            firstName: {
                handler(val) {
                    this.watchName = val + this.lastName;
                }
            },
            // 监听名改变的时候 简写形式
            lastName(val){
                this.watchName =  this.firstName+val;
            },
            // 如果想要延迟执行某个操作
            watchName(){
                setTimeout(() => {
                    // 延迟2s打印某个值
                    console.log(this.watchName,'延迟执行咯'); // 此处要写成箭头函数 因为会失去this指向不会指向window 但是会网上找 找到watchName的this 那么this就指向vm 也就是vue的实例对象
                }, 2000);
            }
        }
    })
    // firstName 的this是指向vue的 所以里面是setTimeOut写箭头函数 就会失去自己的this 会往上级找 就变成firstName的this所以依然指向vm
</script>