• 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. 通过计算属性的双向操作功能语法,可以将页面具有双向功能但逻辑不同的操作模拟成普通属性的双向功能

    1. <div>
    2. <p>username:{{ username }}p>
    3. <input type="text" v-model="username">
    4. div>
    5. <script type="module">
    6. import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
    7. createApp({
    8. data() {
    9. return {
    10. info: "data属性info",
    11. size: -1,
    12. str: "a",
    13. _username:"测试数据"
    14. }
    15. },
    16. // 带有方法运行和计算功能的数据仓库 - 计算属性
    17. computed: {
    18. // key 属性名,value是执行方法,但必须存在return提供属性返回值
    19. msg: function () {
    20. return "计算属性msg"
    21. },
    22. // key定义计算属性的属性名
    23. // valeu 取值 { get:Fuction,set:Fuction } ,用于构建计算的双向操作功能
    24. // username(){
    25. // return "字符串"
    26. // }
    27. username:{
    28. get:function(){
    29. // 计算属性的取值操作
    30. return this._username
    31. },
    32. set:function(nv){
    33. // 计算属性的赋值操作
    34. console.log(nv);
    35. this._username = nv;
    36. }
    37. }

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

    1. <ul>
    2. <li v-for="(i) in arr">{{num(i)}}li>
    3. ul>
    4. methods: {
    5. num(num){
    6. return num*100+"%"
    7. }
    8. },

     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,为被监听的变量提供变换时的主动触发函数

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

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

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

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

    1. // watch 监视器构建时 key可以定义取值表达式(仅支持.号取值),表示需要监控的变量和
    2. 层级
    3. // key取值表达式具有特殊功能的操作,只在vue监视器中有效
    4. "user.name":function(nv,ov){
    5. console.log("watch-user.name变量发生变换",nv,ov);
    6. },
    7. //以下方法不可行
    8. // "user['age']":function(nv,ov){
    9. // console.log("watch-user.age变量发生变换",nv,ov);
    10. // }

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

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

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

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

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

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

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

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

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

                    方式1:通过计算属性

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

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

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

    1. "app">
    2. <p>num1:{{ num1 }}p>
    3. num2:{{ num2 }}

    4. 求和:{{ num1+num2 }}

    5. 求和:{{ sum }}


    6. msg:{{ msg }}



    7. num3:{{ num3 }}

    8. num4:{{ num4 }}

    9. 求和:{{ num3+num4 }}