Vue基礎

本文主要參考了Vue的官方文檔,還結合了其餘的優秀博客內容,提煉出最經常使用的知識點,經過本文能快速地瞭解或者複習Vue的基礎知識。javascript

安裝

Vue Devtools

瀏覽器插件,容許開發者在更友好的界面調試Vue應用css

script標籤引入

構建文件引入html

1.最新版本
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

2.特定版本
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>

3.兼容 ES Module 
<script type="module">
  import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.esm.browser.js'
</script>

4.更小構建
vue.js換成vue.min.js
複製代碼

開發版本和生產版本vue

開發版本包含完整的警告和調試模式
生產版本刪除了警告,33.30KB min+gzipjava

NPM

構建大型Vue應用時推薦用npm,由於它能和打包器webpack配合使用webpack

npm install vue
複製代碼

命令行工具CLI

命令行界面(英語:command-line interface,縮寫:CLI)是在圖形用戶界面獲得普及以前使用最爲普遍的用戶界面,它一般不支持鼠標,用戶經過鍵盤輸入指令,計算機接收到指令後,予以執行。
命令行界面要較圖形用戶界面節約計算機系統的資源。在熟記命令的前提下,使用命令行界面每每要較使用圖形用戶界面的操做速度要快。web

CLI的起源和優點,及不一樣操做系統上的實現npm

CLI (@vue/cli) 是一個全局安裝的 npm 包,提供了終端裏的 vue 命令。它能夠經過 vue create 快速建立一個新項目的腳手架,或者直接經過 vue serve 構建新想法的原型。你也能夠經過 vue ui 經過一套圖形化界面管理你的全部項目。數組

介紹

核心概念

  • javascript框架,網頁越複雜,js文件越多,其鏈接了許多的html與css,缺少正規的組織形式,這就須要js框架來組織這些文件
  • 漸進式,若是已存在一個應用,可將Vue做爲一小部分嵌入其中
  • 組件化,將頁面劃分爲一個個組件,每一個組件都有本身的html、css、js,且組件可複用
  • 響應式,數據改變,頁面上全部用到該數據的地方都會隨之更新
  • 命令行工具,用於快速初始化大型項目
  • 單文件組件,即.vue文件,自己就是一個單獨的組件(與之對應的是在.html文件中的script標 籤內new Vue({el:"xxx"})),擁有template、style、script,經過vue-loader對.vue進行解析,由於瀏覽器不認識.vue文件。

聲明式渲染

模板語法{{ x }}
對屬性 v-bind:屬性名="x"
複製代碼

條件與循環

v-if="x"
v-for="x in arrays"
複製代碼

處理用戶輸入

v-on:click="func"
<input v-model="message">
複製代碼

組件化應用構建

註冊組件
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})
複製代碼
使用組件
<div id="app-7">
  <ol>
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id"
    ></todo-item>
  </ol>
</div>
複製代碼

組件和自定義元素的關係瀏覽器

相同點:實現Slot API和is特性

不一樣點:相比自定義元素,組件在全部支持的瀏覽器下表現一致(兼容性好),多了一些功能,如跨組件數據流、自定義事件通訊以及構建工具集成

Vue實例

建立一個vue實例

var vm = new Vue({
  // 選項對象
})
複製代碼

數據和方法

數據-響應式
var data = { a: 1 }
var vm = new Vue({
  data: data
})

//只有當實例被建立時就已經存在於 data 中的屬性纔是響應式的
data.b = 'xx' // 非響應式

//響應系統沒法再追蹤變化
Object.freeze(data)
複製代碼
方法
都帶有前綴$
vm.$data
vm.$el
vm.$watch('a', function (newValue, oldValue) {
  // 這個回調將在 `vm.a` 改變後調用
})
...
複製代碼

生命週期鉤子

超詳細的解釋
更全的解釋

本人提煉一下

beforeCreate
啥都不存在

created
Vue實例的data數據已存在,可更改

判斷el是否存在
存在則繼續生命週期,不然中止

頁面渲染
優先級:render函數>template>html

beforeMount
<div>{{ x }}</div>

mounted
<div>內容</div>

beforeUpdate
$el$data都改變,實際是data數據改變,但頁面未渲染的階段

updated
更新完畢

beforeDestroy
此階段實例仍可以使用,可作路由跳轉

destroyed
vue 實例指示的全部東西都會解綁,全部的事件監聽器會被移除,全部的子實例也會被銷燬。

複製代碼

模板語法

基於HTML,將DOM與數據綁定,Vue在底層上將模板語法編譯成虛擬DOM渲染函數,這樣可智能計算出最少須要從新渲染多少組件,減小DOM操做。

也可不用模板,用渲染render函數,jsx語法。

插值

文本插值( {{ }} )
<span>Message: {{ msg }}</span>

一次性插值(v-once)
<span v-once>這個將不會改變: {{ msg }}</span>

原始HTML(v-html)
<span v-html="rawHtml"></span>

特性(v-bind)
<div v-bind:id="dynamicId"></div>
<button v-bind:disabled="isButtonDisabled">Button</button>
// 若disablefalse,特性disabled不會被渲染在模板中
強調 :給屬性添加變量時要加v-bind:(本人總是忘記)

js表達式
{{ }} 中能夠放變量的算數操做,三元表達式,數組方法等,但不可放語句(if else var)
""引號中也可寫js表達式(變量是響應的,也能識別布爾值truefalse),
不過若是想要字符串的話,加''單引號,可用+鏈接js表達式和字符串
複製代碼

指令

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

動態參數
<a v-bind:[attributeName]="url"> ... </a>

修飾符
<form v-on:submit.prevent="onSubmit">...</form>
複製代碼

縮寫

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

v-on
<a v-on:click="doSomething">...</a>
<a @click="doSomething">...</a>
複製代碼

計算屬性和偵聽屬性

計算屬性computed

語法格式以下:

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 實例
      return this.message.split('').reverse().join('')
    }
  }
})
複製代碼
  • reversedMessage爲一個屬性,不是一個方法,它和普通的變量使用方式同樣。
  • 無需在data中再聲明一邊,外面也能夠和訪問變量同樣訪問該屬性(this.計算屬性名)
  • 給它設置的函數,爲getter函數,當訪問這個屬性時就返回這個函數的返回值。
  • 它依賴於message這個變量,但內部依賴變化,該計算屬性也會響應式地變化。
  • 也能夠設置setter函數,語法以下
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]
    }
  }
}

// 使用setter函數
vm.fullName = "name1 name2"
複製代碼

計算屬性和方法methods的區別

<p>Reversed message: "{{ reversedMessage() }}"</p>

// 在組件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}
複製代碼

從以上例子能夠看出,利用methods訪問一樣能夠實現computed的功能。

不一樣之處以下:

  • computed放的是屬性,和變量同樣使用;methods放的是函數,使用時後面要加括號
  • 計算屬性基於響應式依賴進行緩存的,若是依賴沒變,屢次訪問該屬性,都是直接調用緩存的,沒必要再次執行函數;而methods下的方法,屢次訪問就要屢次執行函數。

但也要注意,computed下用到Date()的話,計算屬性不會更新的

偵聽器watch

語法格式以下:

<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
    }
  }
})
複製代碼

watch下監聽的都是在data中聲明過的變量,若變量變化,則會執行回調函數。

最佳使用場景:在數據變化時執行異步或開銷較大的操做。

不過通常狀況下都建議用計算屬性computed,每每代碼更簡單,在一些數據須要隨着其它數據變更而變更時更爲明顯。

樣式綁定——class和style

屬性的綁定都用v-bind:屬性名="js表達式+'字符串'+'js表達式'"

本來屬性的賦值只能用字符串,因爲Vue的加強,還能夠用對象和數組,可是仍是要包在""下

綁定class

對象語法

"{類名: 變量或布爾值, 類名:變量或布爾值, ...}"

變量也要是布爾值,做用是設置是否綁定對應的類樣式

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

// 容許普通賦值和對象賦值同時
<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>

// 更加清晰的寫法
<div v-bind:class="classObject"></div>
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

// 結合計算屬性功能更強大
<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
複製代碼

數組語法

"[變量, 變量, ...]"

變量存放着類名,做用是綁定哪些類名,也可在[]中放三元表達式

本人以爲和直接字符串賦值同樣,只是要綁定多個類名,字符串要用+' '+將它們隔開,數組語法直接逗號隔開

<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

// 三元表達式
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

// 數組語法和對象語法結合
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
複製代碼

用在組件上

語法和上面同樣,注意的就是使用組件時加的類名不會覆蓋本來定義組件時加的類名,二者共同存在。

綁定style

對象語法

"{css屬性:變量,css屬性:變量 + '單位',...}"

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

// 更直觀的表示
<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

// 也常和計算屬性結合
複製代碼

數組語法

"[變量,變量,...]"

變量存放着樣式,做用是將多個樣式對象添加到同一個元素上

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

對於不一樣的瀏覽器,Vue會自動添加前綴
複製代碼

條件渲染——v-if/v-show

v-if

v-if = "變量/表達式"

爲truthy則渲染對應的內容

v-else

要有v-if或v-else-if與之相對應

v-else-if

用法同v-if

用v-if渲染分組

能夠把一個<template> 元素當作不可見的包裹元素,並在上面使用 v-if,最終的渲染結果將不包含 <template> 元素。

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
複製代碼

key

Vue 會盡量高效地渲染元素,一般會複用已有元素而不是從頭開始渲染

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

// input的元素中不加key屬性的話,即便用條件切換展現的元素後,以前在input的輸入信息仍存在
// 由於Vue的高效渲染機制,不會替換<input>,而是改變它的placeholder屬性值,其餘不變
複製代碼

v-show

注意:做用至關於display: none而不是visibility: hidden

帶有 v-show 的元素始終會被渲染並保留在 DOM 中。v-show 只是簡單地切換元素的 CSS 屬性 display。

二者區別

  • v-if會真正地銷燬和重建元素
  • v-if是惰性的,起初爲false,則就不渲染了
  • v-show必渲染,而後改變css而已
  • 切換頻繁的話用v-show,省資源;切換少的話用v-if,萬一就不展現了呢!

列表渲染——v-for

v-for遍歷數組

語法:

單參數:v-for="item in items"

雙參數:v-for="(item, index) in items"

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

var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})
複製代碼

v-for遍歷對象

語法:

單參數:v-for="value in object"

雙參數:v-for="(value, name) in object"

三參數:v-for="(value, name, index) in object"

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>

new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})

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

// 三參數
<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>
複製代碼

狀態維護——key

Vue比較懶,能不操做DOM就不操做DOM,對v-for,當其數組變化時,Vue不會移動DOM的位置,而是從新渲染DOM使其與數組對應,這樣的話雖然消耗少,但有問題(好比表單輸入值還留在原位置)

建議使用v-for的時候都加key

<div v-for="item in items" v-bind:key="item.id">
  <!-- 內容 -->
</div>
複製代碼

數組更新檢測

對v-for遍歷的數組而言,其發生變化,視圖應該要響應式地更新

能響應式更新視圖的操做數組的方法

push() pop() shift() unshift() splice() sort() reverse()

須要進一步操做的

filter()、concat() 和 slice(),由於它們不改變原數組,而是返回新數組

操做方法:

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})
複製代碼

不能響應式更新視圖

  • 經過索引值改變數組元素
  • 改變數組.length來改變數組
var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是響應性的
vm.items.length = 2 // 不是響應性的
複製代碼

解決問題1:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

vm.$set(vm.items, indexOfItem, newValue)
複製代碼

解決問題2:

vm.items.splice(newLength)
複製代碼

對象更新檢測

Vue 不能檢測對象屬性的添加或刪除

響應式方法:

Vue.set(vm.userProfile, 'age', 27)

vm.$set(vm.userProfile, 'age', 27)

// 添加多個對象
vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})
複製代碼

其餘

顯示過濾/排序後的結果

v-for循環的數組放在計算屬性中,該計算屬性返回對原數組的操做後的一個新數組,這樣既不會改變原數組的順序,又能按本身的想法顯示過濾或排序後的結果

v-for能夠對數字循環

<div>
  <span v-for="n in 10">{{ n }} </span>
</div>

// 輸出
1 2 3 4 5 6 7 8 9 10
複製代碼

能夠在<template>上使用v-for

v-forv-if一同使用

v-for的優先級大於v-if,從而先循環出列表,再根據條件決定是否渲染單一元素

要想實現先條件再循環的效果,將v-if放在v-for的外層元素上便可

組件上也可以使用v-for

可是組件內部是沒法獲取循環的元素的,仍是要經過prop

注意,組件用v-for的話key是必須的

事件處理——v-on

v-on語法

v-on="JS代碼"

<div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
複製代碼

v-on="methods中定義的方法"

注意該方法的第一個參數 event 爲原生 DOM 事件

<div id="example-2">
  <!-- `greet` 是在下面定義的方法名 -->
  <button v-on:click="greet">Greet</button>
</div>

var example2 = new Vue({
  el: '#example-2',
  data: {
    name: 'Vue.js'
  },
  // 在 `methods` 對象中定義方法
  methods: {
    greet: function (event) {
      // `this` 在方法裏指向當前 Vue 實例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
})
複製代碼

v-on="methods方法(js語句)"

還可傳入特殊變量 $event,表示DOM事件

<div id="example-3">
  <button v-on:click="say('hi')">Say hi</button>
  <button v-on:click="say('what', $event)">Say what</button>
</div>

new Vue({
  el: '#example-3',
  methods: {
    say: function (message, event) {
      alert(message)
    }
  }
})
複製代碼

事件修飾符

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止單擊事件繼續傳播 -->
<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>

<!-- 點擊事件將只會觸發一次 -->
<a v-on:click.once="doThis"></a>

<!-- 滾動事件的默認行爲 (即滾動行爲) 將會當即觸發 -->
<!-- 而不會等待 `onScroll` 完成  -->
<!-- 這其中包含 `event.preventDefault()` 的狀況 -->
<div v-on:scroll.passive="onScroll">...</div>
複製代碼

按鍵修飾符

  • .enter
  • .tab
  • .delete (捕獲「刪除」和「退格」鍵)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
<!-- 只有在 `key` 是 `Enter` 時調用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
複製代碼

按鍵碼的方式(快被廢棄了)

<input v-on:keyup.13="submit">
複製代碼

自定義按鍵修飾符

// 可使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
複製代碼

系統修飾鍵

  • .ctrl
  • .alt
  • .shift
  • .meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
複製代碼
  • .exact
<!-- 即便 Alt 或 Shift 被一同按下時也會觸發 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的時候才觸發 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button @click.exact="onClick">A</button>
複製代碼

鼠標修飾符

  • .left
  • .right
  • .middle

表單綁定——v-model

在表單元素 <input><textarea><select>上建立雙向數據綁定,根據控件類型自動選取正確的方法來更新元素。

本質是語法糖

基礎用法

  • text 和 textarea 元素使用 value 屬性和 input 事件;
  • checkbox 和 radio 使用 checked 屬性和 change 事件;
  • select 字段將 value 做爲 prop 並將 change 做爲事件。

文本text

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
複製代碼

多行文本textarea

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
複製代碼

複選框checkbox

<div id='example-3'>
  <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>
</div>

new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})

全選結果 checkedNames: ["Jack", "John", "Mike"]

// 單個的話,能夠不用指定value,綁定的是一個布爾值
// 多個的話,爲了區分要指定value,否則就是一塊兒勾選,一塊兒不選,綁定的是一個數組,元素爲對應value
複製代碼

單選框radio

<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>
  <br>
  <span>Picked: {{ picked }}</span>
</div>

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

// 對於單選框,只有一個的話就沒有意義,由於點了就沒法取消
// 多個的話綁定的就是對應的value值
複製代碼

選擇框

// 單選
<div id="example-5">
  <select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>

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

// 多選
在select頭部加屬性multiple
Vue實例中的selected定義爲空數組
複製代碼

值綁定

把值綁定到 Vue 實例的一個動態屬性上,這時能夠用 v-bind 實現,而且這個屬性的值能夠不是字符串。

複選框

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

// 當選中時
vm.toggle === 'yes'
// 當沒有選中時
vm.toggle === 'no'
複製代碼

單選框

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

// 當選中時
vm.pick === vm.a
複製代碼

選擇框

<select v-model="selected">
    <!-- 內聯對象字面量 -->
  <option v-bind:value="{ number: 123 }">123</option>
</select>

// 當選中時
typeof vm.selected // => 'object'
vm.selected.number // => 123
複製代碼

修飾符

.lazy

在「change」時而非「input」時更新

<input v-model.lazy="msg" >
複製代碼

.number

自動將用戶的輸入值轉爲數值類型

<input v-model.number="age" type="number">
複製代碼

.trim

<input v-model.trim="xxx">
複製代碼
相關文章
相關標籤/搜索