国产成人精品999视频&日本一区二区亚洲人妻精品&久久久精品国产99久久精&99热这里只有成人精品国产&精品国产剧情av一区二区&成人亚洲精品久久久久app&国产精品美女高潮抽搐A片

Vue 2 備忘清單

漸進(jìn)式 JavaScript 框架 Vue 2 備忘清單的快速參考列表,包含常用 API 和示例。

入門

介紹

Vue 是一套用于構(gòu)建用戶界面的漸進(jìn)式框架

注意:Vue 2.x 版本對(duì)應(yīng) Vue Router 3.x 路由版本

快速創(chuàng)建 Vue 項(xiàng)目

npx @vue/cli create hello-world

參考: Vue CLI 創(chuàng)建一個(gè)項(xiàng)目

聲明式渲染

<div id="app">
  {{ message }}
</div>

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

基礎(chǔ)例子

<div id="example">
  <p>原始信息: "{{ message }}"</p>
  <p>
    計(jì)算的反向信息: "{{ reversedMessage }}"
  </p>
</div>

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計(jì)算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 實(shí)例
      return this.message.split('')
          .reverse().join('')
    }
  }
})

結(jié)果

原始信息:  "Hello"
計(jì)算的反向信息:  "olleH"

綁定元素屬性

<div id="app-2">
  <span v-bind:title="message">
    鼠標(biāo)懸停幾秒鐘查看此處動(dòng)態(tài)綁定的提示信息!
  </span>
</div>

var app2 = new Vue({
  el: '#app-2',
  data: {
    message: '頁(yè)面加載于 ' + new Date()
        .toLocaleString()
  }
})

條件

<div id="app-3">
  <p v-if="seen">現(xiàn)在你看到我了</p>
</div>

var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})

控制切換一個(gè)元素是否顯示

循環(huán)

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>

var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '學(xué)習(xí) JavaScript' },
      { text: '學(xué)習(xí) Vue' },
      { text: '整個(gè)牛項(xiàng)目' }
    ]
  }
})

點(diǎn)擊事件處理

<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">
    反轉(zhuǎn)消息
  </button>
</div>

var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('')
            .reverse().join('')
    }
  }
})

輸入事件處理

<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>

v-model 指令,它能輕松實(shí)現(xiàn)表單輸入和應(yīng)用狀態(tài)之間的雙向綁定

var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})

模板語法

文本

<span>Message: {{ msg }}</span>
<span v-once>
  這個(gè)將不會(huì)改變: {{ msg }}
</span>

使用 v-once 指令,執(zhí)行一次性地插值,當(dāng)數(shù)據(jù)改變時(shí),插值處的內(nèi)容不會(huì)更新

原始 HTML

<p>解釋為普通文本: {{ rawHtml }}</p>
<p>
  使用 v-html 指令: 
  <span v-html="rawHtml"></span>
</p>

使用 v-html 指令,輸出真正的 HTML

屬性

<div v-bind:id="dynamicId"></div>
<button v-bind:disabled="isDisabled">
  Button
</button>

如果 isDisabled 的值是 null/undefined/false 則 disabled 不會(huì)被渲染出來

JavaScript 表達(dá)式

<div id="app">
  <span>消息: {{ msg }}</span>
  <span>{{ msg + '這是字符串' }}</span>
  <span>{{ isWorking ? '是':'否' }}</span>
  <span>{{ msg.getDetials() }}</span>
  <div v-bind:id="'list-' + id"></div>
<div>

指令

<p v-if="seen">
  現(xiàn)在你看到我了
</p>

v-if 指令將根據(jù)表達(dá)式 seen 的值的真假來插入/移除 <p> 元素

指令參數(shù)

<a v-bind:href="url">...</a>

v-bind 指令將該元素 href 屬性與表達(dá)式 url 的值綁定

<a v-on:click="doSomething">...</a>

v-on 指令,用于監(jiān)聽 DOM 事件,oSomething 是事件名

指令動(dòng)態(tài)參數(shù) v2.6

<a v-on:[eventName]="doSomething">...</a>

當(dāng) eventName 的值為 focus 時(shí),v-on:[eventName] 將等價(jià)于 v-on:focus

指令修飾符

<form v-on:submit.prevent="onSubmit">
  ...
</form>

.prevent 修飾符告訴 v-on 指令對(duì)于觸發(fā)的事件調(diào)用 event.preventDefault()

指令縮寫

<!-- 完整語法 -->
<a v-bind:href="url">...</a>
<!-- 縮寫 -->
<a :href="url">...</a>
<!-- 動(dòng)態(tài)參數(shù)的縮寫 (2.6.0+) -->
<a :[key]="url"> ... </a>

Class 與 Style 綁定

對(duì)象語法

<div v-bind:class="{ active: isActive }">

</div>

傳給 v-bind:class 一個(gè)對(duì)象,以動(dòng)態(tài)地切換 class

與普通的 class 屬性共存

<div
  class="static"
  v-bind:class="{
    active: isActive,
    'text-danger': hasError
  }"
></div>

如下 data

data: {
  isActive: true,
  hasError: false
}

結(jié)果渲染為

<div class="static active"></div>

綁定的數(shù)據(jù)對(duì)象不必內(nèi)聯(lián)定義在模板里

<div v-bind:class="classObject"></div>

如下 data

data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

結(jié)果渲染為

<div class="static active"></div>

三元表達(dá)式

<div v-bind:class="[
  isActive ? activeClass : ''
]">
</div>

數(shù)組

<div v-bind:class="[
  { active: isActive }, errorClass
]"></div>

數(shù)組語法

<div v-bind:class="[
  activeClass, errorClass
]">
</div>

如下 data

data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

結(jié)果渲染為

<div class="active text-danger"></div>

內(nèi)聯(lián)樣式

<div v-bind:style="{
    color: activeColor,
    fontSize: fontSize + 'px'
}"></div>

如下 data

data: {
  activeColor: 'red',
  fontSize: 30
}

結(jié)果渲染為

<div style="color: red; font-size: 30px;"></div>

內(nèi)聯(lián)樣式對(duì)象通常更好

<div v-bind:style="styleObject"></div>

如下 data

data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

同樣的,對(duì)象語法常常結(jié)合返回對(duì)象的計(jì)算屬性使用

內(nèi)聯(lián)樣式數(shù)組語法

<div v-bind:style="[
  baseStyles, overridingStyles
]"></div>

內(nèi)聯(lián)樣式多重值

<div :style="{
  display: ['-webkit-box', 'flex']
}"></div>

條件渲染

v-if

<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no ??</h1>

v-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>

@2.1.0 新增,必須緊跟在帶 v-if 或者 v-else-if 的元素之后

v-else

<div v-if="Math.random() > 0.5">
  現(xiàn)在你看到我了
</div>
<div v-else>
  現(xiàn)在你看不見我了
</div>

v-else 元素必須緊跟在帶 v-if 或者 v-else-if 的元素的后面

<template> 上使用 v-if 條件渲染分組

<template v-if="ok">
  <p>Paragraph 1</p>
</template>

用 key 管理可復(fù)用的元素

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="輸入用戶名" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="輸入郵箱" key="email-input">
</template>

v-show

<h1 v-show="ok">
  Hello!
</h1>

帶有 v-show 的元素始終會(huì)被渲染并保留在 DOM 中,只是簡(jiǎn)單地切換元素的 CSS 屬性 display

列表渲染

v-for

<ul id="example-1">
  <li
    v-for="item in items"
    :key="item.message">
    {{ item.message }}
  </li>
</ul>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

v-for 可選的第二個(gè)參數(shù)(索引)

<li v-for="(item, index) in items">
  {{ index }}
  {{ item.message }}
</li>

如下 data

data: {
  items: [
    { message: 'Foo' },
    { message: 'Bar' }
  ]
}

也可以用 of 替代 in 作為分隔符

<div v-for="item of items"></div>

v-for 使用對(duì)象

<li v-for="value in object">
  {{ value }}
</li>

如下 data

data: {
  object: {
    title: 'How to do lists in Vue',
    author: 'Jane Doe',
    publishedAt: '2016-04-10'
  }
}

渲染結(jié)果

How to do lists in Vue
Jane Doe
2016-04-10

提供第二個(gè)的參數(shù)為 property 名稱 (也就是鍵名)

<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>

還可以用第三個(gè)參數(shù)作為索引

<div v-for="(value,name,index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>

v-for/v-if

<li
  v-for="todo in todos"
  v-if="!todo.isComplete"
>
  {{ todo }}
</li>

只渲染未完成的 todo,下面加上 v-else 示例

<ul v-if="todos.length">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
<p v-else>No todos left!</p>

注意: v-forv-if 不推薦一起使用參考官方文檔

組件上使用 v-for

<my-component
  v-for="(item, index) in items"
  v-bind:item="item"
  v-bind:index="index"
  v-bind:key="item.id"
></my-component>

2.2.0+ 的版本里,當(dāng)在組件上使用 v-for 時(shí),key 現(xiàn)在是必須的

事件處理

監(jiān)聽事件

<div id="example-1">
  <button v-on:click="counter += 1">
    +1
  </button>
  <p>按鈕已被點(diǎn)擊 {{ counter }} 次。</p>
</div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

事件處理方法

<div id="example-2">
  <!-- `greet` 是在下面定義的方法名 -->
  <button v-on:click="greet">
    你好
  </button>
</div>
var example2 = new Vue({
  el: '#example-2',
  data: {
    name: 'Vue.js'
  },
  // 在 `methods` 對(duì)象中定義方法
  methods: {
    greet: function (event) {
      // `this` 在方法里指向當(dāng)前 Vue 實(shí)例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
})

也可以用 JavaScript 直接調(diào)用方法

example2.greet() // => 'Hello Vue.js!'

內(nèi)聯(lián)處理器中的方法

<div id="example-3">
  <button v-on:click="say('hi')">
    彈出 hi
  </button>
  <button v-on:click="say('what')">
    彈出 what
  </button>
</div>
new Vue({
  el: '#example-3',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
})

訪問原始的 DOM 事件,用特殊變量 $event

<button v-on:click="say('what', $event)">
  提交
</button>
methods: {
  say: function (message, event) {
    // 現(xiàn)在我們可以訪問原生事件對(duì)象
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

事件修飾符

<!-- 阻止單擊事件繼續(xù)傳播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重載頁(yè)面 -->
<form v-on:submit.prevent="submit"></form>
<!-- 修飾符可以串聯(lián) -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件監(jiān)聽器時(shí)使用事件捕獲模式 -->
<!-- 即內(nèi)部元素觸發(fā)的事件先在此處理 -->
<!-- 然后交由內(nèi)部元素進(jìn)行處理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 當(dāng) event.target 是當(dāng)前元素自身時(shí)觸發(fā) -->
<!-- 即事件不是從內(nèi)部元素觸發(fā)的 -->
<div v-on:click.self="doThat">...</div>
<!-- 點(diǎn)擊事件將只會(huì)觸發(fā)一次 -->
<a v-on:click.once="doThis"></a>

事件修飾符 passive

<!-- 滾動(dòng)事件的默認(rèn)行為(即滾動(dòng)行為)會(huì)立即觸發(fā) -->
<!-- 而不會(huì)等待 `onScroll` 完成  -->
<!-- 包含 event.preventDefault() 的情況 -->
<p v-on:scroll.passive="onScroll">
  ...
</p>

這個(gè) .passive 修飾符尤其能夠提升移動(dòng)端的性能。

按鍵修飾符

<!-- 在 key 是 Enter 時(shí)調(diào)用 vm.submit() -->
<input v-on:keyup.enter="submit">
<!-- 在 key 是 PageDown 時(shí)被調(diào)用 -->
<input v-on:keyup.page-down="onPageDown">
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">

.exact 修飾符

<!-- 即使 Alt 或 Shift 被一同按下時(shí)也會(huì)觸發(fā) -->
<button v-on:click.ctrl="onClick">
<!-- 有且只有 Ctrl 被按下的時(shí)候才觸發(fā) -->
<button v-on:click.ctrl.exact="ctrlClick">
<!-- 沒有任何系統(tǒng)修飾符被按下的時(shí)候才觸發(fā) -->
<button v-on:click.exact="onClick">

計(jì)算屬性和偵聽器

基礎(chǔ)例子

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>
    計(jì)算的反向消息: "{{ reversedMessage }}"
  </p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計(jì)算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 實(shí)例
      return this.message.split('')
                  .reverse().join('')
    }
  }
})

計(jì)算屬性緩存 vs 方法

<p>
  計(jì)算的反向消息:"{{ reversedMessage() }}"
</p>

在組件中,我們可以將同一函數(shù)定義為一個(gè)方法而不是一個(gè)計(jì)算屬性

methods: {
  reversedMessage: function () {
    return this.message.split('')
                .reverse().join('')
  }
}

兩種方式的最終結(jié)果確實(shí)是完全相同的。然而,不同的是計(jì)算屬性是基于它們的響應(yīng)式依賴進(jìn)行緩存的。

計(jì)算屬性 vs 偵聽屬性

<div id="demo">{{ fullName }}</div>
var vm = 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
    }
  }
})

上面代碼是命令式且重復(fù)的。將它與計(jì)算屬性的版本進(jìn)行比較:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName 
        + ' ' + this.lastName
    }
  }
})

計(jì)算屬性的 setter

computed: {
  fullName: {
    get: function () {         // getter
      return this.firstName + ' ' + this.lastName
    },
    set: function (newValue) { // setter
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

表單輸入綁定

文本

<input v-model="msg" placeholder="編輯我">
<p>msg is: {{ msg }}</p>

多行文本

<span>Multiline message is:</span>
<textarea
  v-model="message"
  placeholder="添加多行"></textarea>
<p>{{ message }}</p>

復(fù)選框

<input
  type="checkbox"
  id="checkbox"
  v-model="checked"
>
<label for="checkbox">{{ checked}}</label>

多個(gè)復(fù)選框

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>

如下 data

new Vue({
  el: '...',
  data: {
    checkedNames: []
  }
})

單選按鈕

<div id="example-4">
  <input type="radio" id="one" value="One"
    v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two"
    v-model="picked">
  <label for="two">Two</label>
  <div>Picked: {{ picked }}</div>
</div>

new Vue({
  el: '#example-4',
  data: {
    picked: ''
  }
})

選擇框

<select v-model="selected">
  <option disabled value="">請(qǐng)選擇</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
<span>Selected: {{ selected }}</span>

new Vue({
  el: '...',
  data: {
    selected: ''
  }
})

選擇框(數(shù)組)

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
<div>Selected: {{ selected }}</div>

new Vue({
  el: '...',
  data: {
    selected: []
  }
})

v-for 渲染的動(dòng)態(tài)選項(xiàng)

<select v-model="selected">
  <option
    v-for="option in options"
    v-bind:value="option.value"
  >
    {{ option.text }}
  </option>
</select>
<span>Selected: {{ selected }}</span>

new Vue({
  el: '...',
  data: {
    selected: 'A',
    options: [
      { text: 'One', value: 'A' },
      { text: 'Two', value: 'B' },
      { text: 'Three', value: 'C' }
    ]
  }
})

值綁定

<!-- 當(dāng)選中時(shí),pc 為字符串 "a" -->
<input type="radio" v-model="pc" value="a">

<!-- toggle 為 true 或 false -->
<input type="checkbox" v-model="toggle">
<!-- 選中第一個(gè)選項(xiàng)時(shí)selected為字符串 abc -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>

單選按鈕

<input
  type="radio"
  v-model="pick"
  v-bind:value="a">

當(dāng)選中時(shí)

vm.pick === vm.a

復(fù)選框

<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>

// 當(dāng)選中時(shí)
vm.toggle === 'yes'
// 當(dāng)沒有選中時(shí)
vm.toggle === 'no'

選擇框的選項(xiàng)

<select v-model="selected">
  <!-- 內(nèi)聯(lián)對(duì)象字面量 -->
  <option v-bind:value="{ number: 123 }">
    123
  </option>
</select>

當(dāng)選中時(shí)

typeof vm.selected // => 'object'
vm.selected.number // => 123

修飾符

<!-- lazy:在“change”時(shí)而非“input”時(shí)更新 -->
<input v-model.lazy="msg">

<!-- number:自動(dòng)將用戶的輸入值轉(zhuǎn)為數(shù)值類型 -->
<input v-model.number="age" type="number">

<!-- trim:自動(dòng)過濾用戶輸入的首尾空白字符 -->
<input v-model.trim="msg">

組件基礎(chǔ)

單文件組件

  • HTML/CSS/JS 三部分存放到一個(gè) Hello.vue 文件中

    <template>
      <p>{{ title }} World!</p>
    </template>
    <script>
      export default {
        name: 'Hello',
        props: {
          title: {
            type: String,
            default: 'Hello'
          }
        },
        data: function() {
          return {
            greeting: "Hello"
          };
        }
      };
    </script>
    <style scoped>
      p {
        font-size: 2em;
        text-align: center;
      }
    </style>
    
  • 使用 Hello.vue 組件

    <script>
      import Vue from "vue";
      import Hello from "./Hello";
    
      export default {
        components: { Hello }
      }
    </script>
    <template>
      <div>
        <Hello :title="'aaaa'"></Hello>
      </div>
    </template>
    

基本示例

Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: `
    <button v-on:click="count++">
      你點(diǎn)擊了我 {{ count }} 次
    </button>
  `
})

組件是可復(fù)用的 Vue 實(shí)例

<div id="components-demo">
  <button-counter></button-counter>
</div>

new Vue({
  el: '#components-demo'
})

組件的復(fù)用

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

單個(gè)根元素

Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
      <div v-html="post.content"></div>
    </div>
  `
})

<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:post="post"
>
</blog-post>

向子組件傳遞數(shù)據(jù)

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

當(dāng)值傳遞給一個(gè) prop attribute 的時(shí)候,變成了組件實(shí)例的一個(gè) property

<blog-post title="寫博客"></blog-post>
<blog-post title="如此有趣"></blog-post>

data 必須是一個(gè)函數(shù)

data: function () {
  return {
    count: 0
  }
}

組件的 data 選項(xiàng)必須是一個(gè)函數(shù)

監(jiān)聽子組件事件

Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
      <button
        v-on:click="$emit('enlarge-txt')"
      >放大文字
      </button>
      <div v-html="post.content"></div>
    </div>
  `
})

<blog-post
  ...
  v-on:enlarge-text="postFontSize += 0.1"
></blog-post>

可以使用 $emit 的第二個(gè)參數(shù)來提供這個(gè)值

<button
  v-on:click="$emit('enlarge-text', 0.1)"
>
  Enlarge text
</button>

通過 $event 訪問到被拋出的這個(gè)值

<blog-post
  ...
  v-on:enlarge-text="postFontSize += $event"
></blog-post>

如果這個(gè)事件處理函數(shù)是一個(gè)方法

<blog-post
  ...
  v-on:enlarge-text="onEnlargeText"
></blog-post>

那么這個(gè)值將會(huì)作為第一個(gè)參數(shù)傳入這個(gè)方法

methods: {
  onEnlargeText: function(enlargeAmount) {
    this.postFontSize += enlargeAmount
  }
}

在組件上使用 v-model

自定義事件也可以用于創(chuàng)建支持 v-model 的自定義輸入組件。

<input v-model="searchText">

等價(jià)于

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

當(dāng)用在組件上時(shí),v-model 則會(huì)這樣:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

為了讓它正常工作,這個(gè)組件內(nèi)的 <input> 必須:

  • 將其 value attribute 綁定到一個(gè)名叫 valueprop
  • 在其 input 事件被觸發(fā)時(shí),將新的值通過自定義的 input 事件拋出

Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})

現(xiàn)在 v-model 就應(yīng)該可以在這個(gè)組件上完美地工作起來了

<custom-input
  v-model="searchText"
>
</custom-input>

通過插槽分發(fā)內(nèi)容

<alert-box>
  發(fā)生了不好的事情。
</alert-box>

Vue.component('alert-box', {
  template: `
    <div class="demo-alert-box">
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
})

動(dòng)態(tài)組件示例

<div id="dynamic-component-demo" class="demo">
  <button
    v-for="tab in tabs"
    v-bind:key="tab"
    v-bind:class="['tab-button', { active: currentTab === tab }]"
    v-on:click="currentTab = tab"
  >
    {{ tab }}
  </button>
  <component v-bind:is="currentTabComponent" class="tab"></component>
</div>

<script>
  Vue.component("tab-home", {
    template: "<div>Home component</div>"
  });
  Vue.component("tab-posts", {
    template: "<div>Posts component</div>"
  });
  Vue.component("tab-archive", {
    template: "<div>Archive component</div>"
  });
  new Vue({
    el: "#dynamic-component-demo",
    data: {
      currentTab: "Home",
      tabs: ["Home", "Posts", "Archive"]
    },
    computed: {
      currentTabComponent: function() {
        return "tab-" + this.currentTab.toLowerCase();
      }
    }
  });
</script>

解析 DOM 模板時(shí)的注意事項(xiàng)

有些 HTML 元素,諸如 <ul><ol>、<table><select>,對(duì)于哪些元素可以出現(xiàn)在其內(nèi)部是有嚴(yán)格限制的。有些元素,諸如 <li><tr><option>,只能出現(xiàn)在其它某些特定的元素內(nèi)部

<table>
  <blog-post-row></blog-post-row>
</table>

<blog-post-row> 會(huì)被作為無效的內(nèi)容提升到外部


如果我們從以下來源使用模板的話,這條限制是不存在的

  • 字符串 (例如:template: '...')
  • 單文件組件 (.vue)
  • <script type="text/x-template">

過渡 & 動(dòng)畫

單元素/組件的過渡

<template>
  <button v-on:click="show = !show">
    切換
  </button>
  <transition name="fade">
    <p v-if="show">切換內(nèi)容</p>
  </transition>
</template>

<script>
  export default {
    data: function() {
      return {
        show: true
      };
    }
  };
</script>

<style scoped>
  .fade-enter-active, .fade-leave-active {
    transition: opacity .5s;
  }
  /* .fade-leave-active 低于 2.1.8 版本 */
  .fade-enter, .fade-leave-to {
    opacity: 0;
  }
</style>

CSS 過渡

<template>
  <button @click="show = !show">
    切換渲染
  </button>
  <transition name="slide-fade">
    <p v-if="show">切換內(nèi)容</p>
  </transition>
</template>
<script>
  export default {
    data: function() {
      return {
        show: true
      };
    }
  };
</script>
<style scoped>
  /* 可以設(shè)置不同的進(jìn)入和離開動(dòng)畫 */
  /* 設(shè)置持續(xù)時(shí)間和動(dòng)畫函數(shù) */
  .slide-fade-enter-active {
    transition: all .3s ease;
  }
  .slide-fade-leave-active {
    transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
  }
  /* .slide-fade-leave-active 用于 2.1.8 以下版本 */ 
  .slide-fade-enter, .slide-fade-leave-to {
    transform: translateX(10px);
    opacity: 0;
  }
</style>

CSS 動(dòng)畫

<template>
  <button @click="show = !show">切換展示</button>
  <transition name="bounce">
    <p v-if="show">切換內(nèi)容</p>
  </transition>
</template>
<script>
  export default {
    data: function() {
      return {
        show: true
      };
    }
  };
</script>
<style scoped>
.bounce-enter-active {
  animation: bounce-in .5s;
}
.bounce-leave-active {
  animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(1);
  }
}
</style>

過渡的類名

:-:-
v-enter定義進(jìn)入過渡的開始狀態(tài) #
v-enter-active定義進(jìn)入過渡生效時(shí)的狀態(tài) #
v-enter-to (2.1.8)定義進(jìn)入過渡的結(jié)束狀態(tài) #
v-leave定義離開過渡的開始狀態(tài) #
v-leave-active定義離開過渡生效時(shí)的狀態(tài) #
v-leave-to (2.1.8)定義離開過渡的結(jié)束狀態(tài) #

如果你使用了 <transition name="my-tran">,那么 v-enter 會(huì)替換為 my-tran-enter

自定義過渡的類名

:-:-
enter-class#
enter-active-class#
enter-to-class (2.1.8+)#
leave-class#
leave-active-class#
leave-to-class (2.1.8+)#

<transition
  name="custom-classes-transition"
  enter-active-class="animated tada"
  leave-active-class="animated bounceOutRight"
>
  <p v-if="show">hello</p>
</transition>

顯性的過渡持續(xù)時(shí)間

<transition> 組件上的 duration prop 定制一個(gè)顯性的過渡持續(xù)時(shí)間 (以毫秒計(jì)):

<transition :duration="1000">
  ...
</transition>

你也可以定制進(jìn)入和移出的持續(xù)時(shí)間:

<transition :duration="{
  enter: 500,
  leave: 800
}">
  ...
</transition>

初始渲染的過渡

可以通過 appear attribute 設(shè)置節(jié)點(diǎn)在初始渲染的過渡

<transition appear>
  <!-- ... -->
</transition>

這里默認(rèn)和進(jìn)入/離開過渡一樣,同樣也可以自定義 CSS 類名

<transition
  appear
  appear-class="custom-appear-class"
  appear-to-class="custom-appear-to-class"
  appear-active-class="custom-appear-active-class"
>
  <!-- ... -->
</transition>

自定義 JavaScript 鉤子:

<transition
  appear
  v-on:before-appear="customBeforeAppearHook"
  v-on:appear="customAppearHook"
  v-on:after-appear="customAfterAppearHook"
  v-on:appear-cancelled="customAppearCancelledHook"
>
  <!-- ... -->
</transition>

無論是 appear attribute 還是 v-on:appear 鉤子都會(huì)生成初始渲染過渡

JavaScript 鉤子

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

鉤子函數(shù)可以結(jié)合 CSS transitions/animations 使用,也可以單獨(dú)使用

列表的進(jìn)入/離開過渡

<template>
  <button v-on:click="add">添加</button>
  <button v-on:click="remove">刪除</button>
  <transition-group name="list" tag="p">
    <span v-for="item in items" v-bind:key="item" class="list-item">
      {{ item }}
    </span>
  </transition-group>
</template>
<script>
  export default {
    data: function() {
      return {
        items: [1,2,3,4,5,6,7,8,9],
        nextNum: 10
      };
    },
    methods: {
      randomIndex: function () {
        return Math.floor(Math.random() * this.items.length)
      },
      add: function () {
        this.items.splice(this.randomIndex(), 0, this.nextNum++)
      },
      remove: function () {
        this.items.splice(this.randomIndex(), 1)
      },
    }
  };
</script>
<style scoped>
  .list-item {
    display: inline-block;
    margin-right: 10px;
  }
  .list-enter-active, .list-leave-active {
    transition: all 1s;
  }
  /* .list-leave-active 適用于 2.1.8 以下版本 */
  .list-enter, .list-leave-to {
    opacity: 0;
    transform: translateY(30px);
  }
</style>

Vue 2 API 參考

全局配置

:-:-
silent取消所有的日志與警告 #
optionMergeStrategies自定義合并策略的選項(xiàng) #
devtools是否允許 devtools 檢查 #
errorHandler未捕獲錯(cuò)誤的處理函數(shù) (開發(fā)模式生效) #
warnHandler (2.4.0)運(yùn)行時(shí)警告處理函數(shù) #
ignoredElements忽略 Vue 之外的 (自定義元素) #
keyCodesv-on 自定義鍵位別名 #
performance (2.2.0)性能追蹤 #
productionTip (2.2.0)是否生成生產(chǎn)提示 #

全局 API

:-:-
Vue.extendVue 構(gòu)造器,創(chuàng)建一個(gè)“子類” #
Vue.nextTick執(zhí)行延遲回調(diào) #
Vue.set向響應(yīng)式對(duì)象中添加一個(gè)屬性 #
Vue.delete刪除對(duì)象的 property #
Vue.directive注冊(cè)或獲取全局指令 #
Vue.filter注冊(cè)或獲取全局過濾器 #
Vue.component注冊(cè)或獲取全局組件 #
Vue.use安裝 Vue.js 插件 #
Vue.mixin全局注冊(cè)一個(gè)混入 #
Vue.compile將模板字符串編譯成 render 函數(shù) #
Vue.observable (2.6.0)讓一個(gè)對(duì)象可響應(yīng) #
Vue.versionVue 安裝版本號(hào) #

數(shù)據(jù)

:-:-
data實(shí)例的數(shù)據(jù)對(duì)象 #
props接收來自父組件的數(shù)據(jù) #
propsData創(chuàng)建實(shí)例時(shí)傳遞 props #
computed計(jì)算屬性將被混入到 Vue 實(shí)例中 #
methods將被混入到 Vue 實(shí)例中 #
watch對(duì)象鍵是觀察的表達(dá)式,值是回調(diào)函數(shù) #

DOM

:-:-
el實(shí)例的掛載目標(biāo) #
template字符串模板作為 Vue 實(shí)例的標(biāo)識(shí)使用 #
render字符串模板的代替方案 #
renderError (2.2.0)render錯(cuò)誤時(shí)提供另一種渲染 #

生命周期鉤子

:-:-
beforeCreate實(shí)例初始化之后 #
created實(shí)例創(chuàng)建完成后被立即同步調(diào)用 #
beforeMount在掛載開始之前被調(diào)用 #
mounted實(shí)例被掛載后調(diào)用 #
beforeUpdate數(shù)據(jù)改變后 DOM 更新之前調(diào)用 #
updated數(shù)據(jù)更改更新完畢之后被調(diào)用 #
activatedkeep-alive 緩存組件激活時(shí)調(diào)用 #
deactivatedkeep-alive 緩存的組件失活時(shí)調(diào)用 #
beforeDestroy實(shí)例銷毀之前調(diào)用 #
destroyed實(shí)例銷毀后調(diào)用 #
errorCaptured (2.5.0)來自后代組件的錯(cuò)誤時(shí)被調(diào)用 #

資源

:-:-
directives包含 Vue 實(shí)例可用指令的哈希表 #
filters包含 Vue 實(shí)例可用過濾器的哈希表 #
components包含 Vue 實(shí)例可用組件的哈希表 #

組合

:-:-
parent指定已創(chuàng)建的實(shí)例之父實(shí)例 #
mixins接收一個(gè)混入對(duì)象的數(shù)組 #
extends聲明擴(kuò)展另一個(gè)組件 #
provide/inject (2.2.0)祖組件向所有子孫后代注入依賴 #

其它

:-:-
name允許組件模板遞歸地調(diào)用自身 #
delimiters改變純文本插入分隔符 #
functional使組件無狀態(tài)和無實(shí)例 #
model (2.2.0)使用 v-model 時(shí)定制 prop 和 event #
inheritAttrs (2.4.0)#
comments (2.4.0)是否保留模板中的HTML注釋 #

實(shí)例方法 / 數(shù)據(jù)

:-:-
vm.$watch觀察 Vue 實(shí)例上的一個(gè)表達(dá)式
或者一個(gè)函數(shù)計(jì)算結(jié)果的變化 #
vm.$set全局 Vue.set 的別名 #
vm.$delete全局 Vue.delete 的別名 #

實(shí)例 property

:-:-
vm.$data觀察的數(shù)據(jù)對(duì)象 #
vm.$props (2.2.0)組件接收的 props 對(duì)象 #
vm.$el實(shí)例使用的根 DOM 元素 #
vm.$options實(shí)例的初始化選項(xiàng) #
vm.$parent父實(shí)例 #
vm.$root當(dāng)前組件樹的根實(shí)例 #
vm.$children當(dāng)前實(shí)例的直接子組件 #
vm.$slots訪問被插槽分發(fā)的內(nèi)容 #
vm.$scopedSlots (2.1.0)訪問作用域插槽 #
vm.$refsDOM 元素和組件實(shí)例 #
vm.$isServer是否運(yùn)行于服務(wù)器 #
vm.$attrs (2.4.0)包含父作用域中不作為 prop 被識(shí)別的屬性綁定 ( #
vm.$listeners (2.4.0)包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器 #

實(shí)例方法 / 事件

:-:-
vm.$on監(jiān)聽當(dāng)前實(shí)例上的自定義事件 #
vm.$once監(jiān)聽一個(gè)自定義事件,只觸發(fā)一次 #
vm.$off移除自定義事件監(jiān)聽器 #
vm.$emit觸發(fā)當(dāng)前實(shí)例上的事 #

實(shí)例方法 / 生命周期

:-:-
vm.$mount手動(dòng)地掛載一個(gè)未掛載的實(shí)例 #
vm.$forceUpdate迫使 Vue 實(shí)例重新渲染 #
vm.$nextTick回調(diào)延遲執(zhí)行 #
vm.$destroy完全銷毀一個(gè)實(shí)例 #

指令

:-:-
v-text更新元素的 textContent #
v-html更新元素的 innerHTML #
v-show切換元素的 display css 屬性 #
v-if有條件地渲染元素 #
v-else#
v-else-if (2.1.0)#
v-for多次渲染元素或模板塊 #
v-on綁定事件監(jiān)聽器 #
v-bind動(dòng)態(tài)地綁定一個(gè)或多個(gè)屬性 #
v-model創(chuàng)建雙向綁定 #
v-slot提供插槽或接收 prop 的插槽 #
v-pre跳過元素和它的子元素編譯過程 #
v-cloak保持在元素上直到實(shí)例結(jié)束編譯 #
v-once只渲染元素和組件一次 #

特殊 attribute

:-:-
key用在 Vue 的虛擬 DOM 算法 #
ref元素或子組件注冊(cè)引用信息 #
is限制是否更新 #
slot推薦 2.6.0 新增的 v-slot #
slot-scope推薦 2.6.0 新增的 v-slot #
scope2.5.0 新增的 slot-scope 取代 #

內(nèi)置的組件

:-:-
<component>渲染一個(gè)元組件為動(dòng)態(tài)組件 #
<transition>單個(gè)元素/組件的過渡效果 #
<transition-group>多個(gè)元素/組件的過渡效果 #
<keep-alive>不活動(dòng)的實(shí)例緩存不銷毀 #
<slot>組件模板中的內(nèi)容分發(fā)插槽 #

v-on (事件)修飾符

:-:-
v-on:click.stop #調(diào)用 event.stopPropagation()。
v-on:click.prevent #調(diào)用 event.preventDefault()。
v-on:click.capture #添加事件偵聽器時(shí)使用 capture 模式。
v-on:click.self #只當(dāng)事件是從偵聽器綁定的元素本身觸發(fā)時(shí)才觸發(fā)回調(diào)。
v-on:click.{keyCode|keyAlias} #只當(dāng)事件是從特定鍵觸發(fā)時(shí)才觸發(fā)回調(diào)。
v-on:click.native #監(jiān)聽組件根元素的原生事件。
v-on:click.once #只觸發(fā)一次回調(diào)。
v-on:click.passive (2.3.0) #以 { passive: true } 模式添加偵聽器

v-on (鼠標(biāo))修飾符

:-:-
v-on:click.left #只當(dāng)點(diǎn)擊鼠標(biāo)左鍵時(shí)觸發(fā)
v-on:click.right #只當(dāng)點(diǎn)擊鼠標(biāo)右鍵時(shí)觸發(fā)
v-on:click.middle #只當(dāng)點(diǎn)擊鼠標(biāo)中鍵時(shí)觸發(fā)

(2.2.0) 中新增

系統(tǒng)修飾鍵

:-:-
v-on:keyup.ctrl (2.1.0)#
v-on:keyup.alt (2.1.0)#
v-on:keyup.shift (2.1.0)#
v-on:keyup.meta (2.1.0)#

Keyboard 按鍵修飾符

:-:-
v-on:keyup.enter#
v-on:keyup.tab#
v-on:keyup.delete捕獲“刪除”和“退格”鍵 #
v-on:keyup.esc#
v-on:keyup.space#
v-on:keyup.up#
v-on:keyup.down#
v-on:keyup.left#
v-on:keyup.right#

v-bind 修飾符

:-:-
v-bind.prop #作為一個(gè) DOM property 綁定而不是作為 attribute 綁定。(差別在哪里?)
v-bind.camel (2.1.0+) #將 kebab-case attribute 名轉(zhuǎn)換為 camelCase。
v-bind.sync (2.3.0+) #語法糖,會(huì)擴(kuò)展成一個(gè)更新父組件綁定值的 v-on 偵聽器。

另見