概念:基于现有的数据,计算出来的新属性。依赖的数据变化,自动重新计算
语法:
①声明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>
(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>