少女祈祷中...

简介

  • Vue.js是一套构建用户界面的渐进式框架
  • Vue 只关注视图层, 采用自底向上增量开发的设计
  • Vue 是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件

Vue实例

  • 每个 Vue 应用都通过实例化 Vue 来实现
  • 变量名vm是受到了MVVM模型的启发
  • el 参数绑定对应DOM元素
  • data 定义属性
  • methods 定义函数
1
2
3
4
5
6
7
8
9
10
11
var vm = new Vue({
el: '#app',
data: {
msg: 'test'
},
methods: {
handle() {
alert("alert")
}
}
})

插值

文本插值

  • {{...}}(双大括号)
1
<span>Message: {% raw %}{{ msg }}{% endraw %}</span>
  • v-text 指令,用于文本插值
1
<p v-text="msg"><p>
1
2
3
data: {
msg: 'hello'
}

v-text会覆盖元素中原本的内容,{{...}}只会替换自己的这个占位符,不会把整个元素内容替换

HTML插值

  • v-html 指令,用于HTML插值
1
<span v-html="rawhtml"></span>
1
2
3
data: {
rawhtml: '<p>hello</p>'
}

属性

  • v-bind 指令,用于属性绑定
1
<button v-bind:disabled="isButtonDisabled">Button</button>
1
2
3
data: {
isButtonDisabled: true
}
  • v-bind 缩写
1
<button :disabled="isButtonDisabled">Button</button>

JS表达式

  • 对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持
1
2
3
4
5
{% raw %}{{number + 1}}{% endraw %}

{% raw %}{{ok ? 'YES' : 'NO'}}{% endraw %}

{% raw %}{{message.split('').reverse().join('')}}{% endraw %}

注意JS表达式和JS语句的区别

指令

  • v-bind 指令,如前文所示
  • v-on 指令,用于监听 DOM 事件
1
<a v-on:click="doSomething">...</a>
1
2
3
4
5
methods: {
doSomething() {
alert("alert")
}
}
  • v-on 缩写
1
<a @click="doSomething">...</a>
  • v-model 指令,用于在表单<input>、<textarea> 及 <select> 元素上实现双向数据绑定
1
2
<input v-model="message" placeholder="edit me">
<p>Message is: {% raw %}{{ message }}{% endraw %}</p>
  • v-if 指令,用于条件渲染
1
<h1 v-if="awesome">Vue is awesome!</h1>
1
2
3
data: {
awesome: true
}
  • v-else指令,用于表示 v-if 的“else 块”
1
2
3
4
5
6
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>
  • v-show 指令,用于条件渲染
1
<h1 v-show="ok">Hello!</h1>

v-if和v-show的区别:
带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的display样式
如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

  • v-for 指令,用于列表渲染
  • v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名
1
2
3
4
5
<ul id="example-1">
<li v-for="item in items">
{% raw %}{{ item.message }}{% endraw %}
</li>
</ul>
1
2
3
4
5
6
7
8
9
new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
  • v-for也可以遍历一个对象的 property

计算属性和侦听器

计算属性

  • 计算属性,通过computed来实现复杂逻辑运算
  • 计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值
1
2
3
4
<div id="example">
<p>Original message: "{% raw %}{{ message }}{% endraw %}"</p>
<p>Computed reversed message: "{% raw %}{{ reversedMessage }}{% endraw %}"</p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// this 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
  • 计算属性可以拥有setter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}

侦听器

  • 侦听属性,通过 watch 来响应数据的变化
1
<div id="demo">{% raw %}{{ fullName }}{% endraw %}</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})

事件修饰符

  • .stop 阻止事件冒泡到父元素
  • .prevent 阻止元素发生默认的行为
  • .capture 内部元素触发的事件先在此处理,然后才交由内部元素进行处理
  • .self 忽略事件冒泡和事件捕获对本元素的影响
  • .once 事件将只会触发一次
  • .passive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- 阻止单击事件继续传播 -->
<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>

<!-- 2.1.4新增 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>

<!-- 2.3.0新增 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

表单输入绑定

  • v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
    • text 和 textarea 元素使用 value property 和 input 事件
    • checkbox 和 radio 使用 checked property 和 change 事件
    • select 字段将 value 作为 property 并将 change 作为事件

文本/多行文本

1
2
<input v-model="message">
<textarea v-model="message"></textarea>

复选框

  • 单个复选框,绑定到布尔值
1
<input type="checkbox" id="checkbox" v-model="checked">
1
2
3
4
5
6
new Vue({
el: '...',
data: {
checked: false
}
})
  • 多个复选框,绑定到同一个数组
1
2
3
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
1
2
3
4
5
6
new Vue({
el: '...',
data: {
checkedNames: []
}
})

单选按钮

1
2
<input type="radio" id="one" value="One" v-model="picked">
<input type="radio" id="two" value="Two" v-model="picked">
1
2
3
4
5
6
new Vue({
el: '#example-4',
data: {
picked: ''
}
})

表单修饰符

  • .lazy 默认情况下, v-model 在 input 事件中同步输入框的值与数据,添加一个修饰符 lazy ,从而转变为在 change 事件中同步
1
<input v-model.lazy="msg" > 
  • .number 自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值)
1
<input v-model.number="age" type="number">
  • .trim 自动过滤用户输入的首尾空格
1
<input v-model.trim="msg">

组件

注册

全局注册

1
2
Vue.component('component-a', { /* ... */ })
new Vue({ el: '#app' })

局部注册

1
2
3
4
5
6
7
var ComponentA = { /* ... */ }
new Vue({
el: '#app',
components: {
'component-a': ComponentA
}
})