Vue 指令(一)
指令:绑定在dom属性上
1. v-html
更新元素的 innerHTML
可以解析标签型数据( 可以将一个数据展示在一个dom的内容中( 相当于使用了 innerHTML ))
eg:
<body>
<div id="app">
<p v-html = "h"></p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app', //el表示我们的实例需要一个模板
data: { //是用来给实例定义数据的
h: '<h3> hello Vue.js </h3>'
}
})
</script>
2. v-text
更新元素的 textContent
可以将一个数据展示在一个dom的内容中( 相当于使用了 textContent )
eg:
<body>
<div id="app">
<p v-text = "msg"></p>
<p v-text = " flag && 1 || 2 " > </p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'hello Vue.js',
flag: true
}
})
</script>
3. 条件渲染 v-show
-
用法:
根据表达式之真假值,切换元素的
display
CSS 属性。当条件变化时该指令触发过渡效果。
-
可以控制一个dom的显示隐藏( 这个指令操作的是dom的display属性 )
eg:
<body>
<div id="app">
<h3> v-show </h3>
<p v-show = "showFlag"> v-show指令 </p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',//给跟实例一个模板( 挂载 )
data: {
showFlag: true
}
})
</script>
4. 条件渲染 v-if
-
用法:
根据表达式的值的真假条件渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是
<template>
,将提出它的内容作为条件块。当条件变化时该指令触发过渡效果。
-
可以控制一个dom的存在与否( 创建 和 销毁 )
eg:
<body>
<div id="app">
<h3> v-show </h3>
<p v-show = "showFlag"> v-show指令 </p>
<hr>
<h3> v-if - 单路分支 </h3>
<p v-if = "ifFlag"> v-if - 指令的单路分支 </p>
<h3> v-if - 双路分支 </h3>
<p v-if = "ifFlag"> 双路分支 成立 </p>
<p v-else> 双路分支不成立 </p>
<h3> v-if - 多路分支 </h3>
<p v-if = " type === 'A'"> A </p>
<p v-else-if = " type === 'B'"> B </p>
<p v-else> C </p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',//给跟实例一个模板( 挂载 )
data: {
showFlag: true,
ifFlag: false,
type: 'A'
}
})
</script>
5.条件渲染 v-else
-
限制:前一兄弟元素必须有
v-if
或v-else-if
-
用法:
为
v-if
或者v-else-if
添加“else 块”。
eg: 参考 v-if
6.条件渲染 v-else-if
-
限制:前一兄弟元素必须有
v-if
或v-else-if
-
用法:
表示
v-if
的 “else if 块”。可以链式调用。
eg: 参考 v-if
小结:
(1)v-if vs v-show 区别
- v-if 操作的是dom元素( 组件 ) 的创建或是销毁
- v-show 操作的是dom元素的display属性
- v-if可以有多种使用形式: 单路分支, 多路分支, 双路分支
- v-show 只能写一个单路形式
(2)实用: 项目中 如何选择这两个使用
- 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
- 因此,如果需要非常频繁地切换,则使用 v-show 较好;
- 如果在运行时条件很少改变,则使用 v-if 较好。
7. 列表渲染 v-for
用法:
基于源数据多次渲染元素或模板块。
数据类型可以为数组、对象、json类型数据、嵌套类型数据。
(1)数据类型为数组时:
v-for = " (item,index) in arr "
其中,item是源数据数组arr中的每一个元素,index为当前项的索引
eg:
<body>
<div id="app">
<h3> 数组 </h3>
<ul>
<li v-for=" (item,index) in arr " v-bind:key = "index">
<p> item :{{ item }} -- index: {{ index }}</p>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
arr: [1, 2, 3, 4]
}
})
</script>
结果:
数组
- item :1 – index: 0
- item :2 – index: 1
- item :3 – index: 2
- item :4 – index: 3
(2)数据类型为对象时
v-for = "(item,key,index) in obj "
其中,item是obj的属性值
eg:
<body>
<div id="app">
<h3> 对象 </h3>
<ul>
<li v-for="(item,key,index) in obj" v-bind:key = "index">
<p> value: {{ item }} -- key: {{ key }} -- {{ index }} </p>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
obj: {
id: 1,
name: 'huhu',
sex: 'man',
age: 18
}
}
})
</script>
结果:
对象
- value: 1 – key: id – 0
- value: huhu – key: name – 1
- value: man – key: sex – 2
- value: 18 – key: age – 3
(3)数据类型为json数据类型时
eg:
<body>
<div id="app">
<h3> json </h3>
<ul>
<li v-for="(item,index) of json" v-bind:key = " item.id ">
<p> id: {{ item.id }} </p>
<p> task: {{ item.task }} </p>
<p> {{ index }} </p>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
json: [
{
id: 1,
task: '爬山'
},
{
id: 2,
task: '跑步'
}
]
}
})
</script>
结果:
json
-
id: 1
task: 爬山
0
-
id: 2
task: 跑步
1
(4)数据为嵌套类型时
eg:
<body>
<div id="app">
<h3> 嵌套 </h3>
<ul>
<li v-for=" item in lists " :key = "item.id">
<p> id: {{ item.id }} </p>
<ul>
<li v-for="todo in item.todos">
todos中的数据 -- {{ todo }}
</li>
</ul>
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
lists: [
{
id: 1,
todos: {
id: 1,
name: 'huhu'
}
},
{
id: 2,
todos: {
id: 2,
name: 'dudu'
}
}
]
}
})
</script>
结果:
嵌套
- id: 1
- todos中的数据 – 1
- todos中的数据 – huhu
- id: 2
- todos中的数据 – 2
- todos中的数据 – dudu
(5)key
官方解释:
key
的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
最常见的用例是结合 v-for
。
结合v-for使用时:
key给每一个循环的列表添加一个唯一的标识,
使用指令 v-bind 来绑定 key:
<div v-for = " (item,index) in lists" v-bind:key = " item.id "></div>
注意冒号“:”和key之间不能有空格!
如果有id,那么我们就使用id,如果没有,我们才会选择index
v-bind: 单项数据绑定: 将一个数据绑定在一个dom的属性上
简写:
<div v-for = " (item,index) in lists" :key = " item.id "></div>
8. v-on
在学习这个模块之前,我们先来回顾一下javascript事件添加有几种形式:
- 事件绑定
dom.onclick = function () {}
dom: 事件源
on: 绑定事件的形式
click: 事件类型
function(){} 事件处理函数
-
事件监听 : addeventListener
-
直接在标签中绑定事件
<div onclick = "事件名称"></div>
vue采用了第三种,也是通过属性的形式绑定在dom身上 ,
<div v-on:click = "事件名称"></div>
为什么在 HTML 中监听事件?
你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用
v-on
有几个好处:- 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
- 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
- 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。
v-on使用:
事件源
事件绑定形式
事件类型
事件处理程序
v-on:eventType = " handlerName "
简写 v-on: — > @
在
methods
对象中定义方法eg1:
<body> <div id="app"> <button v-on:click = "helloHandler"> 点击 </button> <button @click = "helloHandler"> 点击 </button> </div> </body> <script> var vm = new Vue({ el: '#app', methods: { // 存放事件处理程序 helloHandler () { alert( 'hello' ) } } }) console.log( 'vm', vm ) </script>
问题: 函数调用有哪些方法?
1.直接调用 ( )
2.事件
eg2:
<body> <div id="app"> <button v-on:click = "helloHandler( 100 )"> 点击 </button> <button @click = "helloHandler( 200 )"> 点击 </button> </div> </body> <script> var vm = new Vue({ el: '#app', methods: { // 存放事件处理程序 helloHandler ( num ) { alert( num ) } } }) console.log( 'vm', vm ) </script>
eg3:
事件对象也可以正常使用
在事件处理程序中, 写e就可以了
<body>
<div id="app">
<button v-on:click = "helloHandler"> 点击 </button>
<button @click = "helloHandler"> 点击 </button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
methods: {
// 存放事件处理程序
helloHandler ( e ) {
console.log( e )
}
}
})
console.log( 'vm', vm )
</script>
eg4:
问题: 如果事件处理程序中有三个参数,第三个参数才是事件对象e,如何实现?
分析: 我们发现事件处理程序中的第三个参数 e 不在是事件对象了,而是一个undefined
解决: 在函数执行时,传入一个实际参数 $event 来代表事件对象
<body>
<div id="app">
<!-- <button v-on:click = "helloHandler"> 点击 </button> -->
<button @click = "helloHandler( 10,20,$event)"> 点击 </button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
methods: {
// 存放事件处理程序
helloHandler ( a,b,e ) {
console.log( a )
console.log( b )
console.log( e )
}
}
})
console.log( 'vm', vm )
</script>
eg5:
业务: 点击这个按钮,添加一条新的数据放在列表数据中
问题: 下标是不能检测变动的,但是我们现在看到了它检测到了
问题: 如果我们通过 length = 0 , 来清空一个数组,那么vue检测不到这个变动
解决方法: 使用splice
问题: 我们直接修改一个数组下的一个数据时,发现下标不能检测变动了
解决方法: 使用 Vue.set / this.$set
<body>
<div id="app">
<button @click = "add"> + </button>
<button @click = "remove"> - </button>
<button @click = "indexHandler"> 修改第二条数据 </button>
<ul>
<li v-for =" item in lists " :key = "item.id">
{{ item.task }}
</li>
</ul>
<hr>
<button @click = "arrChange"> 修改第二条数据 </button>
<ul>
<li v-for = " (item,index ) in arr " :key = "index">
{{ item }}
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
arr: [1,2,3],
lists: [
{
id: 1,
task: '锻炼1'
},
{
id: 2,
task: '敲代码'
}
]
},
methods: {
add () {
// console.log( this )
this.lists.push({
id: this.lists.length + 1,
task: '打篮球'
})
},
remove () {
this.lists.pop()
},
indexHandler () {
//将列表中的第二个数据中的task任务修改为 撸猫
this.lists[1] = {
id: 2,
task: '骏哥'
}
// 将整个列表清空
// this.lists.length = 0 //Jiancebud
// this.lists.splice( 0 )
},
arrChange () {
// this.arr[ 1 ] = '骏哥' 不可以检测到的
// this.$set( this.arr,'1','骏哥' )
Vue.set( this.arr,'1','骏哥')
}
}
})
</script>
9.v-model
用法:
在表单控件或者组件上创建双向绑定。
- 双向数据绑定
- 默认绑定value值
- v-model应用于表单元素
eg:
<body>
<div id="app">
<input type="text" v-model = "msg">
<p> {{ msg }} </p>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
msg: 'hello Vue.js'
}
})
</script>