vue指令
v-model
作用:给表单元素使用,双向数据绑定 语法:v-model='变量' 注意:变量生命在data中
v-model修饰符
- .number转数字,以parseFloat转成数字类型
- .trim去除首尾空白字符(包括空格、换行、tab)
- .lazy在change时触发而非input时
<template>
<div>
用户名<input type="text" v-model.trim="user.name" />
密码:<input type="password" v-model.lazy="user.password" />
年龄:<input type="number" v-model.number="user.age" />
<button @click="login">登陆</button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
user: {
name: "",
password: "",
age: "",
},
},
},
methods: {
login() {
console.log(this.user.name, this.user.password, this.user.age);
},
},
};
</script>
-v-text和v-html
作用:更新元素的innerText、innerHTML 语法:
- v-text="值"
- v-html="值"
区别:
- v-text 不解析标签,相当于innerText
- v-html 解析标签,相当于innerHTML
-v-for
作用:可以遍历 数组 或者 对象,用于渲染结构
- 遍历数组语法:
- v-for="item in 数组名"
- v-for="(item, index) in 数组名"
- 遍历对象语法:
- v-for = "(value, key) in 对象名"
- 遍历数字
- v-for = "item in 数字"
vue的就地复用策略
定义:Vue会尽可能的就地(同层级,同位置)对比虚拟dom,复用旧dom结构,进行差异化更新。 简单理解:只改内容,不变标签,除非需要加减标签 好处:可以提升性能,更新高效!
虚拟Dom
定义:是一个js对象,主要保存标签信息 注意:每次数据变化都会生成新的虚拟Dom 作用:真实的Dom结构复杂,逐一对比消耗性能,虚拟Dom对比性能比较高,对比出变化的部分,只更新变化内容,减少dom操作,提升性能
diff算法
定义:虚拟DOM算法,又称VDOM算法
- 同层级根元素先比较
- 如果根元素变了,删除重建dom树
- 如果根元素没变,先对比对比属性。再对比子元素
- 兄弟元素比较
- 默认按照下标,逐一对比复用
- 如果设置了key,就会优先按照相同key的元素进行比较复用
- key的作用
- 如果列表提供了key,列表就按key对比
- key主要是在列表顺序可能变化的场景可以大幅提升性能
- key的要求
- 在当前列表必须是唯一的
- key是不变的
- 一般来说,key类型是数字或者字符串
- 一半使用id作为key
动态设置class 和 style
class
语法::class="对象/数组"
- 对象:键是属性名,值是布尔值,true则添加,false则删除
- 数组:数组中所有的类,都会添加到盒子上
- 带横杠的类名,加引号。如:'text-center'
:class 对于类名操作的增加,不会影响到原来的 class 属性
style
语法::style="对象/数组
- 对象:键是属性名,值是属性值
- 数组:里面都是对象
- 带横杠的属性名
- 用小驼峰命名法
- 用引号
使用场景
- 优先使用class,方便复用、维护
- 如果样式不确定,比如接口下发,这种时候一般用style
成绩管理案例
思路
- 列表显示
- v-for
- 不及格要标红
- 动态样式绑定
- 删除,v-for里传参数
- array.findIndex
- 查找索引
- array.findIndex
- 添加
- 阻止默认行为
- .number修饰符
<template>
<div class="container">
<!-- 渲染 -->
<div class="row">
<div class="col-12 pt-3">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">编号</th>
<th scope="col">科目</th>
<th scope="col">分数</th>
<th scope="col">考试时间</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="i in list" :key="i.id">
<th scope="row">{{ i.id }}</th>
<td>{{ i.subject }}</td>
<td :style="{ color: i.score < 60 ? 'red' : '' }">
{{ i.score }}
</td>
<td>{{ format(i.exameTime) }}</td>
<td>
<button type="button" class="btn btn-link" @click="del(i.id)">
删除
</button>
</td>
</tr>
<!-- 计算属性 -->
<tr class="bg-light">
<th scope="row">统计</th>
<td colspan="2">总分:{{ getSum }}</td>
<td colspan="2">平均分:{{ getAverage }}</td>
</tr>
</tbody>
<tfoot v-show="false">
<tr>
<td class="text-center" colspan="5">
暂无数据
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<!-- 添加 -->
<form class="row align-items-center">
<div class="col-3">
<input
type="text"
class="form-control"
placeholder="科目"
v-model="subjectAdd"
/>
</div>
<div class="col-3">
<input
type="text"
class="form-control"
placeholder="分数"
v-model.number="scoreAdd"
/>
</div>
<div class="col-3">
<button type="submit" class="btn btn-primary" @click.prevent="add">
添加成绩
</button>
</div>
</form>
</div>
</template>
<script>
// 第三方包,哪里使用,哪里调用
import moment from "moment";
export default {
name: "App",
data() {
return {
list: [
{
id: 1,
// 科目
subject: "语文",
// 成绩
score: 56,
// 考试时间
exameTime: new Date(),
},
{
id: 2,
subject: "数学",
score: 100,
exameTime: new Date(),
},
],
subjectAdd: "",
scoreAdd: "",
};
},
methods: {
del(id) {
const index = this.list.findIndex((value) => value.id === id);
this.list.splice(index, 1);
},
add() {
const last = this.list[this.list.length - 1];
this.list.push({
id: last ? last.id + 1 : 100,
subject: this.subjectAdd,
score: this.scoreAdd,
exameTime: new Date(),
});
this.subjectAdd = "";
this.scoreAdd = "";
},
format(time) {
return moment(time).format("YYYY-MM-DD HH:mm:ss");
},
},
// 计算属性
computed: {
getSum() {
return this.list.reduce((pre, value) => pre + value.score, 0);
},
getAverage() {
return (this.getSum / this.list.length).toFixed(2);
},
},
};
</script>
<style scoped>
</style>