Vue的简单分享
Vue
使用vue
直接使用script
标签引入即可
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,压缩了代码,去除了警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
vue实例
<div id="app">
{{ message }}
<input v-model="message" />
<button v-on:click="getMessage">获取值</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
getMessage: function(e){
alert(this.message);
console.log(e);
}
},
created: function(){
console.log("created");
}
});
</script>
数据与方法
通过data
设置数据
data: {
msg: "Hello Vue!",
arr: [1,2,3],
obj: {
a: "a",
b: "b"
}
}
var msg = vm.msg;
vm.arr = [4,5,6];
通过methods
设置方法
methods: {
setMessage: function(m){
this.msg = m;
},
getMessage: function(){
return this.msg;
}
}
vm.setMessage("Hello");
var msg = vm.getMessage();
还有一些实例数据方法,通过var vm = new Vue({...})
的返回值来操作
传送门
//观察 Vue 实例上的一个表达式或者一个函数计算结果的变化。回调函数得到的参数为新值和旧值。
vm.$watch( expOrFn, callback, [options] );
vm.$watch('obj.a', function (newVal, oldVal) {
console.log("变化前:", oldVal);
console.log("变化后:", newVal);
});
//Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。
vm.$data
//Vue 实例使用的根 DOM 元素。
vm.$el
生命周期
模板语法,数据绑定
- 文本
数据绑定最常见的形式就是使用“Mustache”
语法 (双大括号) 的文本插值:
<span>Message: {{ msg }}</span>
- 原始 HTML
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html
指令:
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
- 属性
Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind
(可简写为:
) 指令:
<div v-bind:id="dynamicId"></div>
<button :disabled="isButtonDisabled">Button</button>
- 使用
JavaScript
表达式
迄今为止,在我们的模板中,我们一直都只绑定简单的属性键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="'list-' + id"></div>
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}
- 指令
传送门
指令 (Directives) 是带有 v- 前缀的特殊 attribute。
v-text
v-html
v-show
v-if
v-else
v-else-if
v-for
v-on(@)
v-bind(:)
v-model
v-slot
v-pre
v-cloak
v-once
Class 与 Style 绑定
操作元素的 class
列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是**对象
或数组
**。
- **
class
**对象语法
我们可以传给 v-bind:class 一个对象,以动态地切换 class:
<!-- 可以这样 -->
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
<!-- 也可以这样 -->
<div :class="classObject"></div>
<script>
data:{
isActive: true,
hasError: false,
classObject: {
active: true,
'text-danger': false
}
}
</script>
<style>
.active{
...
}
.text-danger{
...
}
</style>
- **
class
**数组语法
我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:
<!-- 可以这样 -->
<div v-bind:class="[activeClass, errorClass]"></div>
<!-- 也可以这样 -->
<div :class="[isActive ? activeClass : '', errorClass]"></div>
<!-- 这样写将始终添加 errorClass,但是只有在 isActive 是 truthy 时才添加 activeClass -->
<div :class="[{ active: isActive }, errorClass]"></div>
<script>
data:{
activeClass: 'active',
errorClass: 'text-danger',
isActive: true
}
</script>
<style>
.active{
...
}
.text-danger{
...
}
</style>
- **
style
**对象语法
v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用**引号
**括起来) 来命名:
<!-- 比如这样 -->
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<!-- 当然,也可以像上面class那样传对象 -->
<script>
data: {
activeColor: 'red',
fontSize: 30
}
</script>
- **
style
**数组语法
v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:
<div id="div4" v-bind:style="[baseStyles, overridingStyles]"></div>
<script>
data: {
baseStyles: {
color: 'green',
fontSize: '30px'
},
overridingStyles: {
'font-weight': 'bold'
}
}
</script>
条件渲染
- v-if
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
<!-- 可以单独使用 -->
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<!-- v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。v-else-if 也是一样 -->
<div v-else>
Not A/B/C
</div>
<script>
data: {
type: 'A'
}
</script>
- 在
<template>
元素上使用 v-if 条件渲染分组
因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 <template>
元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template>
元素。
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
- v-show
另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:
<h1 v-show="ok">Hello!</h1>
注意: v-show 不支持
<template>
元素,也不支持 v-else。
- v-if vs v-show
- v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
- v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
- 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS(属性 display)进行切换。
- 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
列表渲染
- v-for 渲染列表
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
<ul id="app">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
<script>
var vm = new Vue({
el: '#app',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
});
</script>
- v-for 渲染对象
你也可以用 v-for 来遍历一个对象的属性。
<ul id="app" class="demo">
<div v-for="(value, name, index) in obj">
{{ index }}. {{ name }}: {{ value }}
</li>
</ul>
<script>
var vm = new Vue({
el: '#app',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
</script>
- 维护状态
当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性:
<div v-for="(item, index) in items" v-bind:key="item.id" >
<!-- 内容 -->
</div>
<!-- 或者 -->
<div v-for="(item, index) in items" v-bind:key="index" >
<!-- 内容 -->
</div>
不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。
- 在
<template>
上使用 v-for
类似于 v-if,你也可以利用带有 v-for 的 <template>
来循环渲染一段包含多个元素的内容。比如:
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
- v-for 与 v-if 一同使用
注意我们不推荐在同一元素上使用 v-if 和 v-for。更多细节可查阅风格指南。
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 <template>
)上。如:
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<!-- 或者 -->
<template v-if="todos.length">
<p v-for="todo in todos">
{{ todo }}
</p>
</template>
事件绑定
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
<div id="app">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
<button v-on:click="greet">Greet</button>
<button v-on:click="say('hi',$event)">Say hi</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
counter: 0
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
},
say: function (message, e) {
alert(message);
console.log(e);
}
}
})
</script>
事件修饰符
<!-- 阻止单击事件继续传播 -->
<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>
表单输入绑定
你可以用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
<input v-model.trim="message" >
<textarea v-model="message" ></textarea>
<input type="checkbox" id="checkbox" v-model="checked"><!-- checked是数组 -->
<input type="radio" id="one" value="One" v-model="picked">
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>