• 简洁的模板语法来声明式的将数据渲染进 DOM 的系统
  1. <div id="app">
  2. {{ message }}
  3. </div>
  1. var app = new Vue({
  2. el: '#app',
  3. data: {
  4. message: 'Hello Vue!'
  5. }
  6. })
  1. Hello Vue!
  • v-bind 属性,被称为指令。
    指令带有前缀 v-,以表示它们是 Vue.js 提供的特殊属性。可能你已经猜到了,它们会在渲染过的 DOM 上应用特殊的响应式行为。这个指令的简单含义是说:将这个元素节点的 title 属性和 Vue 实例的 message 属性绑定到一起。
  1. <div id="app-2">
  2. <span v-bind:title="message">
  3. Hover your mouse over me for a few seconds to see my dynamically bound title!
  4. </span>
  5. </div>
  1. var app2 = new Vue({
  2. el: '#app-2',
  3. data: {
  4. message: 'You loaded this page on ' + new Date()
  5. }
  6. })
  • v-if条件控制
  1. <div id="app-3">
  2. <p v-if="seen">Now you see me</p>
  3. </div>
  1. var app3 = new Vue({
  2. el: '#app-3',
  3. data: {
  4. seen: true
  5. }
  6. })
  • v-for 指令可以绑定数据到数组来渲染一个列表:
  1. <div id="app-4">
  2. <ol>
  3. <li v-for="(todo, index) in todos">
  4. {{ todo.text }}
  5. </li>
  6. </ol>
  7. </div>
  1. var app4 = new Vue({
  2. el: '#app-4',
  3. data: {
  4. todos: [
  5. { text: 'Learn JavaScript' },
  6. { text: 'Learn Vue' },
  7. { text: 'Build something awesome' }
  8. ]
  9. }
  10. })

在控制台里,输入 app4.todos.push({ text: 'New item' })。会发现列表中多了一栏新内容。

  • v-on 指令绑定一个监听事件用于调用我们 Vue 实例中定义的方法:
  1. <div id="app-5">
  2. <p>{{ message }}</p>
  3. <button v-on:click="reverseMessage">Reverse Message</button>
  4. </div>
  1. var app5 = new Vue({
  2. el: '#app-5',
  3. data: {
  4. message: 'Hello Vue.js!'
  5. },
  6. methods: {
  7. reverseMessage: function () {
  8. this.message = this.message.split('').reverse().join('')
  9. }
  10. }
  11. })
  • v-model 指令,它使得在表单输入和应用状态中做双向数据绑定变得非常轻巧.
  1. <div id="app-6">
  2. <p>{{ message }}</p>
  3. <input v-model="message">
  4. </div>
  1. var app6 = new Vue({
  2. el: '#app-6',
  3. data: {
  4. message: 'Hello Vue!'
  5. }
  6. })
  • Vue.component ,在 Vue 里,一个组件实质上是一个拥有预定义选项的一个 Vue 实例
  1. Vue.component('todo-item', {
  2. props: ['todo'],
  3. template: '<li>This is a todo</li>'
  4. })
  5. var app7 = new Vue({
  6. el: '#app-7',
  7. data: {
  8. groceryList: [
  9. { text: 'Vegetables' },
  10. { text: 'Cheese' },
  11. { text: 'Whatever else humans are supposed to eat' }
  12. ]
  13. }
  14. })
  1. <div id="app-7">
  2. <ol>
  3. <todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item>
  4. </ol>
  5. </div>

vue study

  • 可以扩展 Vue 构造器,从而用预定义选项创建可复用的组件构造器:
  1. var MyComponent = Vue.extend({
  2. // 扩展选项
  3. })
  4. // 所有的 `MyComponent` 实例都将以预定义的扩展选项被创建
  5. var myComponentInstance = new MyComponent()
  • 属性与方法
    每个 Vue 实例都会代理其 data 对象里所有的属性:
  1. var data = { a: 1 }
  2. var vm = new Vue({
  3. data: data
  4. })
  5. vm.a === data.a // -> true
  6. // 设置属性也会影响到原始数据
  7. vm.a = 2
  8. data.a // -> 2
  9. // ... 反之亦然
  10. data.a = 3
  11. vm.a // -> 3
  • Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分。例如:
  1. var data = { a: 1 }
  2. var vm = new Vue({
  3. el: '#example',
  4. data: data
  5. })
  6. vm.$data === data // -> true
  7. vm.$el === document.getElementById('example') // -> true
  8. // $watch 是一个实例方法
  9. vm.$watch('a', function (newVal, oldVal) {
  10. // 这个回调将在 `vm.a` 改变后调用
  11. })

注意,不要在实例属性或者回调函数中(如 _vm.$watch('a', newVal => this.myMethod())_)使用箭头函数。因为箭头函数绑定父上下文,所以 this 不会像预想的一样是 Vue 实例,而是 _this.myMethod_ 未被定义。

  • 实例生命周期
    每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如,实例需要配置数据观测(data observer)、编译模版、挂载实例到 DOM ,然后在数据变化时更新 DOM 。在这个过程中,实例也会调用一些 生命周期钩子 ,这就给我们提供了执行自定义逻辑的机会。例如,created 这个钩子在实例被创建之后被调用:
  1. var vm = new Vue({
  2. data: {
  3. a: 1
  4. },
  5. created: function () {
  6. // `this` 指向 vm 实例
  7. console.log('a is: ' + this.a)
  8. }
  9. })
  10. // -> "a is: 1"

也有一些其它的钩子,在实例生命周期的不同阶段调用,如 mounted、 updated 、destroyed 。钩子的 this 指向调用它的 Vue 实例。 Vue.js 是否有“控制器”的概念?答案是没有。组件的自定义逻辑可以分布在这些钩子中。

  • v-html 双大括号会将数据解释为纯文本,而非 HTML 。为了输出真正的 HTML ,你需要使用 v-html 指令:
  1. <div v-html="rawHtml"></div>
  • 属性
    Mustache 不能在 HTML 属性中使用,应使用 v-bind 指令:
  1. <div v-bind:id="dynamicId"></div>

这对布尔值的属性也有效 —— 如果条件被求值为 false 的话该属性会被移除:

  1. <button v-bind:disabled="someDynamicCondition">Button</button>
  • 使用 JavaScript 表达式
  1. {{ number + 1 }}
  2. {{ ok ? 'YES' : 'NO' }}
  3. {{ message.split('').reverse().join('') }}
  4. <div v-bind:id="'list-' + id"></div>

有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

  1. <!-- 这是语句,不是表达式 -->
  2. {{ var a = 1 }}
  3. <!-- 流控制也不会生效,请使用三元表达式 -->
  4. {{ if (ok) { return message } }}

模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 _Math__Date_ 。你不应该在模板表达式中试图访问用户定义的全局变量。

  • 修饰符
    修饰符(Modifiers)是以半角句号 . 指明的特殊后缀,用于指出一个指定应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()
  1. <form v-on:submit.prevent="onSubmit"></form>
  1. //点击事件修饰符
  2. <!-- 阻止单击事件冒泡 -->
  3. <a v-on:click.stop="doThis"></a>
  4. <!-- 提交事件不再重载页面 -->
  5. <form v-on:submit.prevent="onSubmit"></form>
  6. <!-- 修饰符可以串联 -->
  7. <a v-on:click.stop.prevent="doThat"></a>
  8. <!-- 只有修饰符 -->
  9. <form v-on:submit.prevent></form>
  10. <!-- 添加事件侦听器时使用事件捕获模式 -->
  11. <div v-on:click.capture="doThis">...</div>
  12. <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
  13. <div v-on:click.self="doThat">...</div>
  14. <!-- the click event will be triggered at most once -->
  15. <a v-on:click.once="doThis"></a>
  16. //按键修饰符
  17. <!-- 只有在 keyCode 13 时调用 vm.submit() -->
  18. <input v-on:keyup.13="submit">
  19. //记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:
  20. <!-- 同上 -->
  21. <input v-on:keyup.enter="submit">
  22. <!-- 缩写语法 -->
  23. <input @keyup.enter="submit">
  24. //全部的按键别名
  25. .enter
  26. .tab
  27. .delete (捕获 “删除” “退格” 键)
  28. .esc
  29. .space
  30. .up
  31. .down
  32. .left
  33. .right
  34. //2.1.0新增开启鼠标或者键盘事件监听
  35. .ctrl
  36. .alt
  37. .shift
  38. .meta
  39. //可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
  40. // 可以使用 v-on:keyup.f1
  41. Vue.config.keyCodes.f1 = 112
  • v-bind 缩写
  1. <!-- 完整语法 -->
  2. <a v-bind:href="url"></a>
  3. <!-- 缩写 -->
  4. <a :href="url"></a>
  • v-on 缩写
  1. <!-- 完整语法 -->
  2. <a v-on:click="doSomething"></a>
  3. <!-- 缩写 -->
  4. <a @click="doSomething"></a>
  • vue数组变异方法和非变异方法
  1. push()
  2. pop()
  3. shift()
  4. unshift()
  5. splice()
  6. sort()
  7. reverse()
  1. filter()
  2. concat()
  3. slice()
  • 由于 JavaScript 的限制, Vue 不能检测以下变动的数组:
  1. 利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue
  2. 修改数组的长度时,例如:
    vm.items.length = newLength
    为了避免第一种情况,以下两种方式将达到像 vm.items[indexOfItem] = newValue 的效果, 同时也将触发状态更新:
  1. // Vue.set
  2. Vue.set(example1.items, indexOfItem, newValue)
  3. // Array.prototype.splice`
  4. example1.items.splice(indexOfItem, 1, newValue)

避免第二种情况,使用 splice:

  1. example1.items.splice(newLength)
  • 使用 v-on 绑定自定义事件
    每个 Vue 实例都实现了事件接口(Events interface),即:
    使用 **$on(eventName)** 监听事件
    使用 **$emit(eventName)** 触发事件

父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

  1. <div id="counter-event-example">
  2. <p>{{ total }}</p>
  3. <button-counter v-on:increment="incrementTotal"></button-counter>
  4. <button-counter v-on:increment="incrementTotal"></button-counter>
  5. </div>
  • 作用域插槽是一种特殊类型的插槽,用作使用一个(能够传递数据到)可重用模板替换已渲染元素。
    在父级中,具有特殊属性 scope<template> 元素,表示它是作用域插槽的模板。scope 的值对应一个临时变量名,此变量接收从子组件中传递的 prop 对象:
  1. <div class="child">
  2. <slot text="hello from child"></slot>
  3. </div>
  1. <div class="parent">
  2. <child>
  3. <template scope="props">
  4. <span>hello from parent</span>
  5. <span>{{ props.text }}</span>
  6. </template>
  7. </child>
  8. </div>

渲染以后

  1. <div class="parent">
  2. <div class="child">
  3. <span>hello from parent</span>
  4. <span>hello from child</span>
  5. </div>
  6. </div>
  • 子组件索引
    尽管有 props 和 events ,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个索引 ID 。例如:
  1. <div id="parent">
  2. <user-profile ref="profile"></user-profile>
  3. </div>
  1. var parent = new Vue({ el: '#parent' })
  2. // 访问子组件
  3. var child = parent.$refs.profile