02、vue常用指令
在vue中,指令 (Directives) 是带有 v- 前缀的特殊属性,指令属性的值预期是单个 JavaScript 表达式。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。本文内容是对官网文档的一个概括总结,更详细的内容请查看官网API。
常用指令
v-html
为了输出真正的html,而不是普通的字符串文本,可以使用 v-html 指令。
//假设 rawHtml = ‘This should be red’
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
以上的输出结果为
image.png
v-bind
v-bind可用于动态地绑定一个或多个特性,或一个组件 prop 到表达式,常见用法如下:
<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">
<!-- 缩写 -->
<img :src="imageSrc">
<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">
<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>
<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>
因为 v-bind 指令太常用,所以为它设计了一个缩写
<img v-bind:src="imageSrc">
<img :src="imageSrc">
以上两种写法是一样的。
v-on
v-on 指令用于 监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
在点击 按钮的时候, 会执行 counter += 1这段代码。
然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称
<div id="example-2">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
以上代码中,每次点击 按钮的时候,将执行 greet 方法。
同样的,因为 v-on 指令太常用,所以为它设计了一个缩写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
v-model
在表单控件或者组件上创建双向绑定,为了方便表单处理 。v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
以上代码可以实现以下效果:随着用户的输入,p标签上的内容自动更新。很像是 AngularJS中的 ng-model 指令。
条件渲染指令
v-if
v-if 指令将根据表达式的值的真假来插入/移除 元素。注意这里是真正的根据条件来渲染或是不渲染元素,不是简单的隐藏元素。与之对比的有一个 v-show指令,稍后介绍。
<p v-if="seen">现在你看到我了</p>
这里,v-if 指令将根据表达式 seen 的值的真假来插入/移除 <p> 元素。
因为 v-if 是一个指令,所以必须将它添加到一个元素上,如果想要通过 v-if 控制多个 元素的渲染,可以使用 <template> 标签将 需要渲染的内容包裹起来,例如:
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
v-else
v-else 指令和 和 v-if 一起使用,就像是我们代码中的 if else。可以用 v-else 添加一个“else 块”
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
在以上的代码中,如果 ok 的值为真,将渲染 Yes,或者将渲染 No。
v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
v-else-if
v-else-if 指令就像是代码中的 else-if,充当 v-if 的“else-if 块”,可以连续使用
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。
v-show
v-show 用于控制显示或者隐藏元素,只是简单地切换元素的 CSS 属性 display,但是不管怎么样,元素总是会被渲染。需要注意的是,v-show 不支持 <template> 元素,也不支持 v-else。
<h1 v-show="ok">Hello!</h1>
列表渲染指令
v-for
所谓的列表渲染,就是指循环渲染,比如将一个数组中的元素依次渲染出来,每个元素对应一个元素,就像是代码中的循环语句块。
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
以上的代码将被渲染成以下内容
<ul id="example-1">
<li> Foo </li>
<li> Bar</li>
</ul>
v-for 还支持一个可选的第二个参数为当前项的索引
<ul id="example-2">
<li v-for="(item, index) in items">
{{ index }} - {{ item.message }}
</li>
</ul>
这个很有用,有时候我们需要获取一个数组中某个元素的下标,就可以通过这种方式。
在js中,还可以通过 for循环遍历一个 对象中的属性,v-for 指令通用可以做到。
<ul id="testt">
<li v-for="value in object">
{{ value }}
</li>
</ul>
也可以提供第二个的参数作为键名
<div v-for="(value, key) in object">
{{ key }}: {{ value }}
</div>
还可以提供第三个参数作为索引
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }}: {{ value }}
</div>
在使用 v-for 指令的时候,最好可以给每个元素一个 key属性,用于标识这个元素是唯一的,在改变值的时候,方便重新渲染。
<div v-for="item in items" :key="item.id">
给元素加上唯一key属性吧
</div>
类似于 v-if,当 v-for 中的每个数据对应 一个元素块时,可以配合<template>一起使用,将元素块包裹起来
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider"></li>
</template>
</ul>
当 v-f 和 v-for 在同一个元素上使用时,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
在自定义组将中使用 v-for 指令,使用方式没有什么区别,但是数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要用 props
<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"
>
</my-component>
这里用到了 v-bind 指令,将值传递到数组中。
写的比较笼统,配合代码一起才会有感觉。