Vue——计算属性

发布时间:2024年01月21日

计算属性

概念:基于现有的数据,计算出来的新属性。依赖的数据变化,自动重新计算
语法:
①声明computed配置项中,一个计算属性对应一个函数
②使用起来和普通属性一样使用{{ 计算属性名 }}
(平时声明属性是往data中放的,现在要往对应的computed中放👇)

<script>
	computed:{
		计算属性名 () {
			基于现有数据,编写求职逻辑
		return 结果
		}
</script>

计算属性 → 可以将一段求值的代码进行封装(所以写的时候千万不要忘记return

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h3>物品清单</h3>
        <table>
            <tr>
                <th>名字</th>
                <th>数量</th>
            </tr>
            <tr v-for="(item,index) in list" :key="item.id">
                <td>{{ item.name }}</td>
                <td>{{ item.num }}</td>
            </tr>
        </table>

        <p>礼物总数 {{ totalCount }}个</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data:{
                //现有数据
                list:[
                    {id:1,name:'篮球',num:1},
                    {id:2,name:'玩具',num:2},
                    {id:3,name:'铅笔',num:5},
                ]
            },
            computed:{
                totalCount(){
                    //基于现有的数据,编写求职逻辑
                    //计算属性函数内部,可以直接通过this 访问到 app 实例
                    //需求:对 this.list 数组里面的 num 进行求和 → reduce
                   let total = this.list.reduce((sum,item) => sum+item.num,0)// 0 是求和的起始值,会先给到sum 
                    return total
                }
            }
        })
    </script>
</body>
</html>

computed 计算属性 vs methods 方法

(1)computed 计算属性
作用:封装了一段对于数据的处理,求得一个结果
语法
①写在computed配置项中
②作为属性,直接使用 → this.计算属性 {{ 计算属性 }}

缓存特性(提升性能)👇
计算属性会对计算出来的结果缓存,再次使用直接读取缓存,依赖项变化了,会自动重新计算 → 并再次缓存

(2)methods方法
作用:给实例提供一个方法,调用以处理业务逻辑
语法
①写在methods配置项中
②作为方法,需要调用 → this.方法名 {{ 方法名( ) }} (因为是方法,所以用起来是要调用的)
除非配合着事件,相当于帮你调用 → @事件名=“方法名”
在这里插入图片描述

用方法:
methods:{
	totalCountFn () {
		console.log('methods方法执行了')
		let total = this.list.reduce((sum,item) => sum+item.num,0)
        return total
    }
}

算完一个又算一次,是没有缓存的
在这里插入图片描述

计算属性完整写法

Q:上一点我们是访问计算属性,那么应该也能修改了?
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        姓:<input type="text" v-model="firstName">+
        名:<input type="text" v-model="lastName">=
        <span>{{ fullName }}</span>

        <button @click="changeName">改名卡</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data:{
                firstName:'刘',
                lastName:'备',
            },
            methods:{
                changeName(){
                    this.fullName='周心悦'//会传给我们当前 set 方法的形参:value
                }
            },
            computed:{
                //简写 → 获取,没有配置设置的逻辑
                //fullName(){
                //    return this.firstName  + this.lastName
                //}

                //完整写法 → 获取 + 设置
                fullName:{
                    //(1)当fullName计算属性,被获取求值时,执行get(有缓存)
                    //   会将返回值作为求值的结果
                    get (){
                        return this.firstName + this.lastName
                    },
                    //(2)当fullName计算属性,被修改赋值时,执行set
                    //     修改的值,传递给set方法的形参
                    set (value){
                        //改名卡的用法时,把输入的姓名拆分,分别给“姓”和“名”
                        this.firstName=value.slice(0,1)
                        this.lastName=value.slice(1)
                    }
                }
            }
        })
    </script>
</body>
</html>

综合案例:成绩案例

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div class="table">
            <table>
                <thead>

                </thead>

                <tbody v-if="list.length > 0">
                    <tr v-for="(item,index) in list" :key="item.id">
                        <td>{{ index +1 }}</td><!-- 为保证序号连续,推荐使用index -->
                        <td>{{ item.subject }}</td>
                        <!-- 需求:不及格的要标红,及<60,加上red类 -->
                        <td :class="{ red:item.score<60 }">{{ item.score }}</td>
                        <td><a @click.prenvet="del(item.id)" href="#">删除</a></td>
                    </tr>

                </tbody>

                <tbody v-else>
                    <tr>
                        <td colspan="5">
                            <span class="none">暂无数据</span>
                        </td>
                    </tr>
                </tbody>

                <tfoot>
                    <tr>
                        <td colspan="5">
                            <span>总分:{{ totalScore }}</span>
                            <span style="margin-left: 50px;">平均分:{{ averageScore }}</span>
                        </td>
                    </tr>
                </tfoot>
            </table>

        </div>
        <div class="form">
            <div class="form-item">
                <div class="label">科目:</div>
                <div class="input">
                    <input type="text" placeholder="请输入科目" v-model.trim="subject">
                </div>
            </div>
            <div class="form-item">
                <div class="label">分数</div>
                <div class="input">
                    <input type="text" placeholder="请输入分数" v-model.number="score">
                </div>
            </div>
            <div class="form-item">
                <div class="label"></div>
                <div class="input">
                    <button @click="add" class="submit">添加</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data:{
                list:[
                    { id: 1,subject:'语文', score:20},
                    { id: 7,subject:'数学', score:90},
                    { id: 12,subject:'英语', score:70},
                ],
                subject:'',
                score:''
            },
            computed:{
                totalScore(){
                    return this.list.reduce((sum,item) => sum + item.score,0)
                },
                averageScore (){
                    if(this.list.length === 0){
                        return 0
                    }
                    return (this.totalScore/this.list.length).toFixed(2)
                }
            },
            methods:{
                del(id){
                    //相同的移出,不相同的保留
                    this.list = this.list.filter(item =>item.id !== id)
                },
                add(){
                    if(!this.subject){
                        alert('请输入科目')
                        return
                    }
                    if(typeof this.score !== 'number'){
                        alert('请输入正确的成绩')
                        return
                    }
                    //往前面加
                    this.list.unshift({
                        id: +new Date(),
                        subject:this.subject,
                        score:this.score
                    })

                    this.subject=''
                    this.score=''
                }
            }
        })
    </script>
</body>
</html>

在这里插入图片描述

文章来源:https://blog.csdn.net/AYBBZXY/article/details/135729680
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。