笔记目录
小概
本章的学习内容:vue指令补充(v-if,v-show,v-cloak,v-once,v-pre,key值使用),数组遍历进阶(map,filter,firEach,some,every,findIndex方法,reduce方法),vue计算属性与过滤器。
1. vue指令补充
1.1 v-if指令
作用:根据条件渲染元素
语法:v-if = “值”
注意点:v-else-if 前面要有v-if 或 v-else-if
<!-- HTML结构 -->
<div id="app">
<input type="text" placeholder="请输入你的分数" v-model.number.lazy="score">
<p v-if="score >= 90">考的很棒,被奖励卷黄冈密卷</p>
<p v-else-if="score >= 80">考的不错,被带去游乐园一日游</p>
<p v-else-if="score >= 60">有待进步,周末游戏时间减半</p>
<p v-else>被一顿胖揍</p>
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
score: '',
}
})
</script>
1.2 v-show指令
作用:设置元素的display属性
语法:v-show=“值”
<!-- HTML结构 -->
<div id="app">
<p v-if="score>=60">我是v-if渲染的数据</p>
<p v-show="score>=60">我是v-show渲染的数据</p>
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
score: 50,
}
})
</script>
v-if和v-show 的区别:
v-if:根据条件渲染元素(不满足条件是不会加载到dom树上)
v-show:元素一定会渲染,只是根据条件设置display值
应用场景:如果需要频繁的去切换显示与隐藏,就使用v-show,如果状态不频繁改变可以使用v-if(频繁的切换如果使用v-if,就需要频繁的去加载dom树渲染,耗性能)。
1.3 v-cloak指令
作用:设置vue在渲染之前的默认样式
语法: v-cloak
注意点:使用v-cloak指令,必须要在style中设置样式 [v-cloak]{ }
原理:本质其实就是一个属性选择器,当vue没有渲染的时候,默认加载选择器样式,vue完成渲染后,移除v-cloak属性即可
使用场景:使用不多,页面比较复杂的时候,vue在渲染之前用户可能会看到模板语法一下体验
。就可以使用v-cloak设置渲染之前的样式。
<style>
[v-cloak] {
/* display: none; */
color: red;
}
</style>
</head>
<body>
<!-- HTML结构 -->
<div id="app">
<p v-cloak>{{ msg }}</p>
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
msg: '张三!'
}
})
</script>
1.4 v-once指令
作用:让元素只被vue渲染一次
语法:v-once
<!-- HTML结构 -->
<div id="app">
<p>我没有用v-once : {{ msg }}</p>
<p v-once>我使用v-once : {{ msg }}</p>
<button @click="msg='我是修改的msg'">点我修改msg</button>
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
msg: '我是彭于晏',
}
})
</script>
1.5 v-pre指令
作用:让vue不要渲染
语法:v-pre
应用场景:vue教程类网站,我希望用户可以看到语法.但是默认情况下语法会被vue渲染。 如果希望用户看到vue的原始语法,就可以使用v-pre指令跳过渲染过程。
<!-- HTML结构 -->
<div id="app">
<p>我没有使用v-pre : {{ msg }}</p>
<p v-pre>vue的差值表达式语法是: {{ msg }}</p>
<p v-pre>使用v-pre : {{ msg }}</p>
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
msg: '我是胡歌',
}
})
1.6 vue中key值使用
key值:给元素添加一个身份证,便于vue可以更准确的识别
原因:vue在渲染的时候,可能会出现一些bug。(渲染出错)
语法::key = “值” 这种写法使用了v-bind绑定data中的数据
使用场景:key值一般用于v-for 和 v-if
- v-if实现元素切换的时候,有可能会出现渲染bug
- v-for渲染数组的时候,长度长度变化也有可能产生渲染bug
<!-- HTML结构 -->
<div id="app">
<button @click="flag=!flag">邮箱/手机号</button>
<div v-if="flag" key="phone">
<input type="text" placeholder="请输入邮箱" />
<input type="text" placeholder="请输入密码" />
</div>
<div v-else >
<input type="text" placeholder="请输入手机号" />
<input type="text" placeholder="请输入验证码" />
</div>
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
flag:true
}
})
</script>
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误(官方原话)。
2. 数组遍历进阶
一些Array内置的api方法
2.1 map遍历
作用:以某种关系映射数组每一个对象,生成一个新数组
场景:
- 映射关系:数组每一个元素*2
- 映射关系:数组每一个元素+1
- 映射关系:数组超过100元素,除以2
语法注意点: arr.map(value,index)=>{})
- 循环次数 == 数组长度
- 回调函数返回值 (代表每一个元素映射之后的结果,注意:
一定要return,否则新数组每个元素都是undefined
)- 迭代方法本身返回值 (返回映射之后的
新数组
)
<script>
let arr = [23, 31, 60, 88, 90, 108, 260]
//1.1 需求1: 全场8.8折
// let newArr = arr.map((value,index)=>{
// return value*0.88
// });
//使用了箭头函数,函数体只有一行可以省略大括号与return
let newArr = arr.map((value, index) => value * 0.8)
console.log(newArr)
//1.2 需求2: 100满减50
let newArr1 = arr.map((value, index) => {
if (value >= 100) {
return value - 50
} else {
return value
}
})
console.log(newArr1)
</script>
2.2 filter遍历
作用:过滤数组,找出符合条件的所有元素,放入新数组中(返回一个满足条件的 新数组)
场景:
- 找出数组中所有的偶数
- 找出价格超过100的商品
语法点注意:arr.filter((value,index)=>{ })
- 循环次数 == 数组长度
- 回调函数返回值
return true:符合过滤条件,放人新数组中
return false:不符合过滤条件,不放入新数组中- 迭代方法本身返回值
*返回符合过滤条件所有元素(新arrr
)
<script>
let arr1 = [20,11,30,35,60,88,90];
// let res1 = arr1.filter((value,index)=>{
// console.log(index,value);
// if( value % 2 == 0){
// return true;
// }else{
// return false;
// }
// });
//简写
let res1 = arr1.filter(value=>value%2==0)
console.log( res1 );
let arr2 = [
{
name:'小米手机',
price:1800
},{
name:'卫龙',
price:3.5
},{
name:'咪咪',
price:3
},{
name:'电脑',
price:8000
},
];
let res2 = arr2.filter(value=>value.price<100);
console.log(res2);
</script>
2.3 forEach遍历
作用:相当于for循环的另一种写法(不同点,for是一种语法,foreach是一个数组方法)
场景:遍历对象更加方便
<script>
let arr1 = [20,11,30,35,60,88,90];
arr1.forEach((value,index)=>{
console.log(value,index);
});
</script>
foreach()不会返回一个新的数组,在遍历中的操作会直接对原数组操作,map()和filter()都会返回一个新的arr,不会修改原数组。
2.4 some遍历
作用:
判断数组中是否有元素满足条件
场景:判断数组有无负数
语法注意点:arr.some((value,index)=>{ })
- 循环次数 != 数组长度
- 回调函数返回值
return true: 找到了。 循环结束,此时迭代方法本身也返回true
return false:没有找到。 循环继续。如果循环走完了还是没有返回true,则此时迭代方法默认返回false.- 迭代方法本身返回值
*返回布尔类型
<script>
let arr = [20,11,30,-35,60,88,90];
// let res = arr.some((value,index)=>{
// if( value < 0 ){
// return true;
// }else{
// return false
// };
// });
//简写
let res = arr.some(value=>value<0);
console.log( res );//true:有负数 false:没有
</script>
2.5 every遍历
作用:
判断数组中是否所有元素都满足条件
场景:判断数组是不是都是正数
语法注意点:arr.every((value,index)=>{})
- 循环次数 != 数组长度
- 回调函数返回值
return true: 满足条件,循环继续。 循环走完了还是没有false,此时迭代方法默认返回true
return false:不满足条件,循环结束。此时迭代方法返回值就是false- 迭代方法本身返回值
*返回布尔类型
let arr = [20,11,30,-35,60,88,90];
// let res = arr.every((value,index)=>{
// if( value > 0){
// return true;
// }else{
// return false;
// }
// });
let res = arr.every(value=>value>0);
console.log( res );//true:所有元素都是正数 false:有负数
2.6 数组findIndex方法
作用:
查找数组中第一个符合条件的元素下标
场景:一般用于数组中是对象类型查找,比for循环高效
语法:arr.findIndex((value,index)=>{
return true;//找到了,循环结束。此时迭代方法会返回当前index
return false;//没找到,循环继续。直到遍历结束还没有找到,返回固定值-1
})
返回值:满足条件的下标 / -1
let arr = [
{
name:'张三',
age:22
},
{
name:'李四',
age:20
},
{
name:'王五',
age:25
},
];
// //找未成年
// let res = arr.findIndex((value,index)=>{
// if(value.age < 18){
// return true;//找到了,循环结束。此时迭代方法会返回当前index
// }else{
// return false;//没找到,循环继续。直到遍历结束还没有找到,返回固定值-1
// };
// });
let res = arr.findIndex(value=>value.age<18);
console.log(res);
2.7 数组reduce方法
作用:为数组中每一个元素执行一次回调函数
场景:求数组累加和/平均值/最大值/最小值
语法:arr.reduce( (累加器,当前元素,当前下标)=>{ return 下一次累加器值 } , 初始值 )
- 第一个参数: 回调函数
- 第二个参数,初始值(如果不设置初始值,sum默认会是数组第一个元素,此时空数组就会报错)
- 迭代方法本身返回值:
最后一次累加器的结果
注意点: 一定要设置reduce方法的初始值,否则空数组就会报错
let arr = [20,25,30,34,45];
/*
sum : 初始值(累加器),默认数组第一个元素
value: 数组每一个元素,默认第二个元素
index: 数组每一个元素下标,默认1
*/
// let res = arr.reduce((sum,value,index)=>{
// console.log(sum);
// console.log(value);
// console.log(index);
// return sum + value;//相当于给下一次循环的sum赋值, sum = sum + value
// },0);
let res = arr.reduce((sum,value)=>sum+value,0)
console.log( res );//最后一次迭代的sum值
let res1 = arr.reduce((sum,value)=>Math.max(sum,value),0);
console.log(res1);
3. vue计算属性与过滤器
3.1 vue的计算属性
计算属性的作用:
vue中的data数据,有时候在渲染的时候。不是直接渲染,而是经过一些处理。这个时候就会导致模板语法变得冗余。解决渲染冗余问题
计算属性语法:
- 在vue实例的computed对象中添加一个 函数(计算属性的属性名)
- 在计算属性函数中return 返回值 (计算属性的属性值)
计算属性的注意点:
- 计算属性应该写在vue实例的computed成员中
- 计算属性是一个函数,它的值就是这个函数的返回值
计算属性的缓存功能:
- 当第一次访问计算属性的时候,这个函数会被调用一次。之后vue就把返回值缓存起来。
- 第二次访问计算属性,vue不会调用这个函数,而是直接从缓存读取
- 当计算属性内部的数据变化了,计算属性才会重新计算,然后放入缓存
<!-- HTML结构 -->
<div id="app">
<p>{{ msg }}</p>
<h2>反转字符串</h2>
<p>{{ reverseMsg }}</p>
<p>{{ reverseMsg }}</p>
<p>{{ reverseMsg }}</p>
<p>{{ reverseMsg }}</p>
<p>{{ reverseMsg }}</p>
<p>{{ reverseMsg }}</p>
<p>{{ reverseMsg }}</p>
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//1.el:挂载点
el: '#app',
//2.data: 要渲染的数据
data: {
msg: '我爱敲代码',
},
//3.methods:事件处理函数
methods: {
},
//4.computed : 计算属性
computed:{
reverseMsg(){
return this.msg.split('').reverse().join('');
}
}
})
</script>
3.2 计算属性的set和get方法
计算属性作用:解决数据渲染冗余问题
计算属性语法:
- 在vue实例的computed对象中添加一个函数
- 在这个函数中返回值
计算属性特点:缓存
*计算属性默认只会调用一次,之后访问会从缓存读取。 只有当计算属性中的data变化,才会重新计算
注意点:
- 计算默认只能读取,不能修改。 否则程序会报错。
- 如果希望计算属性可以修改,则需要添加set方法
<!-- HTML结构 -->
<div id="app">
<input type="text" placeholder="请输入全名" v-model="fullName">
<br>
<input type="text" placeholder="请输入姓氏" v-model="firstName">
<br>
<input type="text" placeholder="请输入名字" v-model="lastName">
</div>
<script>
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
firstName:'',
lastName:'',
},
computed:{
/*
fullName(){} : 函数写法。 计算属性默认就是get方法
fullName:{ get(){},set(){} }:对象写法。 同时实现计算属性的get与set
*/
fullName:{
//读取
get(){
return this.firstName+this.lastName;
},
//设置
set(val){
//计算属性的set中法中,不能通过this来获取计算属性值,必须要通过形参来获取
console.log(val);//用户设置的计算属性值
console.log(this.fullName);//无法获取
this.firstName = val[0] || '';
this.lastName = val.substr(1,val.length-1) || '';
}
}
}
})
</script>
3.3 vue过滤器
过滤器作用: 对数据进行过滤 (格式化文本)
场景 :敏感词过滤, 格式化文本(日期等)
语法:
- 在vue实例filters中声明函数(过滤器也是一个函数)filMsg(val){}
- 在这个返回中return 过滤的结果
- 使用管道语法添加过滤器: {{ msg | 过滤器 }}
注意点:
过滤器中不能使用this访问data中的数据,而只能使用传参方式
<!-- HTML结构 -->
<div id="app">
<input type="text" placeholder="请输入内容" v-model="msg">
<p>输入的内容是:{{ msg | filMsg }}</p>
</div>
<script>
*/
/* 创建vue实例 */
var app = new Vue({
//el:挂载点
el: '#app',
//data: 要渲染的数据
data: {
msg: '!',
},
//过滤器
filters:{
//过滤器也是一个函数
filMsg(value){
console.log(value);
//注意点: 过滤器中不能使用this访问data成员,只能使用传参方式
/* 原因: 过滤器并不是只能过滤某个属性,它可以过滤所有的数据 */
// console.log( this.msg );
//敏感词过滤
if( value.indexOf('垃圾') != -1 ){
return value.replace('垃圾','**');
}else{
return value;
}
}
}
})
</script>
3.4 moment.js使用
作用:日期格式化
<script src="./moment-with-locales.js"></script>
<script>
//1.原生的date()日期格式化
let date = new Date()
console.log(date.toLocaleString()) //2021/6/18下午4:19:47
//2.moment.js支持更多的格式
//2.1 常规用法
console.log(moment().format('YYYY年-M月-d hh:mm:ss a'))
console.log(moment(new Date()).format('YYYY年-M月-d日 hh:mm:ss a'))
//2.2 相对时间
console.log(moment('20210614', 'YYYYMMDD').fromNow())
</script>
案例
总结
关于v-if和v-for:v-for优先级高于v-if,同一元素上最好不要同时使用v-for 和v-if(低效),如果你需要循环渲染某个东西,但是想只渲染其中满足条件的一部分,你可以先定义一个计算属性 在计算属性中进行遍历(filter()return需要渲染的数组),再对定义的计算属性进行v-for。或者:将 v-if 移动至容器元素上 (比如 ul, ol)。