vue条件渲染与列表渲染
一、条件渲染
1、通过v-if 和 v-for 实现购物车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!-- v-if/v-else实现判断,v-for实现遍历-->
<ul v-if="shopping_car.length>0">
<li v-for="data in shopping_car">{{data}}</li>
</ul>
<div v-else>购物车空空如也</div>
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
shopping_car: ['苹果', '羽绒服', '鼠标']
},
})
</script>
</html>
2、v-if/v-else-if/v-else
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<div v-if="count==1">1111</div>
<div v-else-if="count==2">2222</div>
<div v-else>3333</div>
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
count: 1
},
})
</script>
</html>
二、列表渲染
1、for循环数组、对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<h1>循环数组</h1>
<div><p v-for="data in arr">{{data}}</p></div>
<h1>循环对象</h1>
<div><p v-for="data in obj">{{data}}</p></div>
<h1>循环数组索引和value</h1>
<div><p v-for="(data,index) in arr">索引:{{index}},数据:{{data}}</p></div>
<h1>循环对象key和value</h1>
<div><p v-for="(value,key) in obj">key:{{key}},value:{{value}}</p></div>
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
arr: ['jason', 'andy', 'cc'],
obj: {name: 'cc', age: 18, gender: 'male'}
}
})
</script>
</html>
![image-20201215152130143](https://gitee.com/cuicheng688/img/raw/master/img/20201215152137.png)
2、key值
1、v-for循环数组、对象时,建议在控件、组件、标签上写一个key属性,属性值要唯一
2、页面更新以后,加速dom的替换(渲染),虚拟dom的替换diff算法
3、格式:
:key='变量' # 要加冒号,否则key值会重复,报错
3、数组更新与检测
0 数据双向绑定:数据变-->页面变;页面变化-->数据也跟着变
1 目前使用以下方法操作数组,可以检测变动:push,pop,shift,unshift,splice,sort,reverse
2 不会检测变动的方法:filter(),concat(),slice(),map(),新数组替换旧数组
-页面不会更改的示例:vm.arr.concat(['44','55'])
-解决方案: vm.arr=vm.arr.concat(['44','55'])
3 页面不会更改:通过索引值更新数组
-解决方案一:
vm.arr[0]
"11"
vm.arr[0]='99'
"99"
vm.arr.splice(0,1,'88')
["99"]
-解决方案二
Vue.set(vm.arr,0,'lqz')
3 上面能更新是因为作者重写了那些方法
三、事件处理
# blur: 失去焦点触发
# change: 失去焦点触发
# input: 数据发生变化,就会触发
1、input过滤案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" v-model="myinput" @input="handleChange"> {{myinput}}
<br>
<div>
<p v-for="data in new_arr">{{data}}</p>
</div>
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
myinput: '',
arr: ['aabb', 'aadf', 'qwer', 'xyz'],
new_arr: ['aabb', 'aadf', 'qwer', 'xyz'],
},
methods: {
handleChange() {
console.log(this.myinput)
// 数据双向绑定了,控制arr的变化,页面就会变化
this.new_arr = this.arr.filter(item => {
return item.indexOf(this.myinput) > -1
})
}
}
})
</script>
</html>
![image-20201215182556717](https://gitee.com/cuicheng688/img/raw/master/img/20201215182556.png)
2、简单事件处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<button @click="isShow=!isShow">点击折叠/展开</button>
<button @click="handleClick">点击折叠/展开</button>
<button @click="handleClick($event)">点击折叠/展开,传递event事件</button>
<div v-show="isShow">
窗前明月光
</div>
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
isShow: true,
},
methods: {
handleClick(ev) {
console.log(ev)
this.isShow = !this.isShow
},
}
})
</script>
</html>
3、事件修饰符
.stop 阻止事件冒泡
.self 只处理自己的事件,子控件的事件不处理
.prevent 阻止a链接跳转
.once 只处理一次就解绑(常用于抽奖页面)
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<ul @click.self="handleUl">
<!-- <ul @click="handleUl">-->
<h1>event传递事件</h1>
<!-- <li v-for="data in datalist" @click="handleLi($event)">{{data}}</li>-->
<h1>.stop阻止事件冒泡</h1>
<li v-for="data in datalist" @click.stop="handleLi">{{data}}</li>
<h1>没有加.stop,但是父组件只处理自己的事件</h1>
<li v-for="data in datalist" @click="handleLi">{{data}}</li>
<h1>.once</h1>
<li v-for="data in datalist" @click.once="handleLi">{{data}}</li>
</ul>
<a href="http://www.baidu.com" @click.prevent="handleA">点击</a>
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
datalist: ['aaa', 'bbb', 'ccc']
},
methods: {
// handleLi(ev) {
// console.log('li被点击了')
// ev.stopPropagation() //点击事件停止向父组件传递
// },
handleLi() {
console.log('li被点击了')
},
handleUl() {
console.log('Ul被点击了')
},
handleA() {
console.log('a被点击了')
}
}
})
</script>
</html>
4、按键修饰符
敲击回车键,执行一件事
# 键盘修饰符:
.enter :回车键
.tab :制表键
.delete :含 delete 和 backspace ...
.esc :返回键
.space: 空格键
.up :向上键
.down :向下键
.left :向左键
.right :向右键
# 鼠标修饰符
鼠标修饰符用来限制处理程序监听特定的滑鼠按键。常见的有:
.left:鼠标左键
.middle:鼠标中间滚轮
.right:鼠标右键
# 修饰键
可以用如下修饰符开启鼠标或键盘事件监听,使在按键按下时发生响应:
.ctrl
.alt
.shift
.meta
格式:
@keyup.enter="函数名"
![image-20201215193404246](https://gitee.com/cuicheng688/img/raw/master/img/20201215193404.png)
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" v-model="myInput" @keyup.enter="handleKey">
<!--与上面的作用是一样的-->
<input type="text" v-model="myInput" @keyup.13="handleKey">
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
myInput: ''
},
methods: {
handleKey() {
console.log('回车')
}
}
})
</script>
</html>
四、数据双向绑定
1、v-model使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" v-model="myInput">
<br>
{{myInput}}
<br>
<textarea name="" id="" cols="30" rows="10" v-model="text"></textarea>
<br>
{{text}}
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
myInput: '',
text: ''
},
})
</script>
</html>
![image-20201215193951623](https://gitee.com/cuicheng688/img/raw/master/img/20201215193951.png)
五、表单控制
1、checkbox选中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<h1>表单相关之checkbox</h1>
<input type="checkbox" v-model="check">记住密码
<br>
{{check}}
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
check: true,
},
})
</script>
</html>
2、checkbox多选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<h1>表单相关之checkbox多选</h1>
<h3>你最爱的女明星</h3>
<input type="checkbox" v-model="checkgroup" value="郭德纲">桥本有菜
<input type="checkbox" v-model="checkgroup" value="冯小刚">相泽南
<input type="checkbox" v-model="checkgroup" value="潘长江">大桥未久
<br>
{{checkgroup}}
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
checkgroup: [],
},
})
</script>
</html>
![image-20201215203558448](https://gitee.com/cuicheng688/img/raw/master/img/20201215203558.png)
3、radio单选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<h1>表单相关之radio单选</h1>
<input type="radio" v-model="sex" value="male">男
<input type="radio" v-model="sex" value="female">女
<input type="radio" v-model="sex" value="unknown">未知
<br>
{{sex}}
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
sex: '',
},
})
</script>
</html>
![image-20201215203947595](https://gitee.com/cuicheng688/img/raw/master/img/20201215203947.png)
4、购物车案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<h1>表单相关之radio单选</h1>
<ul>
<li v-for="item in datalist">
<input type="checkbox" :value="item" v-model="checkgroup">
{{item}}
</li>
</ul>
<br>
购物车:{{checkgroup}}
<br>
当前总价:{{getPrice()}}
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
datalist: [
{name: 'apple', price: 100, number: 1, id: '1'},
{name: 'orange', price: 88, number: 2, id: '2'},
{name: 'banana', price: 10, number: 5, id: '3'}
],
checkgroup: [],
},
methods: {
getPrice() {
var sum_price = 0
for (i in this.checkgroup) {
sum_price += this.checkgroup[i]['number'] * this.checkgroup[i]['price']
}
return sum_price
}
}
})
</script>
</html>
![image-20201215213013238](https://gitee.com/cuicheng688/img/raw/master/img/20201215213013.png)
5、购物车全选/全不选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<h1>表单相关之radio单选</h1>
<input type="checkbox" v-model="isAll" @change="handleCheck"> 全选/全不选
<ul>
<li v-for="item in datalist">
<input type="checkbox" :value="item" v-model="checkgroup" @change="handleOne">
{{item}}
</li>
</ul>
<br>
购物车:{{checkgroup}}
<br>
当前总价:{{getPrice()}}
</div>
</body>
<script>
new Vue({
el: '#box',
data: {
datalist: [
{name: 'apple', price: 100, number: 1, id: '1'},
{name: 'orange', price: 88, number: 2, id: '2'},
{name: 'banana', price: 10, number: 5, id: '3'}
],
checkgroup: [],
isAll: false,
},
methods: {
getPrice() {
var sum_price = 0
for (i in this.checkgroup) {
sum_price += this.checkgroup[i]['number'] * this.checkgroup[i]['price']
}
return sum_price
},
handleCheck() {
if (this.isAll) {
this.checkgroup = this.datalist
} else {
this.checkgroup = []
}
},
handleOne() {
console.log('选中:', this.checkgroup.length);
console.log('总数据:', this.datalist.length);
if (this.checkgroup.length == this.datalist.length) {
this.isAll = true
} else {
this.isAll = false
}
}
}
})
</script>
</html>
6、购物车数量控制加减
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<h1>表单相关之radio单选</h1>
<input type="checkbox" v-model="isAll" @change="handleCheck"> 全选/全不选
<ul>
<li v-for="item in datalist">
<input type="checkbox" :value="item" v-model="checkgroup" @change="handleOne">
{{item}}
<button @click="handleReduce(item)">-</button>
{{item.number}}
<button @click="item.number++">+</button>
</li>
</ul>
<br>
购物车:{{checkgroup}}
<br>
当前总价:{{getPrice()}}
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
datalist: [
{name: 'apple', price: 100, number: 1, id: '1'},
{name: 'orange', price: 88, number: 2, id: '2'},
{name: 'banana', price: 10, number: 5, id: '3'}
],
checkgroup: [],
isAll: false,
},
methods: {
getPrice() {
var sum_price = 0
for (i in this.checkgroup) {
sum_price += this.checkgroup[i]['number'] * this.checkgroup[i]['price']
}
return sum_price
},
handleCheck() {
if (this.isAll) {
this.checkgroup = this.datalist
} else {
this.checkgroup = []
}
},
handleOne() {
console.log('选中:', this.checkgroup.length);
console.log('总数据:', this.datalist.length);
if (this.checkgroup.length == this.datalist.length) {
this.isAll = true
} else {
this.isAll = false
}
},
handleReduce(item) {
if (item.number <= 1) {
alert('数量超出范围')
item.number = 1
} else {
item.number--
}
}
}
})
</script>
</html>
7、v-model之lazy,number,trim
lazy:输入的内容不会立马跟vue的数据做交互,提升效率,当光标移出或者按回车键的时候会交互
number:只提取前面输入的数字,数字后面跟的字符不接受
trim:移除两边的空白字符
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" v-model.lazy="myText">||{{myText}}
<br>
<input type="text" v-model.number="myNumber">||{{myNumber}}
<br>
<input type="text" v-model.trim="myTrim">||{{myTrim}}
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
myText: '',
myNumber: '',
myTrim: '',
}
})
</script>
</html>