基礎特性
漸進式開發
可以 單HTML頁面 使用Vue,也可以整個項目使用Vue
生命週期
- beforeCreate 實例開始初始化時同步調用,數據觀測和事件尚未初始化
- created 實例創建之後調用,完成數據綁定,事件方法。Document尚未掛載
- beforeMount 在Document掛載之前運行
- mounted 編譯結束時調用。指令已生效,數據變化已能觸發DOM更新 (不保證$el已經插入文檔)
- beforeUpdate 再次更新實例時會調用,此時DOM尚未更新
- Updated 再次更新實例並更新完DOM後調用
- beforeDestroy 開始銷燬實例時調用,此刻實例仍有效
- destroyed 實例被銷燬之後調用
數據綁定
文本插值
最基礎的形式,使用 雙大括號{{}} (源自Mustache語法)
<span>Hello {{name}}</span>
插值也可以應用在HTML屬性中
<div id='id_{{blogId}}'></div>
// 2.0 寫法
<div v-bind:id='"id_"+blogId'/>
<div :id='"id_"+blogId'/>
過濾器
過濾器可以用在兩個地方:雙花括號插值 和 v-bind 表達式 (後者從 2.1.0+ 開始支持)。過濾器應該被添加在 JavaScript 表達式的尾部,由“管道”符號指示
<!-- 在雙花括號中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
計算屬性
類比Java的 Getter 和 Setter ,先將數據進行處理。
var vm = new Vue({
el:'#app',
data:{
firstName:'NEW',
lastName:'CIH'
},
computed:{
fullName:function(){
return this.firstName + ' ' + this.lastName
}
}
})
該用例即爲 單頁面使用Vue 的用法
表單控件
Vue提供 v-model 指令對錶單元素進行雙向綁定,修改表單元素同時,實例中的對應屬性值也會同時更新。
- Text
<input type="text" v-model="email"/>
<span>Your input is {{email}}</span>
- Radio
<input type="radio" value="male" v-model="gender">男
<input type="radio" value="famale" v-model="gender">女
<span>選擇的性別是 {{gender}}</span>
- CheckBox
<input type="checkbox" value="1" v-model="multiChecked">1
<input type="checkbox" value="2" v-model="multiChecked">2
<input type="checkbox" value="3" v-model="multiChecked">3
<input type="checkbox" value="4" v-model="multiChecked">4
<span>你選擇了 {{multiChecked.join('|')}} </span>
- Select
<select v-model="selected">
<option selected>A</option>
<option>B</option>
<option>C</option>
</select>
<span>你選擇了 {{selected}} </span>
Class及Style綁定
<div class="tab" v-bind:class="{'active':active}"></div>
// Vue實例中必須有
data:{
active:false
}
指令
內置指令
- v-bind 動態綁定DOM元素屬性
- v-model 綁定表單控件
- v-if 及 v-else 根據條件展示對應的模板內容
<div v-if="yes"> yes </div>
<div v-else> no </div>
- v-show 功能同v-if,
v-if 與 v-show 的區別:v-if在條件爲false的情況下並不進行模板的編譯,而v-show則會在模板編譯好之後將元素隱藏掉。v-if的切換消耗比v-show高,但初始條件爲false的情況下,v-if的初始渲染要稍快
- v-for
<ul>
<li v-for=item in items">
<h1> {{item.title}} </h1>
</li>
</ul>
- v-on 事件綁定
<button v-on:click='popLoginDialog'></button>
// 簡寫
<button @click='popLoginDialog'></button>
v-text 更新元素的文本值
v-HTML 用於更新元素的innerHTML,接受的字符串不會進行編譯操作,按普通HTML處理。
<div v-HTML="blogContent"></div>
- v-el 在DOM元素註冊一個索引,使得可以直接訪問DOM元素。(通過$els屬性調用)
<div v-el:blog-content> there is a blog el </div>
// 獲取文本,vm即爲該實例名
vm.$els.blogContent.innerText
由於HTML不區分大小寫,在v-el如果使用了駝峯命名,系統會自動轉換成小寫。但可以使用 - 來連接期望大寫的字母
- v-ref 功能同 v-el,作用於子組件上。(通過$refs訪問)
- v-pre 跳過編譯該元素
- v-cloak 可以隱藏未編譯的Mustache標籤直到實例準備完畢 (解決閃現問題)
<div v-cloak> {{message}} </div>
官方推薦搭配如下 CSS 屬性一起使用
[v-cloak]{
display:none
}
- v-once 標明元素或組件只渲染一次。(即使隨後發生綁定數據的變化或更新,該元素或組件及包含的子元素都不會被編譯和渲染)
自定義指令
通過 Vue.directive(id, definition) 可以註冊一個全局指令
組件
組件選項與Vue選項的區別
在Vue中,屬性的賦值是直接賦值
var vm = new Vue({
el : '#app',
data : {
name : 'newcih'
}
})
而在組件中需要定義
var MyComponent = Vue.extend({
data : function() {
return {
name : 'newcih'
}
}
})
因爲自定義組件可能擁有多個實例,如果直接將對象data傳遞給Vue.extend({}),那所有使用中的組件實例都會共享該data對象,所以需要通過函數返回一個新對象
組件Props
選項Props是組件中非常重要的一個選項。組件實例的作用域是孤立的,子組件的模板和模塊中是無法直接調用父組件的數據,所以通過Props將父組件的數據傳遞給子組件
Vue.component('my-child', {
props : ['parentContent'],
template : '<span> {{parentContent}} is from parent </span>'
})
<my-child parent-Content="This data"></my-child>
同指令,註冊組件的Props也要注意駝峯命名的轉換,即通過 - 連接字母來達到大寫字母的目的
一個完整的組件代碼
文件名 components/Test.vue
<template>
<!-- 存放模板代碼 -->
<div v-if="isLogin">
Welcome, {{name}}
<button @click="login">登錄</button>
</div>
</template>
<script>
export default {
// 存放數據
data () {
return {
name : 'newcih'
}
},
// 生命週期函數
created : function () {
// 方法調用
},
// 計算屬性
computed : {
isLogin () {
return true
}
},
// 監聽函數
watch : {
'name' (newValue, oldValue) {
// 變量name的值變化時觸發
}
},
// 事件及自定義函數
methods : {
login : function () {
}
}
}
</script>
<style scoped>
<!-- 存放css代碼 -->
</style>
狀態管理
Vuex是狀態管理模式的一種實現庫,主要以插件的形式和Vue.js進行配合使用,能夠使我們在Vue.js中管理複雜的組件事件流。
在一些大型應用中,有時會遇到單頁面應用包含着大量的組件及複雜的數據結構,而且可能各種組件還會相互影響各自的狀態,在這種情況下組件樹中的事件流會很快變得非常複雜,也使調試變得困難。爲了解決這種情況,我們往往引入 狀態管理 這種設計模式。
- Store 倉庫,用於存儲整個應用所需要的信息
- State 狀態,Store中的數據
- Mutations 變更,更新Store的接口
一個完整的狀態管理實現
文件名 vuex/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
isLogin: true
},
mutations: {
UPDATE_LOGIN_STATE (state, loginState) {
state.isLogin = loginState
}
},
getters: {
getLoginState: state => {
return state.isLogin
}
}
})
觸發 mutations 的方式可以爲
this.$store.commit('UPDATE_LOGIN_STATE', true)
獲取 state 數據的方式可以爲
return this.$store.getters.getLoginState
獲取 State 數據推薦在計算屬性中獲取,即放置到 computed 中執行
開發實踐
項目結構
- my-project
- build 存放webpack相關配置和腳本
- config 存放配置文件,用於區分開發環境,測試環境,線上環境的不同
- src 項目源碼及需要引用的資源文件
- assets
- components
- App.vue
- main.js
- static 不需要webpack處理的靜態資源
- test 用於存放測試文件
- .babelirc
- .editorconfig
- .eslintignore
- .eslintrc.js
- .gitignore
- index.html 項目入口,嵌入了App.vue組件
- package.json
- README.md
配置代理服務器
設置 config/index.js 文件中的屬性如下
// proxyTable中添加'/api'表明 : 接口'/api'開頭的才使用代理,其它的如靜態資源則使用本地文件
proxyTable : {
'/api' : {
target : 'http://my.service.com',
changeOrigin : true,
pathRewrite : {
'^/api' : '/api'
}
}
}
// pathRewrite表明 : 將前端的接口代理URL中開頭的 **/api** 替換爲 **/api**,如果後臺服務提供的接口並沒有 **/api** 等前綴,則可以寫爲如下
pathRewrite : {
'^/api' : ''
// 或者是
'^/api' : '/'
}
使用Axios發送請求
Axios是Vue 2.0後作者推薦的,不再維護vue-resource。Axios的使用手冊可 點擊查看
基本使用如下
// 發送Get請求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 發送Post請求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Axios的Post請求默認發送的是 JSON 格式的數據,如果後臺使用SpringMVC搭建,則可以使用註解 @RequestBody 接受參數
插件
開發插件
開發的插件必須提供 install 方法,第一個參數是 Vue構造器,第二個參數是可選的選項對象。一個例子如下
require('es6-promise').polyfill()
import axios from 'axios'
import {Promise} from '[email protected]@es6-promise'
export const Axios = axios.create({
baseURL: '',
timeout: 5000
})
// POST傳參序列化(添加請求攔截器,即localStorage如果有token字段,則帶上該字段到請求頭的authentication字段)
Axios.interceptors.request.use(config => {
if (localStorage.token) {
config.headers.authentication = localStorage.token
}
return config
}, error => {
return Promise.reject(error)
})
export default {
install (Vue) {
Object.defineProperty(Vue.prototype, '$http', {value: Axios})
}
}
額外專題:關於 Promise
Promise是抽象異步處理對象以及對其進行各種操作的組件。在使用Promise進行一步處理的時候,我們必須按照接口規定的方法編寫處理代碼,而不會像回調函數那樣可以自己自由的定義回調函數的參數,而必須遵守統一的編程方式來編寫代碼。Promise的功能是可以將複雜的異步處理輕鬆地進行模式化。
構造函數
var promise = new Promise(function(resolve, reject) {
// 異步處理
// 處理結束後,調用resolve或reject
}
靜態方法
- Promise.reject() 返回一個使用接受到的值進行reject的新的promise對象
- Promise.resolove() 具有 .then 方法的對象。
使用Promise
- 創建promise對象
- new Promise(fn) 返回一個promise對象
- 在 fn 中指定異步處理
- 處理結果正常,調用 resolve(處理結果值)
- 處理結果錯誤,調用 reject(Error對象)
- 創建XHR的promise對象
function getURL(URL) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function() {
if (req.status == 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function() {
reject(new Error(req.statusText));
};
req.send();
});
}
// 運行示例
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value) {
console.log(value);
}).catch(function onRejected(error) {
console.error(error);
});
使用插件
通過全局方法 Vue.use() 使用插件
// 調用 NewPlugin.install(Vue)
Vue.use(NewPlugin)
// 或是傳入選項對象
Vue.use(NewPlugin, {someOption : true})
Vue.js 官方提供的一些插件 (例如 vue-router) 在檢測到 Vue 是可訪問的全局變量時會自動調用 Vue.use()。然而在例如 CommonJS 的模塊環境中,你應該始終顯式地調用 Vue.use():
// 用 Browserify 或 webpack 提供的 CommonJS 模塊環境時
var Vue = require('vue')
var VueRouter = require('vue-router')
// 不要忘了調用此方法
Vue.use(VueRouter)
Vue的插件庫,點擊進入
實踐視頻
後續發佈