Vue
Vue指令
V-text/html
作用:修改标签内容
区别:
1.text 内容作为字符串显示
2. html内容作为HTML解析
注意:根据需求,只需要文本就不要用html
V-show/if
作用:控制标签显示隐藏
区别:
1.通过CSS的display来控制属性的显示与隐藏
2.控制显示,不满足条件,删除整个标签。满足条件就加回来
<template>
<div>
<!-- v-show="表达式" -->
<h2>v-show</h2>
<p v-show="age >= 18">成年</p>
<p v-show="age < 18">未成年</p>
<!-- v-if="表达式" -->
<h2>v-if</h2>
<p v-if="age >= 18">按摩</p>
<p v-if="age < 18">打机</p>
</div>
<!-- 区别:
1.v-show 控制显示 通过 display 控制标签显示隐藏
2.v-if控制显示,不满足条件,删除整个标签。满足条件就加回来-->
</template>
export default {
data() {
return {
age: 18,
};
},
};
v-if补充
1.v-if配合v-else使用,必须相邻节点
2.v-if配合v-else-if,可以实现多条件控制,用else结尾,是可选的
<template>
<div>
<!-- if else 必须相邻节点 -->
<h2>if else 配合使用</h2>
<input type="text" v-model="age">
<p v-if="age<18">甜甜圈</p>
<p v-else>快乐水</p>
<!-- if 配合多个 else-if 搭配使用 实现多条件控制 -->
<!-- 用else结尾 是可选的 -->
<h2>IF ELSEIF ELSE配合使用</h2>
<input type="text" v-model="age">
<h3 v-if="age<18">甜甜圈</h3>
<h3 v-else-if="age<50">快乐水</h3>
<h3 v-else>脑白金</h3>
</div>
</template>
export default {
data () {
return {
age:18
}
}
折叠案例
1.给标签设置v-show,值为Vue变量
2.绑定点击事件,拿vue变量做取反
3.收起,隐藏文字用插值表达式,配合三元运算符
<template>
<div>
<h2>折叠案例</h2>
<h3>静夜思 <button @click="toogle">{{show?"收起":"显示"}}</button></h3>
<ul v-show="show">
<li v-for="value in list">{{ value }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
list: [`床前明月光`, `疑是地上霜`, `举头望明月`, `低头思故乡`],
show: true,
};
},
methods: {
toogle() {
this.show = !this.show;
},
},
};
</script>
v-for和KEY的一些理论概念
第一个问题:
1.当v-for数组变化,页面会更新吗?
2.所有数组方法都会造成v-for更新吗?
结论:有些会,有一些不会
本质:
1.数组方法只要修改了原数组,就会触发页面的刷新
2.如果数组方法不会修改原始数组而是返回新数组,就不会触发页面更新,采用this.$set()方法
第二个问题
1.当数组变化了,v-for是如何更新DOM的?
2.和原生的JS有什么区别
结论:
1.v-for采用的是一种就地更新机制(Vue在数组中会把数组修改后,直接把整个列表拿出来,在原来的基础上修改数据,原地修改)
2.造成了元素没动过位置,数据改了而已
本质:每次渲染之前,Vue生成虚拟DOM,描述结构,当数据变化再生成一个虚拟DOM进行对比
作用:
1**.虚拟DOM是一个JS对象**,保存DOM信息,这样就能提高DOM更新的性能。
2.不频繁操作真实DOM,在内存中找到变化部分,再更新真实DOM
第三个问题
1.v-for中的key有什么作用?
结论:
1.性能提升
2.当key值为索引时,还是就地更新机制
3.当key值为id(唯一不重复的字符串或数字)时,不采用就地更新机制
动态设置类名
语法: :class"{类型:布尔值}",true就添加类,false去除类
细节:
1.布尔值灵活,可以是变量
2.如果类型想要用横杆的形式,要加双引号
<p :class="{ color: false }">虹色</p>
<p :class="{ 'backgorund-color': ison }">变量控制</p>
<button @click="ck">点击控制</button>
动态设置样式
语法::style"{属性名='值'}"
细节:
1.属性名是横杆样式时,用小驼峰,如果还想用横杆,用双引号
2.值是灵活的
<p :style="{ color: 'red' }">红色</p>
<p :style="{ color: blue }">红色</p>
<p :style="{backgroundColor:'pink'}">粉色背景</p>
<p :style="{'font-size':'40px'}">我用横杆引起来的</p>
过滤器
作用:转换格式,过滤器就是一个函数,传入值返回处理后的值
<template>
<div>
<p>{{ msg | reverseFn(`$`) }}</p>
<p :title="`翻转一下` | reverseAA">可以翻转吗</p>
</div>
</template>
<script>
export default {
data() {
return {
msg: "HELLO WORLD",
};
},
filters: {
reverseFn(value, unit=``) {
return value.split("").reverse().join("") + `${unit}`;
},
},
};
</script>
细节:
1.过滤器只能用在: 插值表达式和v-bind动态属性里
2.声明的是方法,生命在data方法同级的filters对象中
3.value指的就是表达式的值,后面参数可以继续拼接
4.全局设置过滤器:Vue.filert(''过滤器名'',方法(value))注意return返回值
5.可以同时使用多个过滤器
补充:
1.过滤器使用与数组翻转,会导致原数组变化,然后表达式中 再翻转 无限递归
2.加slice 不会修改原数组 就不会无限递归
计算属性
作用:
1.元素JS计算求和,当计算值改变,和不会随之变化。Vue给出了一种方法
2.根据一些数据计算出一个属性
<input type="text" v-model.number="a">
<h1>{{sum}}={{a}}+{{b}}</h1>
<script>
export default {
data () {
return {
a:10,
b:20
}
},
computed: {
sum(){
return this.a + this.b
}
}
}
</script>
细节:
1.计算属性依赖数据的变化,数据变化,计算属性就会重新运行
2.如果计算属性不依赖数据的变化,就会读取缓存中的数据
3.计算属性也是Vue变量,不要和data里重名
4.变量作为一个方法,声明在于data同级的computed对象里
5.记得要return 一个值
好处:
计算属性带数据缓存
使用场景:当变量值,其他变量计算而得来的
品牌管理系统案例
1.安装bootstrap,导入包
import 'bootstrap/dist/css/bootstrap.css'
2.数据驱动视图
<tr v-for="(value, index) in list" :key="value.id">
<th scope="row">{{ value.id }}</th>
<td>{{ value.name }}</td>
<td>{{ value.price }}</td>
<td>{{ value.time | momentFix }}</td>
<td>
<button type="button" class="btn btn-link">
删除
</button>
</td>
</tr>
3.大于100显示红色字体价格
<td :class="{ onColor: value.price > 100 }">{{ value.price }}</td>
4.绑定点击事件,数组插入数据
<button type="submit" class="btn btn-primary" @click.prevent="add">
添加资产
</button>
add() {
if (!this.placeholderName || !this.placeholderPrice) {
return;
}
this.list.push({
id:this.list[this.list.length - 1].id + 1
name: this.placeholderName,
price: this.placeholderPrice,
time: new Date(),
});
5.绑定事件,点击删除(获取索引下标,删除数组)
<button type="button" class="btn btn-link" @click="del(index)">删除</button>
del(index) {
this.list.splice(index, 1);
},
6.删除完,显示一个暂无数据标签(v-show)
<tfoot v-show="list.length===0">
<tr>
<td class="text-center" colspan="5">暂无数据</td>
</tr>
</tfoot>
7.删除完,添加报错(id是依赖数组长度,现在数组长度为undefined),做判断
let id
if(this.list,length>0){
id=this.list[this.list.length - 1].id + 1
}else{
id=100
}
8.计算总价,均价
<td colspan="2">总价:{{ allSum }}</td>
<td colspan="2">均价:{{ avg }}</td>
computed: {
allSum() {
let sum = 0;
this.list.forEach((value) => {
sum += value.price;
});
return sum;
},
avg() {
let avg = 0;
// 这里拿的是 allSum 不是 sum
avg = this.allSum / this.list.length
return avg
},
},
9.格式化事件(导入moment模块包),使用过滤
import moment from "moment";
filters: {
momentFix(value) {
return moment(value).format(`YYYY-MM-DD HH:mm:ss`);
},
},
练习
导航项目
1.动态添加类名,以index作为判断条件
2.遍历数据,渲染列表
3.点击传入index
4.声明一个变量,关联index 与index做判断
<span
@click="add(index)"
:class="{ active: index===checkindex }"
v-for="(value, index) in arr"
:key="value.first_id"
>{{ value.first_name }}</span>
<script>
export default {
data() {
return {
checkindex: 0,
arr: [...],
};
},
methods: {
add(index) {
console.log(index);
this.checkindex = index;
},
},
};
</script>
学员管理
1.双向绑定表单值
2.添加空数组,渲染列表
3.绑定点击事件,数组插入新数据
4.删除功能,获取下标
5.编辑功能,声明两个变量 一个判断按钮是添加或编辑 一个获取选中下标
<input type="text" v-model="userName" />
<input type="number" v-model="age" />
<select v-model="sex">
<option value="男">男</option>
<option value="女">女</option>
<select>
<button @click="add(indexAdd)">添加/修改</button>
<tr v-for="(value, index) in arr" :key="value.id">
<td>{{ value.id }}</td>
<td>{{ value.userName }}</td>
<td>{{ value.age }}</td>
<td>{{ value.sex }}</td>
<td>
<button @click="del(index)">删除</button>
<button @click="updata(index)">编辑</button>
</td>
</tr>
<tr v-show="arr.length === 0">
<td class="text-center" colspan="5">暂无数据</td>
</tr>
<script>
export default {
data() {
return {
indexAdd: 0,
checkUpdata: false,
// 编辑想要联系 声明的变量 要在data返回对象中设置
userName: "",
age: "",
sex: "男",
arr: [],
};
},
methods: {
add(indexAdd) {
if (!this.userName || !this.age || !this.sex) {
alert(`请输入内容`);
return;
}
let id;
if (this.arr.length > 0) {
id = this.arr[this.arr.length - 1].id + 1;
} else {
id = 1;
}
if (this.checkUpdata === false) {
this.arr.push({
id,
userName: this.userName,
age: this.age,
sex: this.sex,
});
this.userName = "";
this.age = "";
this.sex = "";
} else {
this.checkUpdata = false;
this.arr[indexAdd].userName = this.userName;
this.arr[indexAdd].age = this.age;
this.arr[indexAdd].sex = this.sex;
this.userName = "";
this.age = "";
this.sex = "";
}
},
del(index) {
this.arr.splice(index, 1);
},
updata(index) {
this.indexAdd = index;
this.checkUpdata = true;
this.userName = this.arr[index].userName;
this.age = this.arr[index].age;
this.sex = this.arr[index].sex;
},
},
};
</script>