2 -Vue列表渲染-事件处理-数据的双向绑定-表单控制
六 列表渲染
1.v-if+v-for+v-else控制购物车商品的显示
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>v-if + v-for + v-else控制购物车商品的显示</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
</style>
</head>
<div id="box">
<h2>我的购物车</h2>
<button @click="show">刷新购物车</button>
<br><br>
<table v-if="!shopping_car.length==0">
<td>商品名称</td>
<td>价格</td>
<tr v-for="item in shopping_car">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
</table>
<table v-else>
<td>商品名称</td>
<td>价格</td>
<td>暂无信息</td>
<td>暂无信息</td>
</table>
</div>
</body>
<script>
let vm = new Vue({
el: '#box',
data: {
isActive: false,
shopping_car: []
methods: {
show() {
this.shopping_car = [
{name: 'Threadripper 3990X', price: '29999元'},
{name: 'NVIDIA RTX 8000', price: '59999元'},
{name: 'ROG ZENITH II EXTREME', price: '9999元'},
</script>
</html>
2-v-for遍历数组(列表)、对象(字典)、数字
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>v-for遍历数组(列表)、对象(字典)</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
</style>
</head>
<div id="box">
<h2>数组(列表)for循环遍历</h2>
<li v-for="(value,index) in list_test">{{index}} —— {{value}}</li>
<h2>对象(字典)for循环遍历</h2>
<li v-for="(value,key) in dic_test">{{key}} —— {{value}}</li>
<h2>数组(列表)套对象(字典)for循环遍历</h2>
<table>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
<td>国籍</td>
<tr v-for="info in summary_test">
<td>{{info.name}}</td>
<td>{{info.age}}</td>
<td>{{info.gender}}</td>
<td>{{info.country}}</td>
</table>
</div>
</body>
<script>
let vm = new Vue({
el: '#box',
data: {
list_test: ['First', 'second', 'Third', 'Forth', 'Fifth'],
dic_test:{name: 'Darker', age: 18, gender: 'male'},
summary_test: [
{name: 'Alan', age: 23, gender: 'male', country: 'America'},
{name: 'Ben', age: 15, gender: 'male', country: 'Australia'},
{name: 'Cindy', age: 12, gender: 'female', country: 'Japan'},
{name: 'Darker', age: 18, gender: 'male', country: 'China'},
{name: 'Elisa', age: 26, gender: 'female', country: 'Mexico'},
</script>
</html>
#注意!在Vue中:
数组的index和value是反的
对象的key和value也是反的
3. key值 的解释
vue中使用的是虚拟DOM,会和原生的DOM进行比较,然后进行数据的更新, 提高数据的刷新速度 (虚拟DOM用了diff算法)
-
在
v-for
循环数组、对象
时,建议在控件/组件/标签
写1个key属性
,属性值唯一 - 页面更新之后,会加速DOM的替换(渲染)
-
:key="变量"
4. 数组更新与检测
可以检测到变动的数组操作:
push:最后位置添加
pop:最后位置删除
shift:第一个位置删除
unshift:第一个位置添加
splice:切片
sort:排序
reverse:反转
检测不到变动的数组操作:
filter():过滤
concat():追加另一个数组
slice():
map():
#原因:作者重写了相关方法(只重写了一部分方法,但是还有另一部分没有重写)
解决方法:
// 方法1:通过 索引值 更新数组(数据会更新,但是页面不会发生改变)
vm.arrayList[0]
"Alan"
vm.arrayList[0]='Darker'
"Darker"
// 方法2:通过 Vue.set(对象, index/key, value) 更新数组(数据会更新,页面也会发生改变)
Vue.set(vm.arrayList, 0, 'Darker')
七 事件处理
#change 和 blur 最本质的区别:
1-如果输入框为空,失去焦点后,change不会触发,但是blur会触发
2-两次输入的值没有变化也不会触发change。
1.过滤案例
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>过滤案例</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
<p><input type="text" v-model="myText" @input="handleInput" placeholder="请输入要筛选的内容:"></p>
<!-- <p><input type="text" v-model="myText" @change="handleInput" placeholder="请输入要筛选的内容:"></p> -->
<!-- <p><input type="text" v-model="myText" @blur="handleInput" placeholder="请输入要筛选的内容:"></p> -->
<li v-for="data in newList">{{data}}</li>
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
myText: '',
dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
newList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
methods: {
//方式一:由于里面的this指向的是匿名函数function,所以前面是需要重新给他this的值
// handleInput() {
// let _this = this
// this.newList = this.dataList.filter(
// function (item) {
// return item.indexOf(_this.myText) > -1
// })
// },
//方式二:箭头函数的应用主要是为了处理this指向的问题
handleInput() {
this.newList = this.dataList.filter(item => {
// item.indexOf(this.myText):输入框中输入的字符串在筛选元素中的索引
return item.indexOf(this.myText) > -1 // 返回索引大于1的元素:>-1 就表示包含在其中
</script>
</html>
2.事件修饰符 (阻止事件冒泡事件)
用
v-on:click.prevent.self
会阻止
所有的点击
而
v-on:click.self.prevent
只会阻止
对元素自身的点击
<body>
<div class="container-fluid">
<div class="row">
<div class="col-lg-6 col-md-offset-3">
<div id="app">
<div v-on:click="div_click">
//新方法
<button @click.stop="button_click">点我看美女</button>
//老方法 使用的js操作
//<button @click="handleLink">点我看美女</button>
</div>
<div v-on:click.self="div_click">
<button @click="button_click">点我看美女2</button>
</div>
<a href="http://www.baidu.com" @click.prevent="handle_a">链接被阻止访问了</a>
<button @click.once="handle_one">我只能点一次</button>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
div_click() {
alert('div被点击了')
button_click() {
alert('button被点击了')
handle_a() {
alert('a链接跳转阻挡了')
// location.href = 'http://www.baidu.com'
handle_one() {
alert('我只会谈一次')
//使用了stopPropagation,阻止控件的运行
handleLink(event) {
console.log('li被点击了')
event.stopPropagation() // 点击事件停止 冒泡(向父组件传递时间)
</script>
3.按键修饰符
<body>
<div id="app">
#1.只有按enter键才会触发他的执行
<input type="text" @keyup.enter="handle" v-model="search">
#2、任意键弹起都会触发他的执行
<input type="text" @keyup="handle" v-model="search">
#3、每按一个键都会触发他的执行
<input type="text" @keydown="handle" v-model="search">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
search:''
methods: {
handle(){
console.log('enter建被放开了')
location.href='https://www.baidu.com/s?wd='+this.search
</script>
</html>
八 数据的双向绑定(登录)
v-model的使用
<body>
<div id="app">
请输入您的名字:<input type="text" v-model="name">
请输入您的密码:<input type="password" v-model="password"> <span>{{error}}</span>
您输入的名字是:{{name}}
<button @click="submit_1">登录</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name:'',
password:'',
error:''
methods:{
submit_1(){
if(this.name=='longge' && this.password=='123'){
location.href='http://www.baidu.com'
}else {
this.error='用户名或密码错误'
</script>
九 表单控制
1.checkbox选中
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>checkbox</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
<input type="text" placeholder="请输入用户名:"><br>
<input type="password" placeholder="请输入密码:"><br>
<input type="checkbox" v-model="radio">记住用户名
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
myText: '',
textBig: '',
radio: false,
</script>
</html>
2.单选
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>单选</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
<input type="radio" v-model="radio" value="男">男
<input type="radio" v-model="radio" value="女">女
<input type="radio" v-model="radio" value="保密">保密
<br><br>您选择的性别:{{radio}}
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
radio: '',
</script>
</html>
3.多选
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>多选</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
<input type="checkbox" v-model="many" value="篮球">篮球
<input type="checkbox" v-model="many" value="足球">足球
<input type="checkbox" v-model="many" value="棒球">棒球
<input type="checkbox" v-model="many" value="桌球">桌球
<br><br>您喜欢的球类:{{many}}
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
many: [],
</script>
</html>
4.购物车案例 - 结算
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>购物车结算</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<style>
table, td {
border: 1px solid black;
text-align: center;
</style>
</head>
<div id="box">
<table>
<td>商品名称</td>
<td>价格</td>
<td>数量</td>
<td>选择</td>
<tr v-for="item in dataList">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.number}}</td>
<td><input type="checkbox" :value="item" v-model="checkGroup"></td>
</table>
<br>已选商品:{{checkGroup}}
<br>总价:{{getPrice()}}
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
dataList: [
{name: '今瓶没', price: 99, number: 2},
{name: '西柚记', price: 59, number: 1},
{name: '水壶转', price: 89, number: 5},
checkGroup: [],
methods: {
getPrice() {
let sum_price = 0
for (i in this.checkGroup) { // 这里的 i 是索引
sum_price += this.checkGroup[i]['number'] * this.checkGroup[i]['price']
return sum_price
</script>
</html>
5.购物车案例 - 全选/全不选 -数量加减
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>控制加减</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<div class="row">
<div id="box" class="col-md-4 offset-md-1 text-center mt-5 ">
<table class="table table-bordered">
<thead>
<th scope="col">商品名称</th>
<th scope="col">单价</th>
<th scope="col">数量</th>
<th scope="col">全选/全不选 <input type="checkbox" v-model="allChecked" @change="checkAll"></th>
</thead>
<tbody>
<tr v-for="item in dataList">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<button class="btn link btn-sm" @click="reduceNum(item)">-</button>
{{item.number}}
<button class="btn link btn-sm" @click="item.number++">+</button>
<td><input type="checkbox" :value="item" v-model="checkGroup" @change="checkOne"></td>
<tr class="text-left">
<td colspan="4">总价:{{getPrice()}}
</tbody>
</table>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#box',
data: {
dataList: [
{name: '今瓶没', price: 99, number: 1},
{name: '西柚记', price: 59, number: 1},
{name: '水壶转', price: 89, number: 1},
checkGroup: [],
allChecked: false,
methods: {
getPrice() {
let sum_price = 0
for (i in this.checkGroup) {
sum_price += this.checkGroup[i]['number'] * this.checkGroup[i]['price']
return sum_price
checkAll() {
if (this.checkGroup.length > 0) {
this.checkGroup = []
} else {
this.checkGroup = this.dataList
checkOne() {
// if (this.checkGroup.length === this.dataList.length) {
// this.allChecked = true
// } else {
// this.allChecked = false
// }
this.allChecked = this.checkGroup.length === this.dataList.length;
reduceNum(item) {
if (item.number === 1) {
item.number = 1
} else {
item.number--