Day 02 条件渲染
一、class和style的控制
1.class的三种控制方式
<template>
<div id="test">
<div :style="'background:cyan'+';'+'padding:20px'">
<h1>class的三种写法</h1>
<div :class="isActive?'red':'green'">class三目写法</div>
<p :class="classObj">class对象写法</p>
<p :class="classarr">class数组写法</p>
</div>
</div>
</template>
<script>
export default {
name: "test",
data() {
return {
isActive: true,
classObj:{
red: false, yellow: true, font: true},
classarr:['green', 'font']
};
},
};
</script>
<style scoped>
.red{
background: red;
}
.green{
background: #42b983;
}
.yellow{
background: #ff9400;
}
.font{
font-size: 40px;
}
</style>
2.style的三种控制方式
<template>
<div id="test">
<div :style="'background:#42b983'+';'+'padding:20px'">
<h1>style的三种写法</h1>
<div style="background:red">style三目写法</div>
<div :style="'background:red'">style三目写法</div>
<div :style="'background:'+'red'">style三目写法</div>
<div :style="'background:'+(isActive?'red':'green')">style三目写法</div>
<p :style="styleobj">style对象写法</p>
<p :style="styleattr">style数组写法</p>
</div>
</div>
</template>
<script>
export default {
name: "test",
data() {
return {
isActive: true,
classObj: {
red: false, yellow: true, font: true },
classarr: ["green", "font"],
styleobj:{
background:'yellow',fontSize:'60px'},
styleattr:[{
background:'red'},]
};
}
};
</script>
<style scoped>
.red{
background: red;
}
.green{
background: #42b983;
}
.yellow{
background: #ff9400;
}
.font{
font-size: 40px;
}
</style>
二、条件的控制+列表渲染
<div class="col-2 text-md-left">
<table class="table table-hover table-dark" id="movielist">
<thead>
<tr>
<th scope="col">影片</th>
<th scope="col">票房</th>
</tr>
</thead>
<tbody>
<tr v-for="(movie, index) in Movies.MoviesInShow" :key="index">
<td class="selected-movie">
<div class="movie-desc">
<div class="moviename-num">
<p v-if="index===0" class="first">{
{ index + 1 }}</p>
<p v-else-if="index===1" class="second">{
{ index + 1 }}</p>
<p v-else-if="index===2" class="third">{
{ index + 1 }}</p>
<p v-else class="moviename-index third">{
{ index + 1 }}</p>
<p class="moviename-star"><i v-if="index>2" class="iconfont icon-xingxing" ></i>
<i v-else></i></p>
</div>
<div class="moviename-desc">
<p class="moviename-name">{
{ movie.movie_name }}</p>
<p class="moviename-info"><span>{
{ movie.releaseInfo }}</span></p>
</div>
</div>
</td>
<td class="boxoffice" style="color: #ff9400"><p>{
{ movie.sumBoxDesc }}</p></td>
</tr>
</tbody>
</table>
</div>
export default {
name: "Home",
data() {
return {
Movies: {
"MovieInfo": {
"movie_image": "/media/https%3A/img1.doubanio.com/view/photo/s_ratio_poster/public/p2625777429.jpg",
"movie_name": "除暴",
"movie_id": "30373723",
"area": "2020-11-20(中国大陆)",
"publish_time": "2020-11-20(中国大陆)",
"category": "剧情,动作,犯罪",
"starts": "刘浩良 Ho Leung Lau,王千源 Qianyuan Wang,吴彦祖 Daniel Wu,春夏 Jessie Li,卫诗雅 Michelle Wai,大力 Da Li",
"desc": "上世纪90年代,刑警钟诚受命追捕悍匪集团“老鹰帮”。这群悍匪犯下惊天连环劫案,训练有素且纪律严明,首领张隼更屡次恶意挑衅,矛头直指钟诚。为将“老鹰帮”捉拿归案,钟诚带领刑警小队咬死不放,誓与恶势力斗争到底。数年间,警匪上演了一次次紧张刺激的较量,悍匪愈加猖獗,警方步步逼近,双方展开殊死对决……",
"score": "6.5"
},
"MoviesInShow": [
{
"movie_image": "/media/https%3A/img1.doubanio.com/view/photo/s_ratio_poster/public/p2625777429.jpg",
"movie_id": "30373723",
"movie_name": "除暴",
"releaseInfo": "上映6天",
"sumBoxDesc": "2.77亿"
},
{
"movie_image": "/media/https%3A/img1.doubanio.com/view/photo/s_ratio_poster/public/p2623301908.jpg",
"movie_id": "35155748",
"movie_name": "金刚川",
"releaseInfo": "上映34天",
"sumBoxDesc": "10.73亿"
},
{
"movie_image": "/media/https%3A/img9.doubanio.com/view/photo/s_ratio_poster/public/p2626067725.jpg",
"movie_id": "30220799",
"movie_name": "末日逃生",
"releaseInfo": "上映6天",
"sumBoxDesc": "2756.0万"
},
{
"movie_image": "/media/https%3A/img1.doubanio.com/view/photo/s_ratio_poster/public/p2623500688.jpg",
"movie_id": "26991880",
"movie_name": "热血合唱团",
"releaseInfo": "上映13天",
"sumBoxDesc": "5059.3万"
},
]
},
MovieInfo: null,
MoviesInShow: null
};
},
}
**注意!**在Vue
中:
- 数组的
index
和value
是反的 - 对象的
key
和value
也是反的
2、关于key值的解释
1 v-for循环数组,对象时,建议在控件(组件,标签)写一个key属性,属性值唯一
2 页面更新以后,加速dom的替换(渲染),虚拟dom的替换diff算法
3 :key="变量"
3、数组更新与检测
3.1 数据双向绑定,数据变化,页面变,页面变化数据变
3.2 使用以下方法操作数组,可以检测变动
- push
- pop
- shift
- unshift
- splice
- sort
- reverse
3.3 不会检测变动
- filter()
- concat()
- slice()
- map(),
原因:
作者重写了相关方法(只重写了一部分方法,但是还有另一部分没有重写)
解决方法:
- 页面不会更改:
vm.arr.concat(['44','55'])
- 解决
vm.arr=vm.arr.concat(['44','55'])
4.1 方案一
# 通过 索引值 更新数组(数据会更新,但是页面不会发生改变)
vm.arr[0]
"11"
vm.arr[0]='99'
"99"
vm.arr.splice(0,1,'88')
["99"]
4.2 方案二
# 通过 Vue.set 更新数组(数据会更新,页面也会发生改变)
Vue.set(vm.arr,0,'lqz')
三、事件处理
事件 | 释义 |
---|---|
input | 当输入框进行输入的时候 触发的事件 |
change | 当元素的值发生改变时 触发的事件 |
blur | 当输入框失去焦点的时候 触发的事件 |
change
和blur
最本质的区别:
- 如果输入框为空,失去焦点后,change不会触发,但是blur会触发
1、过滤案例
<template>
<div id="test">
<div>
<p><input type="text" v-model="txt" @input="handleInput" placeholder="请输入要筛选的内容:"></p> // 绑定 input时间
<ul>
<li v-for="animal in new_animal" :key="animal">{
{ animal }}</li> // 这里是循环的新数组,因为如果有旧数组退回不会有反映
</ul>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
txt: "", // 输入的文本
animals: ["mouse", "cow", "tiger", "miki", "milaoshu", "milaozi"],
new_animal: ["mouse", "cow", "tiger", "miki", "milaoshu", "milaozi"]
};
},
methods: {
handleInput() {
this.new_animal = this.animals.filter(item => {
return item.indexOf(this.txt) > -1; //indexof 返回的是位置的索引,
// 如果返回的是正数则说明在文本中,否则不在
});
}
}
};
</script>
2、事件修饰符
事件修饰符 | 释义 |
---|---|
.stop | 只处理自己的事件,父控件冒泡的事件不处理(阻止事件冒泡) |
.self | 只处理自己的事件,子控件冒泡的事件不处理 |
.prevent | 阻止a链接的跳转 |
.once | 事件只会触发一次(适用于抽奖页面) |
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生
- 用
v-on:click.prevent.self
会阻止所有的点击 - 而
v-on:click.self.prevent
只会阻止对元素自身的点击
<template>
<div id="test">
<div>
<!-- <ul @click="handleUl">-->
<ul @click.self="handleUl">
<br>
<br> // 增加换行 好检索到 ul
<!-- <li v-for="data in dataList" @click="handleLi">{
{data}}</li>-->
<li v-for="data in dataList" :key="data" @click="handleLi($event)">{
{ data }}</li>
<li><a href="http://www.baidu.com">不拦截</a></li>
<li><a href="http://www.baidu.com" @click="handleLink($event)">点击拦截</a></li>
<li><a href="https://www.baidu.com" @click.prevent="handleLink">点击拦截</a></li>
<li>
<button @click.once="test">只执行一次</button>
</li>
</ul>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
dataList: ["mouse", "cow", "tiger", "miki", "milaoshu", "milaozi"]
};
},
methods: {
handleUl() {
console.log("ul被点击了!"); // ul的点击提醒
},
handleLi(ev) {
console.log("li被点击了!"); // li 的点击提醒
ev.stopPropagation();// 点击事件停止 冒泡(向父组件传递时间)
},
handleLink(ev) {
ev.preventDefault(); //阻止默认点击事件的执行
},
test() {
alert("只触发一次!");
}
}
};
</script>
3、按键修饰符
<template>
<div id="test">
<div>
<input type="text" @keyup="handlekey">
<input type="text" @keyup.enter="handlekeyEnter"> // 每一个键 都有对应的数值 比如说 enter = 13
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
dataList: ["mouse", "cow", "tiger", "miki", "milaoshu", "milaozi"]
};
},
methods: {
handlekey(ev) {
console.log(ev + "被按下了!");
},
handlekeyEnter() {
console.log('enter 被按下了!')
}
}
};
</script>
四、数据双向绑定
1、v-model的使用
<template>
<div id="test">
<div>
<input type="text" v-model="smallText">
<p>{
{ smallText }}</p>
<textarea name="" id="" cols="30" rows="10" v-model="smallTextarea"></textarea>
<p>{
{ smallTextarea }}</p>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
smallText: null,
smallTextarea: null
};
},
methods: {
}
};
</script>
五、表单控制
1、checkbok选中
<template>
<div id="test">
<div>
<input type="text" placeholder="请输入用户名:"><br>
<input type="password" placeholder="请输入密码:"><br>
<input type="checkbox" v-model="radio">记住用户名
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
radio:true
};
},
methods: {
}
};
</script>
2、单选
<template>
<div id="test">
<div>
<input type="radio" v-model="animal" value="mouse">老鼠
<input type="radio" v-model="animal" value="cow">老牛
<input type="radio" v-model="animal" value="tiger">老虎
<input type="radio" v-model="animal" value="rabbit">老兔
<p>这是你选择的动物--{
{animal}}</p>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
animal:[]
};
},
methods: {
}
};
</script>
3、多选
多选的原理和单选是一样的,只是把input类型换了下
<template>
<div id="test">
<div>
<input type="checkbox" v-model="animal" value="mouse">老鼠
<input type="checkbox" v-model="animal" value="cow">老牛
<input type="checkbox" v-model="animal" value="tiger">老虎
<input type="checkbox" v-model="animal" value="rabbit">老兔
<p>这是你选择的动物--{
{animal}}</p>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
animal:[]
};
},
methods: {
}
};
</script>
4、购物车案例
<template>
<div id="test">
<div>
<ul>
<li v-for="animal in animals" :key="animal">
<input type="checkbox" :value="animal" v-model="animalArray">名称:{
{ animal.name }}---价格---{
{ animal.price
}}
</li>
</ul>
<p>这是你选择的动物--{
{ animalArray }}</p> //一个个对象里面
<p>当前的价格时--{
{ PriceSum() }}</p>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
animals: [
{
name: "mouse", price: 10, number: 10, id: 1 },
{
name: "cow", price: 200, number: 3, id: 2 },
{
name: "tiger", price: 299, number: 1, id: 3 },
{
name: "rabbit", price: 24, number: 25, id: 4 }
],
animalArray: []
};
},
methods: {
PriceSum() {
var i
var sumprice = 0;
for (i in this.animalArray) {
// 这里 i 得到的是索引
sumprice += this.animalArray[i]['number'] * this.animalArray[i]['price'];
};
return sumprice
}
}
};
</script>
5、购物车全选
<template>
<div id="test">
<div>
<input type="radio" v-model="isAll" @change="checkAll">全选\取消
<ul>
<li v-for="animal in animals" :key="animal">
<input type="checkbox" :value="animal" v-model="animalArray" @change="checkOne">名称:{
{ animal.name }}---价格---{
{ animal.price
}} <!->绑定checkone事件,监控animalArray如果不等的话 全选取消</!->
</li>
</ul>
<p>这是你选择的动物--{
{ animalArray }}</p>
<p>当前的价格时--{
{ PriceSum() }}</p>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "test",
data() {
return {
animals: [
{
name: "mouse", price: 10, number: 10, id: 1 },
{
name: "cow", price: 200, number: 3, id: 2 },
{
name: "tiger", price: 299, number: 1, id: 3 },
{
name: "rabbit", price: 24, number: 25, id: 4 }
],
animalArray: [],
isAll: false
};
},
methods: {
PriceSum() {
var i;
var sumprice = 0;
for (i in this.animalArray) {
sumprice += this.animalArray[i]["number"] * this.animalArray[i]["price"];
}
;
return sumprice;
},
checkAll() {
if (this.animalArray.length > 0) {
this.animalArray = [];
} else {
this.animalArray = this.animals;
}
},
checkOne() {
if (this.animalArray.length == this.animals.length) {
this.isAll = true;
} else {
this.isAll = false;
}
}
}
};
</script>