Vue + ElementUI 後臺管理系統項目心得(二)

此篇是關於 Vue 的總結。Js 的總結請見前一篇:Vue + ElementUI 後臺管理系統項目心得(一)javascript

話說過完年回來,彷彿一晚上之間身邊的人都在談論 Vue,相關的組件也如雨後春筍通常涌現出來,好比大名鼎鼎的 Element UIiView 還有不久前剛發佈的 ATUI,這些組件庫雖然實現方式和接口格式有所不一樣,但大都界面美觀,體驗流暢,能夠說和 Vue 框架提供的良好性能是密不可分的。css

Vue 是一個上手簡單,卻富有內涵的框架,既能夠像使用 jQuery 同樣簡單地經過 <script> 標籤引入,也支持經過打包工具構建。html

// 一個簡單的title.vue模板文件,同時具有了Web三要素:結構層、表現層和行爲層。
<template>
  <div class="box">
    <span class="title-text">title</span>
  </div>
</template>

<script> export default { name: 'TitleBox', }; </script>

<style> .title-text{ font-size:18px } </style>複製代碼

擴展名爲 vue 的文件會被打包工具編譯成標準 js 文件以供瀏覽器執行,在編譯時 <template> 模板的內容會被轉換爲 render 函數,換句話說 <template> 的內容只是一個配置參數,Vue 經過這種相似於 HTML 的結構來生成渲染方法,最後經過執行渲染方法來初始化一個真正的頁面。固然對於複雜的需求咱們也能夠不用模板,直接編寫 render 函數。vue

相似的還有 data 屬性,咱們一般使用這樣的格式來定義 datajava

data() {
    return {
        commonData,
        layout,
        isShow: true,
        isLoading: false
    };
}複製代碼

事實上這只是一個配置選項,編譯時 Vue 會根據咱們傳入的選項來生成真正的 data 實例,其中的每一個屬性都綁定了 gettersetter 方法,具有響應式特性。這就是爲何須要顯式的定義 data 屬性。後端

默認狀況下 data 內的屬性會被 Vue 實例代理(Vue 實例的同名屬性指向 data 對象的屬性),若是某些屬性不想被 Vue 代理能夠在屬性名稱前面加上 '$''_' ,這樣就只能經過 Vue.$data._someProp 來訪問。數組

在實例化一個 Vue 對象時會經歷那些階段呢?通俗的說會有兩個階段:一是生成 data,二是掛載 template,也就是 MVVM 中的 VM(view-model)。瀏覽器

生成 data 被稱做 create,掛載 template 被稱做 mount,兩個階段的先後分別對應着兩組生命週期節點,也就是 beforeCreatecreated 以及 beforeMoundmounded框架

有生則有滅,銷燬響應式屬性,解除綁定事件的過程被稱做 destroy,先後也分別對應着 beforeDestroydestroyed 節點。異步

響應式屬性的變化會觸發視圖的更新,這個更新的過程被稱做 update,先後天然也對應着 beforeUpdateupdated 兩個節點。數據與視圖綁定是 VM 框架提供的核心功能,也正是所謂的數據驅動,數據驅動和事件驅動的差別有點相似於查詢和中斷的區別。

組件是一個封閉的環境,除非經過生命週期節點來探測,否則操做內部數據的進度是沒法獲知的,換句話說咱們從組件外部訪問 data 數據時,沒法肯定它是更新前仍是更新後的,尤爲在經過異步方式請求後端數據時,這個問題就更加明顯。所以官方不建議經過 $parent$children$refs 等方式強行獲取數據,而是建議在數據狀態可控時經過事件觸發來回傳數據($emit、$on)。

經常使用的模板語法

  • 大鬍子語法(雙大括號)能夠方便的在 HTML 元素內部(innerHTML)插入文本。
<span> {{ status ? '有效' : '無效' }} </span>複製代碼
  • 設置模板標籤屬性能夠直接用 <span prop="text"></span> 的格式書寫,若是須要爲屬性綁定變量或表達式則需使用 v-bind 指令:<span :prop="value"></span>,沒錯,冒號 ':' 正是 v-bind 指令的縮寫,等同於 <span v-bind:prop="value"></span>,有時咱們須要綁定數值(Number),而非內容爲數字的字符串,v-bind 指令剛好能夠區分二者。
// 後端發送的數據
requiredData: {cityId: 3}

// 模板綁定的數據
<ex-select v-model="cityId">
    <ex-option :value="1">北京</option>
    <ex-option :value="2">上海</option>
    <ex-option :value="3">廣州</option>
    // 若是不加 ':' 會由於 3 !== '3'而找不到匹配項 
</ex-select>複製代碼
  • 另外一個支持縮寫的指令是 v-on ,能夠用 '@' 表示,好比 <button @click="handleClick"></button>,指令較多時,縮寫可使代碼更清晰。
<ex-input v-model="userName" :placeholder="姓名" :disabled="isDisabled" :readonly="isReadonly" @focus="handleFocus" @input="handleInput" @change="handleChange">
</ex-input>複製代碼
  • 控制流程的指令包括:v-ifv-elsev-else-ifv-for
// 判斷單行或多行文本框
<input type="text" v-if="inputType==='singleLine'"></input>
<textarea v-else="inputType==='multiLine'"></textarea>

// v-for 除了能夠生成列表,還能夠用於經過 JSON 動態生成模板
let formConfig = [{
    type: 'singleLine',
    name: 'userName'
},{
    type: 'singleLine',
    name: 'birthday'
},{
    type: 'multiLine',
    name: 'comment'
}]

<label v-for="item in formConfig">
    {{ item.name }}
    <ex-input inputType="item.type"></ex-input> </label>複製代碼
  • 計算屬性能夠用於篩選或格式化數據,好比當後端返回時間戳時,咱們可經過計算屬性獲取指定格式的日期時間。
data() {
    return {
        updateTime: 1490526754
    }
}

computed: {
    timeString: {
        get () {
            // Js默認以毫秒爲單位,須要進行轉換
            let timeStamp = new Date(this.updateTime * 1000)
            return timeStamp.toLocaleString()
        },
        set (val) {
            let timeStamp = Math.round(Date.getTime() / 1000)
            this.updateTime = val || timeStamp
        }
    }
}複製代碼
  • 如何響應式更新 data 中的數組?
    有時咱們須要在數據表格組件中顯示一組數據,後端返回給咱們一個 JSON 數組:
<ex-table
    data="dataSource"
></ex-table> ... data () { return { dataSource: [{ id: 1, name: lily, age: 21 },{ id: 2, name: terry, age: 23 },{ id: 3, name: dill, age: 26 }] } }複製代碼

咱們修改了其中的某一項,並經過下面的方式更新到數組中:

let modifiedRow = {id: 2, name: frank, age: 20}
// 視圖未發生更新
this.dataSource[1] = modifiedRow複製代碼

咱們會發現,表格中顯示的數據並無改變,這是由於直接對數組中的元素賦值不會觸發Vue的響應式更新,爲了解決 Js 語言特性的限制,Vue 提供了一種變通的方法,可使用 push()pop()shift() 等函數來修改數組。

// 視圖響應式更新
dataSource.splice(1, 1, modifiedRow)複製代碼

除此以外咱們也能夠經過 Vue.set() 函數修改數組,好比:

Vue.set(dataSource, 1, modifiedRow)複製代碼
  • 經過 v-model 指令爲表單元素綁定數據

表單元素不但能夠顯示數據也能夠修改數據,咱們固然能夠經過 :value="data" 來顯示數據,而且經過 @input="data=$event.target.value" 來修改數據,不過 Vue 爲咱們提供了一個更簡潔的語法糖,直接使用 v-model="data" 便可同時實現二者的功能。

其實,對於任何自定義組件只要咱們實現了 value 屬性和 input 事件均可以使用 v-model 指令進行數據綁定。若是實現了 change 事件也能夠配合 v-model.lazy 來調用。

// ex-input.vue
<input 
    type="text" 
    v-if="inputType==='singleLine'"
    :value="editValue"
    @input="handelInput"
></input>
<textarea 
    v-else="inputType==='multiLine'"
    :value="editValue"
    @input="handelInput"
></textarea>
...
data() {
    return {
        // 獲取表單初始值
        editValue: this.value
    }
},
prop: {
    // 定義value屬性
    value:[String, Number]
},
watch: {
    // 觀察並同步value屬性
    value(val) {
        this.editValue = val
    }
},
methods: {
    handelInput (event) {
        this.editValue = event.target.value
        // 實現input事件
        this.$emit('input', this.editValue)
    }
}
...
// 二者是等價的,顯然 v-model 更簡潔一些
<ex-input v-model="data"></ex-input>
<ex-input :value="data" @input="data=arguments[0]"></ex-input>複製代碼

(未完待續...)

相關文章
相關標籤/搜索