Vue----class与style绑定,事件的绑定,事件相关的处理
class与style绑定
- class 绑定
对象
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>class绑定</title>
<style>
.coloractive {
color: red;
}
.bgactive {
background-color: green;
}
.box {
width: 150px;
height: 150px;
background-color: #f66;
position: relative;
}
.active {
position: absolute;
top: 3px;
left: 3px;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body>
<div id="app">
<div class="coloractive bgactive">样式的写法</div>
<div class="coloractive" :class="{ bgactive: flag}">class对象的绑定</div>
<div class="box" v-for="item of list">
<div :class="{ active: item.flag }">{{ item.msg }}</div>
</div>
</div></body><script>
// 如果样式的名称是后端给你提供的class的名字,前端不能直接写,此时就可以使用class绑定
// 场景: 产品列表中的 hot 、 秒杀、....,后端会给你传递一个标识,前端可以依据这个标识搞事情
// class 绑定有两种形式
// 对象
new Vue({
el: '#app',
data: {
list: [{
flag: true,
msg: '秒杀'
},
{
flag: false,
msg: ''
},
{
flag: true,
msg: '热推'
}]
}
})
</script></html>
数组
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>class绑定</title>
<style>
.class1 {
font-size: 32px;
color: #f66;
}
.class2 {
background-color: #ccc;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body>
<div id="app">
<div class="class1 class2">class数组写法</div>
<div :class="[classa, classb]">class数组写法</div>
</div></body><script>
new Vue({
el: '#app',
data: {
classa: 'class1',
classb: 'class2'
}
})
</script></html>
- 作业:查看api 熟练使用style绑定对象形式和数组形式
条件判断
v-if v-else-if v-else
v-show
注意审查元素查看效果
<body>
<div id="app">
<div v-if="flag">如果为真我就显示</div>
<div v-if="Math.random() < 0.2"> 0.2 </div>
<div v-else-if="Math.random() < 0.8"> 0.8 </div>
<div v-else="Math.random() < 1"> 1 </div>
<div v-show="flag">如过为真我就显示</div>
</div></body><script>
new Vue({
el: '#app',
data: {
flag: false
}
})
</script>
作业: 什么时候使用v-if,什么时候使用v-show
列表渲染
v-for
key ********************************************
key 不可以重复、key可以为 用户id、产品id,**id,因为id具有唯一性
node项目中使用uuid确保id是不重复的
? 思考, js中 数组可以遍历,对象能不能遍历,字符串能不能遍历
key
<body>
<div id="app">
<ul>
<li v-for="item in arr1">{{ item }}</li>
</ul>
<ul>
<li v-for="(item, index) in arr1" :key="index">{{ item }}</li>
</ul>
<ul>
<li v-for="(item, index) of arr1" :key="item">{{ item }}</li>
</ul>
</div></body><script>
var app = new Vue({
el: '#app',
data: {
arr1: ['a', 'b', 'c']
}
})
</script>
多层遍历
<body>
<div id="app">
<h1>遍历数组 无key值</h1>
<ul>
<li v-for="item in arr1">{{ item }}</li>
</ul>
<h1>遍历数组 key值为索引值</h1>
<ul>
<li v-for="(item, index) in arr1" :key="index">{{ item }}</li>
</ul>
<h1>遍历数组 key值为唯一值</h1>
<ul>
<li v-for="(item, index) of arr1" :key="item">{{ item }}</li>
</ul>
<h1>遍历对象数组</h1>
<ul>
<li v-for="item of arr2" :key="item.bannerid">
<img :src="item.img" alt="">
</li>
</ul>
<h1>多层遍历,内层循环换个变量名和索引值是为了区分</h1>
<ul>
<li v-for="(item, index) of arr3" :key="index">
<h1>{{ item.brand }}</h1>
<ol>
<li v-for="(itm, idx) of item.list" :key="idx">
{{ itm }} - {{ item.brand }}
</li>
</ol>
</li>
</ul>
</div></body><script>
var app = new Vue({
el: '#app',
data: {
arr1: ['a', 'b', 'c'],
arr2: [{ bannerid: 'banner_1', img: 'https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/89951/22/13835/67854/5e64a4b8E84c207d9/7367dad332fe905b.jpg!cr_1125x445_0_171!q70.jpg.dpg', href: '', alt: '' }, { bannerid: 'banner_2', img: 'https://imgcps.jd.com/ling4/1670651/6Z2i6Iac55yB5b-D55yB5Yqb/5ZOB6LSo5rqQ5LqO5Y2T6LaK/p-5c13869682acdd181deeff08/2d409b2d/cr_1125x445_0_171/s1125x690/q70.jpg', href: '', alt: '' }, { bannerid: 'banner_3', img: 'https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/88149/40/14147/100076/5e6229a8Ef51e1321/54e2c5dd2c357e1e.jpg!cr_1125x445_0_171!q70.jpg.dpg', href: '', alt: '' }, { bannerid: 'banner_4', img: 'https://m.360buyimg.com/mobilecms/s700x280_jfs/t1/93827/39/13300/60640/5e561c60Edd0d8e34/73428f511893f63e.jpg!cr_1125x445_0_171!q70.jpg.dpg', href: '', alt: '' }],
arr3: [{
brand: '宝马',
list: ['X5', 'X6']
},{
brand: '奥迪',
list: ['Q7', 'A8']
}]
}
})
</script>
事件处理
- 事件处理-行内
<body>
<div id="app">
<h3>计数器</h3>
<div>
<button v-on:click="count += 1">点击</button> {{ count }} 次
</div>
<h3>案例 --- 简单业务逻辑可以考虑使用 行内的事件处理</h3>
<ul>
<li v-for="(item, index) of list" :key="index">
{{ item.name }} -
<button :disabled="item.num === 1" @click="item.num > 1 ? item.num -= 1: item.num = 1">-</button>
{{ item.num }}
<button @click="item.num += 1">+</button>
</li>
</ul>
</div></body><script>
new Vue({
el: '#app',
data: {
count: 0,
list: [
{
name:'aaa',
num:1
},
{
name:'bbb',
num:2
}
]
}
})
</script>
总结:这也就是玩一玩而已,项目中一般不要使用,比如上一个案例,如果点击 加 ,先向服务器发起更新数据库的操作,得到回应后采取改变视图
- 事件处理-方法
不传参可以不写(),要传参就传对象
<body>
<div id="app">
<h3>计数器</h3>
<div>
<button v-on:click="countfn">点击</button> {{ count }} 次
</div>
<h3>案例 -- 传对象</h3>
<ul>
<li v-for="(item, index) of list" :key="index">
{{ item.name }} -
<button :disabled="item.num === 1" @click=" reduce(item)">-</button>
{{ item.num }}
<button @click="add(item)">+</button>
</li>
</ul>
</div></body><script>
new Vue({
el: '#app',
data: {
count: 0,
list: [
{
name:'aaa',
num:1
},
{
name:'bbb',
num:2
}
]
},
methods: { // vue自定义的事件
countfn () {
this.count += 1
},
reduce (item) {
// 服务器发起请求 --- 成功
item.num > 1 ? item.num -= 1 : item.num = 1
},
add (item) {
// 服务器发起请求 --- 成功
item.num += 1
}
}
})
</script>
- 事件处理 - 事件对象
不传参,方法默认参数为事件对象
传递参数,并且获取事件对象 - $event
? 思考:一般使用事件对象解决什么问题? ---- 复习js中的事件对象
阻止默认事件、阻止冒泡、获取鼠标位置、获取事件源、获取DOM节点,传递数据,确定按键.........
利用事件对象阻止冒泡
虽然可以利用事件对象解决冒泡问题,但是你还使用了 event事件对象
事件修饰符
常用的事件修饰符
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 --><a v-on:click.stop.prevent="doThat"></a><!-- 只有修饰符 --><form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 --><!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 --><!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<!-- 这个 .passive 修饰符尤其能够提升移动端的性能。 --><div v-on:scroll.passive="onScroll">...</div>
不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。
按键修饰符
表单的数据绑定
v-model
如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。
<body>
<div id="app">
<div>
用户名:
<input type="text" v-mode="username" /> {{ username }}
</div>
<div>
密码:
<input type="password" v-model="password" /> {{ password }}
</div>
<div>
性别:
<input type="radio" name="sex" value="1" v-model="sex">男
<input type="radio" name="sex" value="0" v-model="sex">女
</div>
<div>
爱好:
<input type="checkbox" value="篮球" v-model="hobby">篮球
<input type="checkbox" value="排球" v-model="hobby">排球
<input type="checkbox" value="足球" v-model="hobby">足球
<input type="checkbox" value="乒乓球" v-model="hobby">乒乓球
</div>
<div>
阶段
<select v-model="lesson">
<option disabled value="">请选择</option>
<option value="一阶段">一阶段</option>
<option value="二阶段">二阶段</option>
<option value="三阶段">三阶段</option>
</select>
</div>
<div>
备注:
<textarea v-model="note"></textarea>
</div>
<div>
<input type="checkbox" v-model='flag'>同意***协议
{{ flag }}
</div>
<button @click="login">登陆</button>
</div></body><script>
var app = new Vue({
el: '#app',
data: { // Vue 实例也代理了 data 对象上所有的属性
username: '大勋勋',
password: '123456',
sex: '1',
hobby: [], // 多选 --- 初始化数据为 数组
lesson: '',
note: '',
flag: false // 选中还是未选中 - 单选 -- 初始化为boolean
},
methods: {
login () {
this.flag ? console.log({
username: this.username,
password: this.password,
sex: this.sex === '1' ? '男' : '女',
hobby: this.hobby,
lesson: this.lesson,
note: this.note
}) : console.log('请先勾选同意此协议')
}
}
})
console.log(app.username)
console.log(app.$data.username)
</script>
追加修饰符 lazy / number / trim
一般使用 trim 为居多
玩表单 不忘 v-model
v-model 有特殊
特殊1 checkbox 数组表多选 bool表单选
特殊2 select 不选第一项
计算属性
任何复杂的业务逻辑,我们都应当使用计算属性
计算属性具有依赖性,只有依赖的那个值发生了改变,计算属性才会重新计算,原数据不变,计算属性就不会执行 --- 缓存
所有的计算属性被包含在computed选项中
计算属性其实就是一个函数,必须得返回一个值,使用形式形如data中的数据
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>表单输入绑定</title>
<style>
.error {
color: #f00
}
.success {
color: #0f0
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body>
<div id="app">
<div>
用户名:
<input type="text" v-model.trim="username" /> {{ username }} - <span v-html="usernametip"></span>
</div>
<div>
密码:
<input type="password" v-model="password" /> {{ password }}
</div>
<div>
性别:
<input type="radio" name="sex" value="1" v-model="sex">男
<input type="radio" name="sex" value="0" v-model="sex">女
</div>
<div>
爱好:
<input type="checkbox" value="篮球" v-model="hobby">篮球
<input type="checkbox" value="排球" v-model="hobby">排球
<input type="checkbox" value="足球" v-model="hobby">足球
<input type="checkbox" value="乒乓球" v-model="hobby">乒乓球
</div>
<div>
阶段
<select v-model="lesson">
<option disabled value="">请选择</option>
<option value="一阶段">一阶段</option>
<option value="二阶段">二阶段</option>
<option value="三阶段">三阶段</option>
</select>
</div>
<div>
备注:
<textarea v-model="note"></textarea>
</div>
<div>
<input type="checkbox" v-model='flag'>同意***协议
{{ flag }}
</div>
<button @click="login">登陆</button>
</div></body><script>
var app = new Vue({
el: '#app',
data: { // Vue 实例也代理了 data 对象上所有的属性
username: '',
password: '',
sex: '1',
hobby: [], // 多选 --- 初始化数据为 数组
lesson: '',
note: '',
flag: false // 选中还是未选中 - 单选 -- 初始化为boolean
},
computed: { // 计算属性
usernametip () {
if (this.username === '') {
return '<span>请输入用户名</span>'
}
if (this.username.length < 6) {
return '<span class="error">用户名格式错误</span>'
} else {
return '<span class="success">ok</span>'
}
}
},
methods: {
login () {
this.flag ? console.log({
username: this.username,
password: this.password,
sex: this.sex === '1' ? '男' : '女',
hobby: this.hobby,
lesson: this.lesson,
note: this.note
}) : console.log('请先勾选同意此协议')
}
}
})
console.log(app.username)
console.log(app.$data.username)
</script></html>