老师有关watch和$options的理解、疑问

老师有关watch和$options的理解、疑问

图片描述
图片描述
难道监听的是 rules下的ageval???并不是数据data下的age??

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>插件实例, 数据校验</title>
    <script src="http://unpkg.com/vue@next"></script>
</head>
<body>
    
    <div class="root"></div>
    <script>
        const app =Vue.createApp({
            data(){
                return{
                    age:23,
                    name:"王紫腾"
                }
            },
            rules:{
                // 被校验的数据
                ageval:{
                    validata: age=>{return age>25},
                    message:`too young`
                },
            },
            template:`
                <div>{{connumble}}</div>
            `  
        })
        //定义一个数据校验的插件
        const datajianchaPlugin=(app,options)=>{
            //利用插件传递过来的app实例,创建使用mixin
            app.mixin({
                // 周期函数
                created(){
                    // console.log(this.$options.rules);
                    for(let key in this.$options.rules){
                        let item=this.$options.rules[key];
                        // console.log(item.validata(26));
                        this.$watch(age,(newvalue)=>{
                            console.log("datachange");
                            // const result=this.item.validata(newvalue);
                            // if(!result){
                            //     console.log(item.message);
                            // }
                        })
                    }
                }
            })
        }
        //使用该插件
        app.use(datajianchaPlugin);//此处没有传参

        const vm=app.mount(".root");

    </script>

</body>
</html>

我感觉老师在准备案例的时候还是不要重名的好, 容易疑惑

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕小李 2023-01-30 17:09:56

同学你好,解答如下:

先说问题,代码中的connumble未声明就使用了。这不好~

https://img1.sycdn.imooc.com//climg/63d77edf09336d5804170073.jpg

接下来回答问题:

1、this.$options我们打印一下看看是什么:

https://img1.sycdn.imooc.com//climg/63d780a7096530ac07000453.jpg

https://img1.sycdn.imooc.com//climg/63d78099090d1d8013170165.jpg

那么结果来看同学的理解是对的,this.$options就是实例上属性的集合。

2、$watch的第一个参数是监听来源的(属性名也就是data中的属性名)那么同学这里改为age,会报错的原因是获取不到,这是因为已经使用了for in遍历,那么基于第一个参数是监听来源的,则第一个参数应是key也就是ageval如下:

https://img1.sycdn.imooc.com//climg/63d7825f09c0c68407510479.jpg

但是我们在使用watch进行监听的时候会发现并没有打印出任何的东西如下:

https://img1.sycdn.imooc.com//climg/63d7850e0985803107760403.jpg

https://img1.sycdn.imooc.com//climg/63d7851d09bf8f3b11160249.jpg

那么这里的问题就出在了监听的key是ageval而不是age,也就是指data中并没有ageval这个属性名,所以我们监听不到。

https://img1.sycdn.imooc.com//climg/63d7859609fe423a07330424.jpg

既然这样我们将同学代码中rules中ageval改回age在试试如下:

https://img1.sycdn.imooc.com//climg/63d785f20999f52108720840.jpg

https://img1.sycdn.imooc.com//climg/63d785d70994c6d310320307.jpg

这时watch才监听到了。

this.$watch()中监听的也是属性名(其实是data中的数据,与这里同名而已)当data中的数据发生了变化则watch就会监听到。那么我们进一步认证上述的说法,老师这边完善了小例子如下:

https://img1.sycdn.imooc.com//climg/63d788c209903bfe10730877.jpg

将data中数据的属性名全部都纳入了rules中如上图,然后我们在通过vm.$data.age\ageval\name去改变它,看看是否能出发watch如下:

https://img1.sycdn.imooc.com//climg/63d789350932904814260639.jpg

综上所述,this.$watch的第一个参数实际上就是data中的属性名。

祝学习愉快!

  • 提问者 鸣蜩十柒 #1

    那老师 若是不重名的情况下, 该如何表示呢,我当时就用重名的情况下(都是age的情况下),watch能触发监听,

    https://img1.sycdn.imooc.com//climg/63d7a82208c2b5e705590872.jpg




    2023-01-30 19:21:21
  • 好帮手慕小李 回复 提问者 鸣蜩十柒 #2

    我可能是没表达清晰,这个例子中不能不重名。视频中老师这么写是一个取巧的写法,因为watch的第一个参数就是针对data中所具有的属性名,比如说name与age他们都在data中存在的,然后老师通过遍历rules中的key这里的key就是ageval(改了以后)如下:

    https://img1.sycdn.imooc.com//climg/63d7c5120962c1c414080731.jpg

    相当于是讲ageval变成监听的源头,那么data中不存在ageval则watch是没办法监听到的。

    如果同学需要这里一定要换名字,那么如下方式仅供参考。

    不遍历rules直接将data中的属性单独写一份监听如下:

    https://img1.sycdn.imooc.com//climg/63d7c611096bba3217851809.jpg

    或如下:

    https://img1.sycdn.imooc.com//climg/63d7c70909c6986813551050.jpg

    遍历this.$options.data()也可以,因为this.$options.data()就是data中的数据如下:

    https://img1.sycdn.imooc.com//climg/63d7c744098c9fe109920404.jpg

    那么遍历时key就是name与age。以上两种方式中的rules名字可以是自定义的。

    同学尝试理解一下,代码如下。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>插件实例, 数据校验</title>
        <script src="http://unpkg.com/vue@next"></script>
    </head>
    <body>
        <div class="root"></div>
        <script>
            const app =Vue.createApp({
                data(){
                    return{
                        age:23,
                        name:"王紫腾"
                    }
                },
                rules:{
                    ageval:{
                        validata: age=>{return age>25},
                        message:`too young`
                    },
                },
                template:`
                    <div>{{name}},{{age}}</div>
                `  
            })
            const datajianchaPlugin=(app,options)=>{
                app.mixin({
                    created(){
    
                        // 方式一
    
                        // this.$watch("age",(newvalue)=>{
                        //     console.log("datachange");
                        // })
                        // this.$watch("name",(newvalue)=>{
                        //     console.log("datachange");
                        // })
    
                        // 方式二
    
                        // for(let key in this.$options.data()){
                        //     console.log(key) // name 、 age
                        //     this.$watch(key,(newvalue)=>{
                        //         console.log("datachange");
                        //     })
                        // }
                    }
                })
            }
            app.use(datajianchaPlugin);
            const vm=app.mount(".root");
        </script>
    </body>
    </html>

    祝学习愉快!

    2023-01-30 21:37:21
  • 提问者 鸣蜩十柒 回复 好帮手慕小李 #3

    好的,知道了 谢谢老师

    2023-01-31 09:51:32
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师