Vue 计算属性、Vue 计算属性的特点 Vue 计算属性的缓存、Vue watch监听、Vue 过滤器、

计算属性

我们有时候会在模板中绑定表达式来做简单的数据处理,但是如果表达式太长,就会变得臃肿难以维护。

比如以下代码

<div>
    {{text.split(',').reverse().join(',')}}
</div>

表达式里面包含了3个操作,并不是很清晰,有时候可能会更加复杂,所以在遇到复杂的逻辑时,我们应该使用计算属性。上例可以用计算属性进行改写:

<div id="app">
    {{reverseText}}
</div>
<script>
	var app = new Vue({
        el:"#app",
        data:{
            text:"123,456"
        },
        computed:{
            reverseText:funtion(){
            	return this.text.split(',').reverse().join(',');
        	}
        }
    })
</script>

所有的计算属性都以函数的形式写在 Vue 实例内的 computed 选项内,最终返回计算后的结果。

【注意】虽然我们是以函数的形式书写计算属性的,但是在使用时,不能加()

计算属性的特点

1、计算属性中任意一个实例数据发生变化。计算属性就会重新计算,视图也会更新。

以购物车中的计算总价为例:

<div id="app">
   总价:{{total}}
</div>
var app = new Vue({
    el:"#app",
    data:{
        product:[
            {
                name:"iphone 12",
                price:"7199",
                num:"2"
            },
            {
                name:"LV",
                price:"4888",
                num:"3"
            },
            {
                name:"six god",
                price:"100",
                num:"1"
            }
        ]
    },
    computed: {
        total: function () {
            var price = 0;
            for(var i = 0; i < this.product.length; i++){
                price += this.product[i].num * this.product[i].num
            }
            return price;
        }
    }
})

当购买数量或增删商品时,计算属性就会自动更新,视图中的总结也会随之变化。

2、每一个计算属性都包含一个getter和setter

上面的例子都是计算属性的默认用法,只是利用了getter来读取。每调用一次计算属性,就相当于调用一次getter属性;当计算属性的值发生变化时,会默认调用setter属性,进行相应的操作例如

<div id="app">
    {{fullName}}
</div>
var vm = new Vue({
    el: "#app",
    data: {
        firstName: "尼古拉斯",
        lastName: "赵四",
    },
    computed: {
        fullName: {
            get: function () {
                return this.firstName + "·" + this.lastName
            },
            set:function (value) {
                var arr = value.split("·");
                this.firstName = arr[0];
                this.lastName = arr[1];
            }
        }
    }
})

当我们在控制台执行 app.fullName='弗拉基米尔·普京’时,setter就会被调用。

绝大多数情况下,我们只会用默认的 getter 方法来读取一个计算属性,在业务中很少用到setter,

所以在声明一个计算属性时,可以直接使用默认的写法,不必将getter,setter都声明。

3、计算属性可以依赖多个Vue实例中的数据

<div id="app1"></div>
<div id="app2">
    {{reversedText}}
</div>
<script>
    var app1 = new Vue({
        el: "#app1",
        data: {
            text: "123,456"
        }
    });
    var app2 = new Vue({
        el: "#app2",
        computed: {
            reversedText: function () {
                //这里是依赖app1实例中的数据text
                return app1.text.split(',').reverse().join(',')
            }
        }
    })
</script>

这里我们创建了两个vue实例app1和app2,在app2的计算属性reversedText中,依赖的是app1的数据text,所以当text变化时,实例app2的计算属性也会变化.

计算属性的缓存

其实细心的话就会发现,调用methods里的方法也能实现和计算属性一样的效果,甚至有的方法还能接收参数,使用起来更加的灵活,既然使用methods就可以实现,那为什么还需要计算属性呢?原因就是计算属性是基于依赖缓存的。一个计算属性所依赖的数据发生变化时,他才会重新取值,所以依赖的数据只要不改变。计算属性也就不更新。

举个例子:

<div id="app">
    姓名:{{getName()}}
    年龄:{{getAge()}}
    工作:{{getSay()}}
</div>
var vm = new Vue({
    el: "#app",
    data: {
        name: "葱油饼",
        age: "38",
        say:"宝,我去输液了,什么液,想你的夜"
    },
    methods: {
        getName() {
            console.log("getName执行了")
            return this.name;
        },
        getAge() {
            console.log("getAge执行了")
            return this.age;
        },
         getSay() {
            console.log("getSay执行了")
            return this.say;
        }
    }
})

当我们在控制台,分别修改name,age,say的值时会发现,getName,getAge,getJob都执行了。

vm.name="小王"

也就是说:当修改其中一个属性时,其他属性的值都没改变,但会发现methods里的方法都被执行

现在我们换成计算属性computed试一下、

<div id="app">
    姓名:{{getName}}
    年龄:{{getAge}}
    工作:{{getSay}}
</div>
var vm = new Vue({
    el: "#app",
    data: {
        name: "葱油饼",
        age: "38",
        say:"宝,我去输液了,什么液,想你的夜"
    },
    computed: {
        getName() {
            console.log("getName执行了")
            return this.name;
        },
        getAge() {
            console.log("getAge执行了")
            return this.age;
        },
         getSay() {
            console.log("getSay执行了")
            return this.say;
        }
    }
})

当我们在控制台,分别修改name,age,say的值时会发现,当修改其中一个值的时候,只会执行于其相关的方法。

总结

1).methods方法和computed计算属性,两种方式的最终结果确实是完全相同。

2).不同的是计算属性是基于它们的响应式依赖进行缓存的。

只在相关响应式依赖发生改变时它们才会重新求值,多次访问计算属性会立即返回之前的计算结果,而不必再次执行函数。

3)methods方法,每当触发重新渲染时,调用方法将总会再次执行函数。

4).官网的一句话:对于任何复杂逻辑,你都应当使用计算属性。

2.watch监听

2.1 作用

watch监听器会监听data中数据的变化,只要一变化,就能够执行相应的逻辑

2.2 用法

2.2.1 常用用法

监听的数据名放到这里面作为函数名,这个函数里面有两个参数,一个是新值,一个是旧值

<div id="app">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <h1>全名:{{fullName}}</h1>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstName: '',
            lastName: '',
            fullName: ''
        },
        watch: {
            firstName(newVal, oldVal) {
                console.log(newVal, oldVal)
                this.fullName = newVal + this.lastName
            }, 
            lastName(newVal, oldVal) {
                this.fullName = this.firstName + newVal
            }
        }
    })
</script>

2.2.2 立即执行

当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果在最初绑定值的时候也要执行函数,则就需要用到immediate属性

<div id="app">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <h1>全名:{{fullName}}</h1>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstName: '',
            lastName: '',
            fullName: ''
        },
        watch: {
            firstName(newVal, oldVal) {
                console.log(newVal, oldVal)
                this.fullName = newVal + this.lastName
            }, 
            lastName(newVal, oldVal) {
                this.fullName = this.firstName + newVal
            },
            // 立即执行
        	immediate: true
        }
    })
</script>

2.2.3 深度监听

需要监听复杂数据类型(对象)的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。

<div id="app">
  <!-- 更新对象属性的值 -->
  <input type="text" v-model="person.name" />
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      person: {
        id: 1,
        name: '咸鱼'
      }
    },
    watch: {     
      person: {
        handler(newVal, oldVal) {
          console.log(newVal, oldVal);
        },
        // deep:true 更新对象属性的值,会触发监听
        deep: true,
      }
    }
  })
</script>

如果是要给对象的某个特定的属性加监听器,则可以这样写

watch: {
    //对象的属性名
    "person.name": {
        handler(newVal, oldVal) {
        }
    }
}
与computed比较:
  • 对比computed而言,computed性能更好,所以能用computed实现就用computed实现。
  • 在涉及到异步数据操作的时候,就只能用watch去实现了。

3.过滤器

3.1 基本概念

简单介绍一下过滤器,顾名思义,过滤就是一个数据经过了这个过滤之后出来另一样东西,可以是从中取得你想要的,或者给那个数据添加点什么装饰,那么过滤器则是过滤的工具。

3.2 使用方法

vue中的过滤器分为两种:局部过滤器和全局过滤器

3.2.1 全局过滤器

格式:Vue.filter(“过滤器名称”, 过滤器处理函数)

<div id="app">
    <p>{{ year | formartStr}}</p>
</div>

<script>
    Vue.filter("formartStr", function (value) {
        return value+"年";
    });
    let vue = new Vue({
        el: '#app',
        data: {
            year: "2021"
        }
    });
</script>

使用全局过滤器

{{msg | 过滤器名称}}
:value="msg | 过滤器名称"

3.2.2 局部过滤器

创建一个局部过滤器

给创建Vue实例时传递的对象添加filters属性。

filters: {
    '过滤器名称':过滤器处理函数
}

局部过滤器只能在自定义的那个Vue实例中使用。

<div id="app1">
    <p>{{name | formartStr}}</p>
</div>
<div id="app2">
    <!-- 报错 -->
    <p>{{name | formartStr}}</p>
</div>
let vue = new Vue({
    el: '#app1',
    data: {
        year: "2021"
    },
    filters: {
        "formartStr": function (value) {
            return value+"年";
        }
    }
});

【注意】

1、当全局过滤器和局部过滤器重名时,会采用局部过滤器。

2、过滤器可以串联

<div id="app1">
    <p>{{name | formartStr1 | formartStr2}}</p>
</div>

3、过滤器是 JavaScript 函数,因此可以接收参数

{{ message | filterA(arg1, arg2) }}

上述代码中,filterA的第一个参数是message,第二个参数是‘arg1’,第三个参数是arg2。也就是说,过滤器函数默认第一个参数为 | 前面的内容。

3.3 日期格式化练习

<div id="app">
    <p>{{time | dateFormart("yyyy-MM-dd")}}</p>
</div>
Vue.filter("dateFormart", function (value, fmStr) {
    let date = new Date(value);
    let year = date.getFullYear();
    let month = date.getMonth() + 1 + "";
    let day = date.getDate() + "";
    let hour = date.getHours() + "";
    let minute = date.getMinutes() + "";
    let second = date.getSeconds() + "";
    if(fmStr && fmStr === "yyyy-MM-dd"){
        return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
    }
    return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")} ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}:${second.padStart(2, "0")}`;
});
// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        time: Date.now()
    }
});
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值