Vue计算属性&侦听器|监听器&过滤器

计算属性:

                1.定义:要用的属性不存在,要通过已有属性计算得来。

                2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。

                3.get函数什么时候执行?

                            (1).初次读取时会执行一次。

                            (2).当依赖的数据发生改变时会被再次调用。

                4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。

                5.备注:

                        1.计算属性最终会出现在vm上,直接读取使用即可。

                        2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。


<div id="app">

        <p>姓:<input type="text" v-model="firstName"></p>

        <p>名:<input type="text" v-model="lastName"></p>

        <p>地址:<input type="text" v-model="address"></p>

        <!-- 计算属性的优势是:有缓存,当页面数据发生变化时,所有的方法都要重新执行,

        当计算属性用到的数据发生变化时,计算属性才会重新执行。 -->

        <p>方法返回姓名:<input type="text" :value="fullName2()"></p>

        <p>计算属性返回姓名:<input type="text" :value="fullName"></p>

        <hr>

        <ul>

            <li v-for="(item,index) in goodses" :key="index">{{item.name}}--{{item.price}}元--

                <button @click="delGoods(index)">删除</button>

            </li>

            <li>总价是--{{totalPrice}}元</li>

        </ul>

    </div>


 new Vue({

            el: '#app',

            data: {

                firstName: '张',

                lastName: '杰',

                address: '成都',

                goodses: [{

                    name: '洗衣机',

                    price: 2999,

                }, {

                    name: '电视机',

                    price: 3999,

                }, {

                    name: '油烟机',

                    price: 1999,

                }]

            },

            methods: {

                fullName2() {

                    console.log('我是方法');

                    return this.firstName + '.' + this.lastName

                },

                delGoods(index){

                    this.goodses.splice(index,1)

                }

                /* totalPrice(){

                    console.log('我在计算总价格');

                   let sum=0

                   this.goodses.forEach(r=>{

                       sum+=r.price

                   })

                   return sum

                } */

            },

            //用于定义计算属性

            computed: {

                totalPrice() {

                    console.log('我在计算总价格');

                    let sum = 0

                    this.goodses.forEach(r => {

                        sum += r.price

                    })

                    return sum

                },

                // 在这里面定义的是方法,计算属性默认情况下只能读,不能改

                fullName() {

                    console.log('我是计算属性');

                    return this.firstName + '.' + this.lastName

                }

                // 定义完整结构的计算属性

                /* fullName:{

                    //get方法,用于返回计算属性的值

                    get(){

                        return this.firstName+'.'+this.lastName

                    },

                    //set方法,用于修改计算属性的值

                    set(val){

                        let arr = val.split('.')

                        this.firstName = arr[0]

                        this.lastName = arr[1]

                    }

                } */

            }

        })


监视属性watch:

                1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作

                2.监视的属性必须存在,才能进行监视!!

                3.监视的两种写法:

                        (1).new Vue时传入watch配置

                        (2).通过vm.$watch监视

<div id="root">

            <h2>今天天气很{{info}}</h2>

            <button @click="changeWeather">切换天气</button>

  </div>


new Vue({

            el:'#root',

            data:{

                isHot:true,

            },

            computed:{

                info(){

                    return this.isHot ? '炎热' : '凉爽'

                }

            },

            methods: {

                changeWeather(){

                    this.isHot = !this.isHot

                }

            },

            watch:{

                isHot:{

                    immediate:true, //初始化时让handler调用一下

                    //handler什么时候调用?当isHot发生改变时。

                    handler(newValue,oldValue){

                        console.log('isHot被修改了',newValue,oldValue)

                    }

                }

            }

        })

        vm.$watch('isHot',{

            immediate:true, //初始化时让handler调用一下

            //handler什么时候调用?当isHot发生改变时。

            handler(newValue,oldValue){

                console.log('isHot被修改了',newValue,oldValue)

            }

        })

深度监视:

                    (1).Vue中的watch默认不监测对象内部值的改变(一层)。

                    (2).配置deep:true可以监测对象内部值改变(多层)。

            备注:

                    (1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!

                    (2).使用watch时根据数据的具体结构,决定是否采用深度监视。

div id="root">

            <h2>今天天气很{{info}}</h2>

            <button @click="changeWeather">切换天气</button>

            <hr/>

            <h3>a的值是:{{numbers.a}}</h3>

            <button @click="numbers.a++">点我让a+1</button>

            <h3>b的值是:{{numbers.b}}</h3>

            <button @click="numbers.b++">点我让b+1</button>

            <button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>

            {{numbers.c.d.e}}

        </div>


new Vue({

            el:'#root',

            data:{

                isHot:true,

                numbers:{

                    a:1,

                    b:1,

                    c:{

                        d:{

                            e:100

                        }

                    }

                }

            },

            computed:{

                info(){

                    return this.isHot ? '炎热' : '凉爽'

                }

            },

            methods: {

                changeWeather(){

                    this.isHot = !this.isHot

                }

            },

            watch:{

                isHot:{

                    // immediate:true, //初始化时让handler调用一下

                    //handler什么时候调用?当isHot发生改变时。

                    handler(newValue,oldValue){

                        console.log('isHot被修改了',newValue,oldValue)

                    }

                },

                //监视多级结构中某个属性的变化

                /* 'numbers.a':{

                    handler(){

                        console.log('a被改变了')

                    }

                } */

                //监视多级结构中所有属性的变化

                numbers:{

                    deep:true,

                    handler(){

                        console.log('numbers改变了')

                    }

                }

            }

        })


过滤器:

            定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。

            语法:

                    1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}

                    2.使用过滤器:{{ xxx | 过滤器名}}  或  v-bind:属性 = "xxx | 过滤器名"

            备注:

                    1.过滤器也可以接收额外参数、多个过滤器也可以串联

                    2.并没有改变原本的数据, 是产生新的对应的数据

//局部过滤器

<div id="app">

        <p>商品名称:{{goods.name}}</p>

        <p>商品价格:{{toFixed2(goods.price)}}</p>

        <p>商品价格:{{myGoods.price}}</p>

        <!-- 通过管道符| 调用过滤器,其实就是调用那个方法,将值传进去,再返回新的值 -->

        <p>商品价格(人民币):{{goods.price | toFixed2 | toRMB}}

            <input type="text" :value="goods.price | toFixed2">

        </p>

        <!-- 过滤器可以链式调用,就是之前已经过滤完成的结果,继续传给下一个过滤器,注意顺序 -->

        <p>商品价格(美元):{{goods.price | toFixed2 | toUS}}</p>

    </div>


new Vue({

            el:'#app',

            data:{

                goods:{

                    name:'小米手机',

                    price:1999.22222

                }

            },

            // 定义方法,过滤商品的价格

            methods: {

                toFixed2(val){

                    return val.toFixed(2)

                }

            },

            // 定义一个计算属性

            computed:{

                myGoods(){

                    let goods = {

                        name:this.goods.name,

                        price:this.goods.price.toFixed(2)

                    }

                    return goods

                }

            },

            // 定义过滤器

            filters:{

                // 过滤在模板中通过管道符 | 的方式来调用

                toFixed2(val){

                    return val.toFixed(2)

                },

                //返回人民币数据

                toRMB(val){

                    return '¥'+ val

                },

                //返回美元数据

                toUS(val){

                    return '$'+ (val/6.5).toFixed(2)

                }

            }

        })


//全局过滤器

<div id="app2">

        <p>商品名称:{{goods.name}}</p>

        <p>商品价格:{{goods.price | toFixed2}}</p>

    </div>


<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>


// 定义全局过滤器

// 如果局部过滤器和全局过滤器冲突了,优先级更高的是局部过滤器

Vue.filter("toFixed2", function (val) {

  return val.toFixed(2);

});


面试相关考点:

1.计算属性与 watch 区别
Computed watch 区别就是 computed 的缓存功能,当无关数据数
据改变时,不会重新计算,直接使用缓存中的值。计算属性是用来声明
式的描述一个值依赖了其他的值,当所依赖的值后者变量发生变化时,
计算属性也跟着改变,
Watch 监听的是在 data 中定义的变量,当该变量变化时,会触发 watch
中的方法

2.什么是计算属性
计算属性是用来声明式的描述一个值依赖了其他的值,当它依赖的这个
值发生改变时,就更新 DOM
当在模板中把数据绑定到一个计算属性上时,vue 会在它依赖的任何值导
致该计算属性改变时更新 DOM
每个计算属性都包括一个 getter 和 setter,读取时触发 getter,修改时
触发 setter

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容