前端基础之《Vue(3)—计算属性》

一、computed选项

1、计算属性
语法:在computed选项中,定义计算属性方法,在方法体使用声明式变量进行若干计算。

2、计算属性一定是个函数。一定有返回值。

3、计算属性的作用
(1)用于优化指令的表达式,当指令的表达式比较复杂,我们建议使用计算属性来优化,提升视图模板中代码的可阅读性、可维护性。
(2)用于缓存一个复杂的计算,避免组件更新时产生没有必要的损耗。
(3)计算属性本质上是一个函数,vue会分析函数体中使用到了哪些声明式变量,有且仅有这些声明式变量发生变化时,计算属性才会重新执行。

二、例子

<html>
<head>
    <title>计算属性</title>
    <style>
        [v-cloak] {display: none;}
    </style>
    
</head>
<body>
    <div id="app">
        <h1 v-text='("总价:" + "¥" + (num*price).toFixed(2))'></h1>
        <h1 v-text='total'></h1>
        <hr>
        <h1 v-text='Math.random() * count'></h1>
        <h1 v-text='random'></h1>
        <hr>
        <button @click="test">用代码访问计算属性</button>
        <hr>
        <h1 v-text='total2'></h1>
        <hr>
        Firstname:<input type="text" v-model='firstname' />
        Lastname:<input type="text" v-model='lastname' />
        <h1 v-cloak>全名:<input type="text" v-model='fullname' /></h1>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                num: 1,
                price: 10,
                count: 100,
                firstname: '张',
                lastname: '兰兰'
            },
            methods: {
                test() {
                    console.log('---total', this.total)
                    this.total = 100
                }
            },
            computed: {
                //计算属性一定要有返回值
                total() {
                    //做一切可以做的复杂计算
                    const res = (this.num * this.price)
                    const tt = res.toFixed(2)
                    return '总价:¥' + tt
                },
                random() {
                    return Math.random() * this.count
                },
                total2: { //用对象的写法
                    get() {
                        return (this.num * this.price).toFixed(2)
                    },
                    set(newVal) {
                        this.price = newVal
                        return (this.num * this.price).toFixed(2)
                    }
                },
                fullname: {
                    get() {
                        return this.lastname + "*" + this.firstname
                    },
                    set(val) {
                        if (val.indexOf('*') === -1) {
                            throw new Error('字符串必须用*号分割')
                        }
                        const arr = val.split('*')
                        this.lastname = arr[0]
                        this.firstname = arr[1]
                    }
                }
            }
        })

    </script>
</body>
</html>

1、计算属性可以将复杂的表达式封装起来
要求把金额前加上人民币符号,金额带2位小数

直接写,就是一个很复杂的表达式:

<h1 v-text='("总价:" + "¥" + (num*price).toFixed(2))'></h1>

调用计算属性方法(当做变量来使用),就很方便:

<h1 v-text='total'></h1>
computed: {
    //计算属性一定要有返回值
    total() {
        //做一切可以做的复杂计算
        const res = (this.num * this.price)
        const tt = res.toFixed(2)
        return '总价:¥' + tt
    }
}

2、计算属性可以避免更改一个变量时,另一个值也变了
组件更新时,页面复杂的计算也重新计算了
我更新app.price = 2,此时页面上:<h1 v-text='Math.random() * count'></h1>也会更新
用计算属性:<h1 v-text='random'></h1>就不会变化

3、控制台可以直接访问计算属性
app.total
app.random

4、计算属性默认只支持get操作
如果尝试在点击事件里设置计算属性的值

test() {
	console.log('---total', this.total)
	this.total = 100
}

报错信息:

[Vue warn]: Computed property "total" was assigned to but it has no setter.

(found in <Root>)

报错计算属性被修改,但是它没有setter

5、在视图模板中把计算属性直接当作变量直接使用,在vue逻辑代码使用this访问计算属性,默认只有get功能

6、如何让计算属性同时支持get/set功能呢
计算属性默认是一个函数,表示get功能。为了支持set,要把计算属性写成对象结构。

total2: { //用对象的写法
    get() {
        return (this.num * this.price).toFixed(2)
    },
    set(newVal) {
        this.price = newVal
        return (this.num * this.price).toFixed(2)
    }
}

原先页面显示:

<h1 v-text='total2'></h1>

修改app.total2 = 3,页面自动变为了

7、问题:计算属性能不能绑定在v-model上
可以,计算属性要有set功能,拆成get/set写法。因为v-model是双向绑定,可以获取也可以设置。

Firstname:<input type="text" v-model='firstname' />
Lastname:<input type="text" v-model='lastname' />
<h1 v-cloak>全名:<input type="text" v-model='fullname' /></h1>
fullname: {
    get() {
        return this.lastname + "*" + this.firstname
    },
    set(val) {
        if (val.indexOf('*') === -1) {
            throw new Error('字符串必须用*号分割')
        }
        const arr = val.split('*')
        this.lastname = arr[0]
        this.firstname = arr[1]
    }
}

8、问题:计算属性能计算哪些性质的变量呢
除了可以计算data、vuex数据、$route路由数据等,还可以计算一切带有__ob__的数据。

经常拿计算属性来计算状态管理vuex中的数据,route路由url数据。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值