1.vue 的指令
1.1 指令的概念与分类
指令 是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
vue 中的指令按照不同的用途可以分为:
- 内容渲染指令
- 属性绑定指令
- 事件绑定指令
- 双向绑定指令
- 条件渲染指令
- 列表渲染指令
1.2 内容渲染指令
内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。
-
v-text 缺点:会覆盖元素内部原有的内容 <body>
<div id="app">
<p v-text="username"></p>
<p v-text="gender">性别</p>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: '李四',
gender: '男'
}
})
</script>
</body>
-
{{ }}:插值表达式,将对应的值渲染到元素的内容节点 <div id="app">
<p>姓名:{{ username }}</p>
<p>性别: {{ gender }}</p>
</div>
-
v-html 把包含 HTML 标签的字符串渲染为页面的 HTML 元素 <body>
<div id="app">
<p v-html="info"></p>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
info: '<h4 style="color:red; font-weight:bold">Hello Vue !</h4>'
}
})
</script>
</body
1.3 属性绑定指令
实例代码:
<body>
<div id="app">
<input type="text" name="" id="" v-bind:placeholder="tips">
<img v-bind:src="photo" alt="" style="width: 30px;">
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
tips: '请输入用户名',
photo: 'https://cn.vuejs.org/images/logo.svg'
}
})
</script>
</body>
使用 Javascript 表达式:
<body>
<div id="app">
<div>1 + 2 = {{ 1 + 2}}</div>
<div>{{ tips }} 反转 :{{ tips.split('').reverse().join('')}}</div>
<div :title="'box' + index">这是一个 div</div>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
tips: '请输入用户名',
index: 3
}
})
</script>
</body>
1.4 事件绑定指令
1.4.1 如何绑定
vue 提供了 v-on 事件绑定指令,用来辅助程序员为 DOM 元素绑定事件监听。
<body>
<div id="app">
<p>count : {{ count }}</p>
<button v-on:click="add(2)"> + 2 </button>
<button v-on:click="sub"> - 1 </button>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 5
},
methods: {
add( n ) {
this.count += n
},
sub() {
this.count --
}
}
})
</script>
</body>
1.4.2 事件对象
- vue 提供内置变量
$event ,是原生的 DOM 的事件对象 e.target 指向触发事件的 DOM 对象
<body>
<div id="app">
<p>count : {{ count }}</p>
<button v-on:click="add(1 , $event)"> + N </button>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 5
},
methods: {
add( n ,e ) {
this.count += n
if(this.count % 2 === 0){
e.target.style.backgroundColor = 'red'
}else{
e.target.style.backgroundColor = ''
}
}
}
})
</script>
</body>
1.4.3 事件修饰符
-
取消事件的默认行为:.prevent 原生: e.preventDefault() <div id="app">
<a href="http://www.baidu.com" @click.prevent="show">跳转到百度首页</a>
</div>
-
阻止时事件冒泡:.stop 原生: e.stopPropagation() 如果子元素和父元素同时绑定 click 事件,那么点击子元素,会先触发子元素的点击事件然后再往外冒泡,触发父元素的点击事件。 -
以捕获模式触发当前的事件处理函数:.Capture -
绑定的事件只能触发一次:.once -
只有在 event.target 是当前元素自身时触发事件处理函数:.selt
1.4.4按键修饰符
在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符。
-
<input type="text" @keyup.esc="clearInput"> 当 key 是 Esc 时调用 clearInput -
<input type="text" @keyup.enter="submit"> 当 key 是 Enter 时调用 submit 例子:
<body>
<div id="app">
<input type="text" @keyup.esc="clearInput">
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 5
},
methods: {
clearInput(e) {
console.log('触发了 clearInput')
e.target.value = ''
}
}
})
</script>
</body>
1.5 双向绑定指令
1.5.1 基本使用
vue 提供 v-model 双向数据绑定指令,用来辅助开发在不操作 DOM 的前提下,快速获取表单的数据。
input 文本框中的内容与 v-model 指令绑定的数据一致- 当操作
input 文本框内容 v-model 指令绑定的数据也会一起改变 v-model 能和 input 输入框(type=radio,checkbox,xxx),textarea,select 一起使用
<body>
<div id="app">
<div id="app">
<p>用户的名字是:{{ username }} </p>
<input type="text" v-model="username" >
<hr>
<input type="text" :value="username" >
<hr>
<select v-model="city">
<option value="">请选择城市</option>
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">广州</option>
</select>
<div v-model="username"></div>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: 'ZhangSan'
}
})
</script>
</body>
1.5.2 v-model 指令的修饰符
为了方便对用户输入的内容进行处理
修饰符 | 作用 | 实例 |
---|
.number | 自动把输入值转为Number 类型 | <input type="text" v-model.number="n1"> | .trim | 去掉首尾空白字符 | <input type="text" v-model.trim="username"> | .lazy | 在change 时而非input 时更新 | <input type="text" v-model.lazy="username"> |
.trim 只会取出首端和末尾的空格,中间的不会取出.lazy 之后在最后输入框失去焦点时同步最后一次数据,中间的变化不会实时同步
<body>
<div id="app">
<input type="text" v-model.number="n1"> + <input type="text" v-model.number="n2"> = <span>{{ n1 + n2 }} </span>
<hr>
<input type="text" v-model.trim="username">
<button @click="showName"> 获取用户名 </button>
<hr>
<input type="text" v-model.lazy="username">
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
n1: 1,
n2: 2,
username: 'zhangsan'
},
methods: {
showName() {
console.log(`用户名是:"${this.username}"`)
}
}
})
</script>
</body>
1.6 条件渲染指令
1.6.1 v-if 和 v-show
条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏。
v-if v-show
v-if 值为true显示,值为false隐藏,隐藏:直接 移除DOM结构v-show 值为true显示,值为false隐藏,隐藏:给 DOM 的 dispaly 设置为 none - 如果要频繁的切换元素的显示状态,
v-show 性能更好,不用每次都动态添加删除元素 - 如果初始状态为 false ,并且之后显示的状态可能性较小,使用
v-if 更好
1.6.2v-else-if 和 v-else
v-else-if 必须配合 v-if 使用,否则不被识别
<div v-if="type === 'A' ">优秀</div>
<div v-else-if="type === 'B' ">良好</div>
<div v-else-if="type === 'C' ">一般</div>
<div v-else="type === 'D' ">差</div>
1.7 列表渲染条件
vue 提供了 v-for 列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。v-for 指令需要使用 item in items 形式的特殊语法。
- items 是待循环的数组
- item 是被循环的每一项
v-for 还支持一个可选的第二个参数,即当前项的索引。语法格式:
(item,index) in items
item 和 index 都是形参
<div id="app">
<table class="table table-border table-hover table-striped">
<thead>
<th>索引</th>
<th>ID</th>
<th>姓名</th>
</thead>
<tbody>
<tr v-for="(item,index) in list">
<td>{{ index }} </td>
<td>{{ item.id }} </td>
<td>{{ item.name }} </td>
</tr>
</tbody>
</table>
</div>
- 官方建议:只要用到了
v-for 指令,那么一定要绑定一个 :key 属性 - 最好将
id 作为 key 的值 - 对 key 的值得类型,是有要求的,字符串或者数值类型
- key 值不允许重复,否则报错
Duplicate keys detected - 使用 index 的值当做 key 的值没有任何意义,index 的值不具有唯一性
1.7 品牌列表案例源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<div style="width: 30%;position: relative;margin: 20px;">
<form @submit.prevent="add" class="bs-example bs-example-form" role="form" style="width: 80%;">
<div class="input-group">
<span class="input-group-addon">品牌名称</span>
<input type="text" class="form-control" placeholder="请输入品牌名称" v-model.trim="brand">
</div>
<button type="submit" class="btn btn-success" style="position: absolute;right: 0;top: 0;">添加</button>
</form>
</div>
<div style="width: 80%;border-top: 1px solid #cfcfcf;margin-left: 20px;">
<table class="table table-bordered table-hover table-striped">
<thead>
<th>#</th>
<th>品牌名称</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="item in list" :key="item.id">
<td>{{ item.id }} </td>
<td>{{ item.name }} </td>
<td>
<div class="checkbox">
<label>
<input type="checkbox" v-model="item.status">
<span v-if="item.status === false">已禁用</span>
<span v-else>已启用</span>
</label>
</div>
</td>
<td>{{ item.time}} </td>
<td>
<span @click="remove(item.id)" style="cursor: pointer;">删除</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: '宝马',status: true,time: new Date()},
{ id: 2, name: '奔驰',status: false,time: new Date()},
{ id: 3, name: '奥迪',status: true,time: new Date()},
],
brand: '',
nextId: 4
},
methods: {
remove(id) {
console.log(id)
this.list = this.list.filter(item => item.id !== id)
},
add(){
console.log(this.brand)
if(this.brand === ''){
return window.alert('必须填写品牌名称!!!')
}
let obj = {
id: this.nextId,
name: this.brand,
status: true,
time: new Date()
}
this.list.push(obj)
this.brand = ''
this.nextId ++
}
}
})
</script>
</body>
</html>
|