Vue的数据控制-----计算属性(computed)&&侦听器(watch)

5 、数据控制
5.1 、计算属性 (computed)
构建方式: 类型: computed:{ key:value }
key :取值类型 string ,用于 == 定义计算属性变量名称 == 计算属性具有 vue
通数据仓库的变量功能,同时具有 vue 方法仓库中 this 的指向
value :定义计算属性的相关取值
取值为 Function 时,提供计算属性取值功能 (getter) ,此时该计算属性为
读属性
取值为 Object { get:Function,set:Function } 时,提供计算属性取值 (getter)
和修改 (setter) 功能
功能:用于控制数据在页面输出前,对数据进行包装处理
特性:
计算属性 在对数据进行处理包装时,需要依赖一个当前 Vue 对象中普通属性
计算属性的结果 ,会随着依赖的普通属性的变换发生变换(重新调用方法)
计算属性的变量名称不能和 vue 实例中其它存储仓库中属性名称或者方法名称一
计算属性具有缓存结果的功能

 计算属性:

                提供和data一样的属性页面调用语法规则,

                但同时又能兼顾方法的自定义执行逻辑扩展( 计算属性的方法内部this指向于当前应用实例 )

            计算属性的特性:

                默认情况下计算属性构建的变量为只读变量,只能取值不能修改;

                通过对象取值配置,可以实现计算属性的双向操作功能;

               

            应用场景

                1. 可以将页面的相关复杂执行逻辑定义于计算中,页面以属性调用的方式简化模板语法的定义

                2. 通过计算属性的缓存规则,可以减少模板调用时对计算逻辑的执行的次数提供运行性能的提升

                    + 计算属性独立存在没有使用价值的,程序开发中会和其它属性实现关联依赖开发,提供逻辑运算和缓存功能;

                    + 计算属性的缓存是指在依赖变量未发生变换时,当前vue容器中多次使用不会重新执行方法,而是读取计算后的缓存结果

                3. 通过计算属性的双向操作功能语法,可以将页面具有双向功能但逻辑不同的操作模拟成普通属性的双向功能

<div>
<p>username:{{ username }}</p>
        <input type="text" v-model="username">
    </div>

    <script type="module">
        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        createApp({
            data() {
                return {
                    info: "data属性info",
                    size: -1,
                    str: "a",
                    _username:"测试数据"
                }
            },
            // 带有方法运行和计算功能的数据仓库 - 计算属性
            computed: {
                // key 属性名,value是执行方法,但必须存在return提供属性返回值
                msg: function () {
                    return "计算属性msg"
                },
               
                // key定义计算属性的属性名
                // valeu 取值 { get:Fuction,set:Fuction } ,用于构建计算的双向操作功能
                // username(){
                //     return "字符串"
                // }
                username:{
                    get:function(){
                        // 计算属性的取值操作
                        return this._username
                    },
                    set:function(nv){
                        // 计算属性的赋值操作
                        console.log(nv);
                        this._username = nv;
                    }
                }

 当需要计算的变量为循环时的临时变量,此时计算功能只能由方法提供

      <!-- 当需要计算的变量为循环时的临时变量,此时计算功能只能由方法提供 -->
    <ul>
        <li v-for="(i) in arr">{{num(i)}}</li>
    </ul>

     methods: {
             
                num(num){
                       return num*100+"%"
                }

            },

 5.2、侦听器 (监视器) (watch)

功能:构建一个对 Vue 实例中数据仓库中变量( data computed.... )的监控方
法, 实现当数据变化时执行额外扩展方法
实例内构建方式:
key string ):被监视的数据变量名称 == 或对象路径表示方式 ==
! 注意 ! : 对象路径表示形式只能用于 Vue 的监视器定义时
value Function|Object|Array : 定义监视器执行方式
Vue . createApp ({
data :{},
computed :{
// 构建计算属性
}
methods :{}
})
Vue . createApp ({
watch : {
key : value
},
}) 取值 Function : 定义基础的数据监控方法
取值 Object : 定义可扩展数据监控配置
实例外构建
expOrFn string|Function )被监视的数据变量名称、 == 对象路径表示方
== == 多变量配置方法 ==
取值为 string :被监视的数据变量名称 == 或对象路径表示方式 ==
取值为 Function :被监视的 == 多变量配置方法 ==
callback Function : 定义的监控处理方法
options Object ):定义监控扩展功能
返回值 unwatch Function : 返回一个用于关闭销毁销毁当前监控的方法
5.4 、计算属性、监视器、普通方法
{
handler : Function 定义监控方法
deep : Boolean 是否开启深度监视
immediate : Boolean 是否开启初始化触发
}
var app = Vue . createApp ({ …… });
var vm = app . mount ( "#app" )
var unwatch = vm . $watch ( expOrFn , callback , [ options ] )
{
deep : Boolean 是否开启深度监视
immediate : Boolean 是否开启初始化触发
}

 key 定义和描述需要监听的变量名(data,computed,……)

 value 取值Function,为被监听的变量提供变换时的主动触发函数

 该方法具有两个固定形参,分别是变化后的值和变化前的值

     watch:{
                // key 定义和描述需要监听的变量名(data,computed,……)
                // value 取值Function,为被监听的变量提供变换时的主动触发函数
                //       该方法具有两个固定形参,分别是变化后的值和变化前的值
                msg:function(nv,ov){
                    console.log("watch-msg变量发生变换",nv,ov);
                },
           }

 watch 监视器构建时 key可以定义取值表达式(仅支持.号取值),表示需要监控的变量和层级

 key取值表达式具有特殊功能的操作,只在vue监视器中有效

                // watch 监视器构建时 key可以定义取值表达式(仅支持.号取值),表示需要监控的变量和 
                   层级
                //   key取值表达式具有特殊功能的操作,只在vue监视器中有效
                "user.name":function(nv,ov){
                    console.log("watch-user.name变量发生变换",nv,ov);
                },


                 //以下方法不可行
                // "user['age']":function(nv,ov){
                //     console.log("watch-user.age变量发生变换",nv,ov);
                // }

vue的watch监视器构建的引用数据监控,默认为浅监控,使用时需要转换为深监控

 watch 监视器构建时 value取值固定对象结构 { handler:Function,deep:Boolean }

handler 监控数据发生变换时的回调方法

 deep 为监控深度的描述 默认为false(浅监控)

    // watch 监视器构建时 value取值固定对象结构 { handler:Function,deep:Boolean }
                //      handler 监控数据发生变换时的回调方法
                //      deep 为监控深度的描述 默认为false(浅监控) 
                
             watch:{    
             arr:{
                    handler(nv,ov){
                        console.log("watch-arr变量发生变换",nv,ov);
                    },
                    deep:true // 开启深度监控
                },
                }
             

 watch 监视器构建时,value取值固定对象 { handler:Function,immediate:Boolean },实现在页面第一次运行时执行方法 
 immediate 默认值false , 页面首次加载不会执行该监视方法,为true时,页面加载则会执行监视

                // watch 监视器构建时,value取值固定对象 { handler:Function,immediate:Boolean 
                   },实现在页面第一次运行时执行方法 
                //          immediate 默认值false , 页面首次加载不会执行该监视方法
          watch:{      
             
          info:{
                    handler(nv,ov){
                        console.log("watch-info=变量发生变换",nv,ov);
                    },
                    immediate:true
                }
                }

 出现上面原因,前后值相同是因为只改变了数组里面的内容,对地址没变,所以前后值相同,如果是整个数组都被改变了,则前后值不同

 面试题:vue中如何同时对多个变量定义统一监控方法?

                方式1:通过计算属性

                方式2:通过$watch完成监控

<!--

            vue也可以构建可控监视器(vue应用外构建方案)

                + 通过vue提供的应用实例方法 $watch 完成变量监视器的定义

                + $watch定义的监视器会返回一个 关闭该监视器的回调方法

               

            vue变量监视器可以累加,而每次通过$watch返回监控解绑方法是相互独立

           

            vue实例.$watch(expOrFn, callback, [options])

                + expOrFn : 接收被监控的变量的名称 或者 和监控变量有关的方法

                            + 定义字符串表达式时,等效于对变量直接完成监控控制

                            + 定义方法且方法返回值绑定了相关变量,等同于对绑定的所有变量统一完成监控(expOrFn取值可以是方法构建多变量统一监控)

                + callback : 变量发生变化时执行的回调函数

                + options : 取值 Object ,用于定义除handler以外的其它监视配置(深度监控,初始调用……可选项)

           

        -->

 // 在应用根属性上添加一个用于中转,但不需要劫持的变量数据 - 为其他区域提供调用支持

 // 这种中转数据变量 在vue 开发规范中建议 以 $ 开头(非仓库中的数据,在实例构建上均以$符开头),实现和普通劫持变量的区分,防止污染

    <div id="app">
      
        <p>num1:{{ num1 }}</p>
        <input type="number" v-model.number="num1">
        <p>num2:{{ num2 }}</p>
        <input type="number" v-model.number="num2">
        <p>求和:{{ num1+num2 }}</p>
        <p>求和:{{ sum }}</p>
        <hr>
        <p>msg:{{ msg }}</p>
        <input type="text" v-model="msg">
        <br>
        <input type="button" value="绑定msg监视" @click="addWatch()">
        <input type="button" value="解绑msg监视" @click="removeWatch()">
        <hr>
        <p>num3:{{ num3 }}</p>
        <input type="number" v-model.number="num3">
        <p>num4:{{ num4 }}</p>
        <input type="number" v-model.number="num4">
        <p>求和:{{ num3+num4 }}</p>
        <input type="button" value="绑定num3+num4求和监视" @click="addNumWatch()">
    </div>

    <script type="module">
        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        var vm = createApp({
            data() {
                return {
                    num1: 10,
                    num2: 20,
                    num3: 30,
                    num4: 40,
                    msg: "msg",
                }
            },
            computed: {
                sum() {
                    return this.num1 + this.num2
                }
            },
            watch: {
                sum(nv, ov) {
                    console.log("num1+num2求和结果变化:", nv, ov);
                }
            },
            methods: {
                addWatch() {
                    // 在应用根属性上添加一个用于中转,但不需要劫持的变量数据 - 为其他区域提供调用支持
                    // 这种中转数据变量 在vue 开发规范中建议 以 $ 开头,实现和普通劫持变量的区分
                    if(this.$unwatch) return;
                    this.$unwatch = this.$watch("msg", (nv, ov) => {
                        console.log("$watch 监控的msg发生变化", nv, ov);
                    })
                    console.log(this.$unwatch);
                    console.log(this);
                },
                removeWatch(){
                     // 方法转换成布尔类型,是true,方法不存在的话是undefined,相当于false,
                    /* if(!this.$unwatch){
                          return
                           } */
                    if(!this.$unwatch) return; //ES5中,程序中只有一行代码,大括号可以省略,但是不能换行
                    this.$unwatch(); // $watch过会返回一个方法函数,该方法函数被执行后会解绑 
     当前监控器
                    this.$unwatch = undefined/null; // 解绑以后,this.unwatch依然存在,须重置为重新绑定的取值上,设置为null或者undefined
                },
                addNumWatch() {
                    this.$watch(
                        () => {
                            // return this.num3+this.num4
                            // return [this.num3,this.num4]
                            return {
                                num3:this.num3,
                                num4:this.num4
                            }
                        },
                        (nv, ov) => {
                            // console.log("$watch 监控的num3+num4发生变化", nv, ov);
                            // console.log("$watch 监控的[num3,num4]发生变化", nv, ov);
                            console.log("$watch 监控的{num3,num4}发生变化", nv, ov);

                        }
                    )
                }
            }
        }).mount("#app")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值