精华内容
下载资源
问答
  • vue监听数据变化

    2020-04-10 15:51:36
    监听数据变化,在Vue中是通过侦听器来实现的,你也可以将它理解为监听器,时刻监听某个数据的变化。 watch的基本用法 在之前我们在js中添加了data、methods,这一次我们要添加的是watch属性。下面我们先来眼熟一下...

    监听数据变化,在Vue中是通过侦听器来实现的,你也可以将它理解为监听器,时刻监听某个数据的变化。

    watch的基本用法

    在之前我们在js中添加了data、methods,这一次我们要添加的是watch属性。下面我们先来眼熟一下侦听器的添加位置:

    <script>
    export default {
        name: "app",
        // 数据
        data() {
            return {};
        },
        // 方法
        methods:{},
        // 侦听器
        watch:{}
    };
    </script>
    

    一个简单的例子:

    <template>
        <p>你点击按钮的次数是: {{ count }} </p>
        <button @click="add" v-model="count">点击</button>
    </template>
    
    <script>
    export default {
        name: "app",
        data(){
            return {
                count:0
            }
        },
        methods:{
            add(){
                this.count++;
            }
        },
        watch:{
            // 被侦听的变量count
            count(){
                console.log('count 发生了变化');
            }
        }
    };
    </script>
    

    侦听器更多的是用在异步操作中,所谓异步操作就是数据返回有所延迟的操作,比如说我们要请求后端的接口,接口会返回给我们数据,然后我们再将数据渲染在页面上。

    从请求接口到返回数据,这中间需要一定的时间,此时我们就可以用侦听器来侦听返回的数据,当数据返回以后,我们再触发渲染。

    模拟一个伪异步操作:

    <template>
        <input type="text" v-model="inputValue">
        <p>从输入框中获取到的数据:{{ passedInputValue }}</p>
    </template>
    
    <script>
    export default {
        name: "app",
        data(){
            return {
                inputValue: '',
                passedInputValue: ''
            }
        },
        watch:{
            inputValue() {
                // 当inputValue数据发生变化以后,延迟三秒赋值给passedInputValue
                setTimeout(() => {
                    this.passedInputValue = this.inputValue;
                }, 3000)
            }
        }
    };
    </script>
    

    此时你就会发现,当你在input输入框中输入文字以后,p标签内的数据不是立马改变,而是过三秒才会去渲染。

    获取前一次的值

    在某些场景中,我们会需要上一次的数据,此时,侦听器就可以给我们两个值,旧值和新值。

    在上一个案例的基础上,我们只需要添加一个参数,即可获取旧值,代码如下:

    watch:{
        inputValue(value,oldValue) {
            // 第一个参数为新值,第二个参数为旧值,不能调换顺序
            console.log(`新值:${value}`);
            console.log(`旧值:${oldValue}`);
        }
    }
    

    handler方法和immediate属性

    前面我们已经知道,当我们侦听的值没有发生改变的时候,是不会触发侦听器的,并且,页面第一次渲染的时候也不会触发侦听器

    但是现在我有个需求就是要让页面第一次渲染的时候就去触发侦听器呢?

    此时就要用到一个方法和一个属性。

    <template>
        <p>FullName: {{fullName}}</p>
        <p>FirstName: <input type="text" v-model="firstName"></p>
    </template>
    
    <script>
    export default {
        name: "app",
        data(){
            return {
                firstName: 'Su',
                lastName: 'Junyang',
                fullName: ''
            }
        },
        watch:{
            firstName: {
                handler(newName, oldName) {
                    this.fullName = newName + ' ' + this.lastName;
                },
                // 如果设置了false,那么在页面第一次渲染以后不会触发侦听器
                immediate: true
            }
        }
    };
    </script>
    

    deep 深度侦听

    所谓深度侦听就是侦听对象内部属性的值

    我们之前用的侦听器都只能侦听一个变量的变化,(重点看一下代码中的注释)例如:

    data:{
        return {
            // 字符串发生变化,可以侦听
            firstName: 'Su',
            room:{
                name:"大床房",
                // 当房号发生变化的时候,侦听器并不能侦听到。
                // 因为侦听器只侦听到room,不能侦听number或者name
                number: 302
            }
        }
    },
    

    此时我们就需要深度侦听。
    深度侦听在代码上并不难实现,只需要在handler的基础上添加一个deep属性,代码如下:

    watch:{
        room:{
            handler(newRoom,oldRoom){
                console.log("房间号发生了变化")
            },
            deep: true
        }
    }
    

    案例:使用侦听器和定时器实现伪模糊搜索

    <template>
      <div class="search">
        <input type="text" v-model="inputValue" />
        <div class="search-block" v-for="(element, index) in results" :key="index">
          {{ element }}
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'app',
      data() {
        return {
          results: [],
          mockData: [
            '浙江大学',
            '中国人民大学',
            '清华大学',
            '清华大学附属中学',
            '浙江理工大学',
            '浙江工业大学'
          ],
          inputValue: ''
        };
      },
      watch: {
        inputValue(value) {
          if (!!value) {
            setTimeout(() => {
              this.results = this.mockData.filter(el => {
                console.log(value);
    
                return el.indexOf(value) !== -1;
              });
            }, 300);
          }
        }
      }
    };
    </script>
    
    
    展开全文
  • 本篇文章主要介绍了Vue监听数据变化,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Vue监听数据变化

    万次阅读 2017-02-17 09:58:35
    浅度监听<!DOCTYPE html> 自定义键盘信息 , initial-scale=1.0, maximum-scale=1.0, user-scala

    浅度监听

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>浅度监听</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <script src="../js/vue1.0.js"></script>
        <script src="../js/vue-resource.js"></script>
        <script>
            window.onload = function(){
                var vm = new Vue({
                    el:'#box',
                    data:{
                        a:111,
                        b:2
                    }
                });
                vm.$watch('a',function(){
                    alert('发生变化了');
                });
                document.onclick = function(){
                    vm.a = 1;
                }
            }
        </script>
    </head>
    <body>
    <div id="box">
        {{a}}
        <hr>
        {{b}}
    </div>
    </body>
    </html>

    深度监听

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>深度监听</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <script src="../js/vue1.0.js"></script>
        <script src="../js/vue-resource.js"></script>
        <script>
            window.onload = function(){
                var vm = new Vue({
                    el:'#box',
                    data:{
                        json:{name:'abcdef',age:'16'},
                        b:2
                    }
                });
                vm.$watch('json',function(){
                    alert('发生变化了');
                },{deep:true});
                document.onclick = function(){
                    vm.json.name = "aaaaaa";
                }
            }
        </script>
    </head>
    <body>
    <div id="box">
        {{json | json}}
        <hr>
        {{b}}
    </div>
    </body>
    </html>
    展开全文
  • Vue监听数据变化原理

    2021-04-22 11:08:21
    Vue监听数据变化原理 vue2.x版本底层使用Object.defineProperty监听数据变化,数据变化后通知观察者observer 我们模拟new Vue()过程初始化一个vue的实例 const vm = new Vue_({ key: '' + Date.now(), data: ...

    Vue监听数据变化原理

    vue2.x版本底层使用Object.defineProperty监听数据变化,数据变化后通知观察者observer

    我们模拟new Vue()过程初始化一个vue的实例

    const vm = new Vue_({
        key: '' + Date.now(),
        data: function () {// 数据
            return {
                menu: {
                    home: 'home',
                    mine: 'mine'
                }
            }
        },
        watch:{// 监听变化
            "menu.home":function (newv, oldv) {
                console.log(`newv=${newv},oldv=${oldv}`)
            },
            "menu.mine": function (newv, oldv) {
                console.log(`newv=${newv},oldv=${oldv}`)
            }
        },
        methods:{
            setHomeName(name){
                console.log('name=',name)
                this.data.menu.home = name
            }
        }
    })
    

    调用vm的方法改变home的值,vm.setHomeName('这是home主页')

    上面这个方法在Vue中实际上相当于this.setHomeName('这是home主页')

    下面是Vue_的具体实现

    // Vue实例
    const Vue_ = function(props){
        const {key,data,watch,methods} = props;
        this._id = key;
        this.data = data();
        this.depen(watch);
        this.recursion(this.data)
        this.mapMethods(methods)
    }
    /**
     * 给wathc对象添加订阅
     * @param {Object} watch 
     */
    Vue_.prototype.depen = function(watch){
        for (var key in watch) {
            console.log('key=',key)
            this.observer(this._id).subscribe(key, watch[key])
        }
    }
    /**
     * 递归调用
     * @param {*} obj 
     * @param {*} path 
     */
    Vue_.prototype.recursion = function(obj,path){
        for (var key in obj) {
            this.defineReaactive(obj, key, obj[key], path)
        }
    }
    /**
     * 给对象添加getter/setter方法
     * @param {*} obj 对象
     * @param {*} key 属性名
     * @param {*} val 属性值
     * @param {*} path 属性路径
     */
    Vue_.prototype.defineReaactive = function(obj, key, val, path){
        var _self = this;
        path = `${path ? path + '.' : ''}${key}`
        if (typeof val === 'object') {
            this.recursion(val, path);
        } else {
            Object.defineProperty(obj, key, {
                set(newv) {
                    console.log(`path=${path},key=${key},newv=${newv},oldv=${val}`)
                    _self.observer(_self._id).publish(path, newv, val)
                    if (newv !== val) val = newv;
                },
                get() {
                    return val
                }
            })
        }
    }
    Vue_.prototype.mapMethods = function(methods){
        var _this = this;
        for (var key in methods){
            Vue_.prototype[key] = function(){
                return methods[key].apply(_this,arguments)
            }
        }
    }
    // 观察者
    Vue_.prototype.observer = (function () {
        var namespaces = {}, NAMESPACE = '_default'
        /**
         * 监听
         * @param {string} path 
         * @param {*} cache 
         * @param {Function} cb 
         */
        var _subsribe = function (path, cache, cb) {
            if (!cache[path]) {
                cache[path] = [];
            }
            var listeners = cache[path];
            listeners.push(cb)
        }
        /**
         * 发布订阅
         * @param {string} path 
         * @param {*} cache 
         * @param  {arguments} args 
         */
        var _publish = function (path, cache, ...args) {
            if (cache[path]) {
                var listeners = cache[path];
                listeners.forEach(function (cb) {
                    cb.apply(cb, args)
                })
            }
        }
        /**
         * 创建观察者实例
         * @param {String} namespace 
         * @returns {{subscribe, publish}} 返回一个对象
         */
        var create = function (namespace) {
            namespace = namespace || NAMESPACE;
            var listenerCache = {}
            var subscribe = function (type, cb) {
                _subsribe(type, listenerCache, cb)
            }
            var publish = function (type, ...args) {
                _publish(type, listenerCache, ...args)
            }
            return namespaces[namespace] ? namespaces[namespace] : namespaces[namespace] = { subscribe, publish }
        }
        return create;
    })();
    
    

    下图给出了Data,observer, dep, wather之间的关系
    在这里插入图片描述

    参考文献

    • 深入浅出Vue.js-第二章. [D]. 刘博文. 人民邮电出版社
    展开全文
  • Vue监听数据变化watch() watch()可以监视data中指定数据的变化 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-...

    Vue监听数据变化

    watch

    watch可以监视data中指定数据的变化
    在这里插入图片描述

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, inital-scale=1.0">
    	<meta http-equiv="X-UA-Compatible" content="ie=edge">
    	<title></title>
    	<script src="vue.js"></script>
    	<script src="vue-router.js"></script>
    </head>
    <body>
    	<div id="app">
    		我们应该称呼您<input type="text" v-model="firstName">先生/女士
    		如果方便,请告诉我们您的名字<input type="text" v-model="lastName">
    		<input type="text" v-model="fullName">您好!很高兴为您服务!
    	</div>
    	<script>
    		var vm = new Vue({
    			el:'#app',
    			data: {
    				firstName:'',
    				lastName:'',
    				fullName:''
    			},
    			methods: {},
    			watch: {//监视data中指定数据的变化
    				'firstName': function(newVal, oldVal) {
    					this.fullName = newVal + this.lastName
    				},
    				'lastName': function(newVal) {
    					this.fullName = this.firstName + newVal
    				}
    			}
    		});
    	</script>
    </body>
    </html>
    
    

    computed()

    computed()中,可以定义一些计算属性,它的本质是一个方法,但使用时是直接把方法名称当作属性使用
    它有三个特点:

    1. 计算属性在引用的时候不加()直接当作普通属性使用
    2. 只要function(){}内部任何data中的数据发生变化,就会重新计算
    3. 计算属性的结果会被缓存起来方便下次使用,如果方法中的数据没有变化则不重新计算
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, inital-scale=1.0">
    	<meta http-equiv="X-UA-Compatible" content="ie=edge">
    	<title></title>
    	<script src="vue.js"></script>
    	<script src="vue-router.js"></script>
    </head>
    <body>
    	<div id="app">
    		我们应该称呼您<input type="text" v-model="firstName">先生/女士
    		如果方便,请告诉我们您的名字<input type="text" v-model="lastName">
    		<input type="text" v-model="fullName">您好!很高兴为您服务!
    	</div>
    	<script>
    		var vm = new Vue({
    			el:'#app',
    			data: {
    				firstName:'',
    				lastName:'',
    			},
    			methods: {},
    			computed: {//监视data中指定数据的变化
    				'fullName': function() {
    				 	return	this.firstName + this.lastName
    				}
    			}
    		});
    	</script>
    </body>
    </html>
    
    

    watch、computed、methods之间的对比

    1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算,主要当作属性来使用
    2. methods方法表示一个具体的操作,主要书写业务逻辑
    3. watch一个对象,键是需要观察的表达式,值是对应的回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看做是computedmethods的结合体
    展开全文
  • 2.环境:vue+数据从父组jian件传进(TimeIntervalNumberData) <template> <div> <div id="chart-temperature-timeintervalnumber" style="width: 200px;height:30px;"></...
  • 主要为大家详细介绍了Vue监听数据对象变化的源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 下面小编就为大家分享一篇浅谈VUE监听窗口变化事件的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • vue监听json数据变化

    2020-06-30 15:06:10
    普通数据 export default { data() { return { descLength: 0 } }, watch: { 'descLength': function(newValue) { console.log(newValue) } } } json数据的某个元素 export default { data() { return ...
  • vue 监听data数据变化

    千次阅读 2017-12-11 16:24:00
    当被监听数据发生变化是,函数被执行 created() { this.$watch("Withdrawals", function (newValue, oldValue) { if(this.Withdrawals==false){ console.log("123") } }) } data(){ retu.....
  • vue watch监听数据变化

    2021-04-02 14:29:50
    // 数据发生变化就会调用这个函数 handler(newVal, oldVal) { console.log('oldVal:', oldVal) console.log('newVal:', newVal) }, // 立即处理 进入页面就触发 immediate: true, deep.
  • Vue页面监听数据变化

    千次阅读 2020-07-19 15:49:43
    某个页面需要根据路由query查询参变化执行对应的操作,放在生命周期钩子函数里面都不太合适,因为生命周期钩子函数是针对组件的不是针对页面的,所以需要通过watch监听路由query查询参的变化,代码如下: ...
  • Vue监听数据变化

    万次阅读 2017-09-24 14:25:38
    1.轻度监视 window.onload=function(){ var vm=new Vue({ el:'#box', data:{ a:111,
  • 我们使用vue的时候都知道vue有一个很好用watch可以用来监听数据的变化,但是,默认的时候是监听不到对象变化的,这时候就要配置deep=true这个字段。 代码: watch: { // 监听对象数据变化 objData: { handler...
  • vue监听数据改变

    千次阅读 2021-01-29 13:15:32
    当data中的数据变化时,watch监听到并且执行 <template> <div> <p>大名: {{fullName}}</p> <p>名称: <input type="text" v-model="firstName"></p&g
  • vue 监听路由变化

    2020-10-27 15:59:31
    在多页面开发中我们总是要通过路由来映射不同的组件,这样势必就涉及到页面与页面之间的交互,比如传参,A页面=>B页面的拦截,当A跳转成功后B页面做...// 监听新老路由变化信息 watch:{ $route:{ handler(newVal,
  • vue computed+watch监听数据变化 vue computed+watch监听数据变化 data(){ return{ listQuery: { QueryInfo: null, PageNo: 1, PageSize: 50 }, } } computed: { QueryInfo: function() { return this.list...
  • Vue 监听路由变化

    千次阅读 2019-03-05 18:28:41
    Vue.js 官方文档中提供了导航完成后获取数据 和在导航完成前获取数据两种方法,我个人使用的是前者,这个需要小伙伴们自己按照需求来定。文档地址 现在着重说一下导航完成后获取数据中的不同的写法: 第一种 ...
  • Vue监听vuex中的数据变化

    千次阅读 2020-08-10 19:48:38
    watch主要作用是监听数据变化 假如我们的购物车的商品信息在vuex中,属性名是:carshopping 那我们监听的时候就要在组件中用到watch了 注意:watch在Vue中和name、data这些属性同级。 watch有两个参数,分别是...
  • Vue项目数据变化被watch监听并处理

    千次阅读 2020-02-21 14:04:06
    Vue项目数据变化被watch监听并处理监听当前vue文件数据监听vuex中的数据 监听当前vue文件数据 例如,当前的vue文件的data中有如下属性: data() { return { dialogFormVisible: false, } } 要监听...
  • Vue监听表单变化

    千次阅读 2019-12-19 17:02:56
    需求:当表单中未填写任何项时,提交按钮置灰,只要填写其中一项,则可点击按钮。 <el-buttontype="primary":disabled="isButtonGray"@click="handleSave('ruleForm')">保存</el-button> ... ...
  • vue通过watch监听数据变化

    千次阅读 2020-04-12 10:18:15
    一:通过watch来监听数据变化,并通过打印显示 <template> <div class="personal-center"> <input type="text" placeholder="请输入" v-model="inputVal"/> <p>{{newVal}}</p> &...
  • 1 vue监听路由参数变化,路由变化的时候刷新数据 path的路径还是本页面,通过query传入query数据,但是页面数据没有刷新 <router-link tag="div" :to="{path:'/playList',query:{id:item.id}}"></router-...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 35,271
精华内容 14,108
关键字:

vue监听数据变化

vue 订阅