手把手教你用指令(directives)寫個仿 element-ui 的v-loading

說來慚愧,用 Vue 這么長時間了倒得,今天第一次用指令立叛。

是出于什么契機呢壤躲?

主要是今天我們需要優(yōu)化一下 loading 的效果城菊,之前項目中用的都是 element-ui 的v-loading,現(xiàn)在我們網(wǎng)站的審美提上來了碉克,過去的效果已經(jīng)跟不上我們“羅網(wǎng)”的氣質(zhì)了凌唬。修改默認 loading 效果的方法千千萬,我為啥要自定義指令來寫一個 loading 呢漏麦,因為我沒用過客税,我就想用一下,我愿意撕贞,而且以后再做修改的話更耻,這個方案的可擴展性更好,想怎么改就怎改捏膨,不用摳摳搜搜地去改樣式秧均。

提示:本文只針對有 Vue 開發(fā)經(jīng)驗的同學(xué)『叛模看完這篇文章目胡,大家應(yīng)該能夠?qū)懸恍〇|西了,如果看完還不會链快,很正常誉己,每個人都有自己的天賦,對于不是自己天賦方面的東西多看幾遍就好了久又,大家都是智商正常的人類巫延,沒有什么東西是他能學(xué)會,你不能學(xué)會的地消,所以不用著急炉峰,跟著節(jié)奏慢慢來就可以。分享一個我奶奶留下來的家訓(xùn)“活到老脉执,學(xué)到老疼阔,還有一招學(xué)不到”,所以大家要對自己有信心。

今天排插炸了婆廊,還好沒炸的很大迅细,只是小小的炸了一下起了點火星子冒了點小煙,沒炸到臉淘邻。我可是沒開空調(diào)茵典、沒坐在電熱毯里,穿個睡衣坐在書桌前寫的文啊宾舅。還好有我們王剛王老師推薦的“每日堅果”補充能量统阿,加班寫文必備,代碼的好伴侶筹我,大家快去買扶平。

本文大綱

  • 什么是指令?
  • 常見的默認指令
  • 什么是自定義指令蔬蕊?我會帶著大家過一下 Vue 官網(wǎng)文檔上的demo
  • 結(jié)合具體的業(yè)務(wù)場景寫一個自定義的loading指定 结澄,暫定 v-cloading
  • 總結(jié) 指令比較適合哪些應(yīng)用場景
  • 參考文檔

什么是指令?

  • 指令是帶有 v-前綴的特殊屬性
  • 當表達式的值改變時岸夯,將其產(chǎn)生的 連帶影響麻献,響應(yīng)式地作用于 DOM

第一句換很好理解,第二句我們在接下來的demo中會讓你直觀的感受到這句話的意思囱修。

常見的默認指令

這里我們就列舉三個常見的指令赎瑰,想看更多指令可以看看 Vue 官方文檔王悍,或是 Vue指令基本使用大全這篇博文破镰,這篇文章列舉出了挺多的。

v-model

  • 作用:在表單元素上創(chuàng)建雙向的數(shù)據(jù)綁定

  • 說明:監(jiān)聽用戶的輸入事件以更新數(shù)據(jù)

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

v-on

  • 作用:綁定事件
  • 語法:v-on:click="say" or v-on:click="say('參數(shù)', $event)"
  • 簡寫:@click="say"
  • 說明:綁定的事件從methods中獲取
<!-- 完整語法 -->
<a v-on:click="doSomething"></a>
<!-- 縮寫 -->
<a @click="doSomething"></a>
<!-- 方法傳參 -->
<a @click="doSomething(“123”)"></a>

 <script>
    // 2 創(chuàng)建 Vue 的實例對象
    var vm = new Vue({
      el: '#app',
      // methods屬性用來給vue實例提供方法(事件)
      methods: {
        doSomething: function(str) {
          //接受參數(shù)压储,并輸出
          console.log(str);
        }
      }
    })
  </script>

v-bind

  • 作用:當表達式的值改變時鲜漩,將其產(chǎn)生的連帶影響,響應(yīng)式地作用于 DOM
  • 語法:v-bind:title="msg"
  • 簡寫::title="msg"
<!-- 完整語法 -->
<a v-bind:href="url"></a>
<!-- 縮寫 -->
<a :href="url"></a>
<script>
    // 2 創(chuàng)建 Vue 的實例對象
    var vm = new Vue({
      // el 用來指定vue掛載到頁面中的元素集惋,值是:選擇器
      // 理解:用來指定vue管理的HTML區(qū)域
      el: '#app',
      // 數(shù)據(jù)對象孕似,用來給視圖中提供數(shù)據(jù)的
      data: {
        url: 'http://www.baidu.com'
      }
    })
  </script>

什么是自定義指令

這里我會把 官方文檔上的 demo 和一些必要的說明搬過來。為什么要這么做刮刑?為了從來沒接觸過自定義指令的同學(xué)不用自己查找切換看文檔喉祭。只需要看完這一篇,了解一些基本的概念雷绢,就可以循序漸進的帶你寫一個 v-cloading 自定義loading的指令泛烙。如果有想了解源碼的同學(xué),可以暫時移步翘紊,網(wǎng)上有很多介紹 v-loading 帶你解讀源碼的文章蔽氨。這里我們是第一次使用,所以只會淺顯地介紹應(yīng)用。

Vue 官方文檔上都是以全局注冊為例子鹉究,在這里我們就都以局部注冊為例子宇立。

demo1:當頁面加載時,input 自動獲取焦點

我們先上代碼

<template>
  <div class="test-page">
    <!-- 我們的指令 v-fo我們的指令 -->
    <input type="text" v-focus>
  </div>
</template>
<script>
export default {
  // directives 不用多做解釋自赔,就是放指令的地方
  directives: {
    // focus 我們的指令名稱 這里我們寫focus就可以了妈嘹,Vue會默認給我們加上 v-的
    focus: { // 這個對象相當于我們?nèi)绾稳ッ枋龊投x這個 focus 指令
      // 當被綁定的元素插入到 dom 中時
      inserted: (el) => {
        // el 綁定指令的元素,聚焦
        el.focus()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.test-page {
  padding: 20px;
  input {
    width: 200px;
    height: 40px;
  }
}
</style>

在這里我們不用過多糾結(jié)每一行代碼是什么绍妨,比如 inserted 是什么蟋滴,inserted 是指令的一個鉤子函數(shù),不用著急痘绎,后面我們會具體介紹一下 指令的鉤子函數(shù)的津函。這個demo只是讓我們先感受下指令是什么,能做什么孤页,是不是很簡單尔苦,感覺自己隨隨便也能寫一個 demo 了。

結(jié)果:可以看到確實是頁面一加載就 input 就獲取到了焦點

image-20191221110017591.png

demo2:帶你感受指令的鉤子函數(shù)

雖然代碼應(yīng)該是很客觀很理性的東西行施,但是學(xué)習(xí)的過程中允坚,感受也很重要,感受會影響你想不想學(xué)蛾号,如果只是冰冷的定義我覺得會很難理解一個東西稠项。你感受到了,也自然就學(xué)會了鲜结。

我先列一下官網(wǎng)對于鉤子函數(shù)的定義和描述展运,然后我會結(jié)合具體的例子,讓大家感受一下鉤子函數(shù)是怎樣發(fā)揮作用的精刷,觸發(fā)的時機是什么拗胜。

一個指令定義對象可以提供如下幾個鉤子函數(shù)(均為可選):

  • bind:只調(diào)用一次,指令第一次綁定到元素時調(diào)用怒允。在這里可以進行一次性的初始化設(shè)置埂软。
  • inserted: 被綁定元素插入父節(jié)點時調(diào)用(僅保證父節(jié)點存在,但不一定已被插入文檔中)
  • update:所在組件的 VNode 更新時調(diào)用纫事,但是可能發(fā)生在其子 VNode 更新之前勘畔。指令的值可能發(fā)生了改變,也可能沒有丽惶。但是你可以通過比較更新前后的值來忽略不必要的模板更新炫七。
  • componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用
  • unbind:只調(diào)用一次,指令與元素解綁時調(diào)用蚊夫。

關(guān)于鉤子函數(shù)其實我理解的也不是和深刻诉字,就以 demo 去理解,如果有同學(xué)更加理解鉤子函數(shù),可以告訴我壤圃,大家一起交流一下陵霉。這個 demo 也是看別人寫的。

<template>
  <div class="test-page">
    <h1 v-color="color" v-if="show">{{title}}</h1>
    <button @click="show=false">測試解綁 v-color</button>
    <button @click="title='更換title'">更換 title</button>
    <button @click="color='blue'">更換 color</button>
  </div>
</template>
<script>
export default {
  data () {
    return {
      color: 'red',
      title: '自定義指令',
      show: true
    }
  },
  directives: {
    color: {
      bind: () => {
        console.log('bind')
      },
      inserted: (el, binding) => {
        console.log('inserted')
        el.style.color = binding.value
      },
      update: (el, binding) => {
        console.log('update value: ', binding.value)
        console.log('update oldValue: ', binding.oldValue)
        if (binding.value !== binding.oldValue) {
          el.style.color = binding.value
        }
      },
      componentUpdated: (el, binding) => {
        console.log('componentUpdated')
      },
      unbind: () => {
        console.log('v-color 指令解綁')
      }
    }
  }
}
</script>

當我們刷新頁面時伍绳,指令顯示被綁定到了 dom 上踊挠,然后被插入到了父節(jié)點中。


image-20191221135933395.png

當我們點擊 “更換title” 按鈕時冲杀,其實指定綁定的元素肯定是會更新的效床,但是指令的 value 值是還沒有更新的,仍然是 red权谁。

image-20191221140302702.png

當我們點擊 “更換 color” 按鈕時剩檀,指令的值就發(fā)生變化而,由 red 變成了 blue旺芽。

image-20191221140510817.png

當我們點擊 “測試解綁 v-color”沪猴,我們其實就是銷毀了指令所綁定的組件,指令就解綁了采章。

image-20191221140652888.png

demo3:鉤子函數(shù)參數(shù)

在上述 demo 中我們看到鉤子函數(shù)的參數(shù)有 el运嗜、binding 等,可能不是很理解悯舟,這一個 demo 就帶大家了解一下鉤子函數(shù)的參數(shù)担租。

照例我們先看看官網(wǎng)是怎么說明鉤子函數(shù)參數(shù)的。

  • el:指令所綁定的元素抵怎,可以用來直接操作 DOM

  • binding:一個對象奋救,包含一下屬性:

    • name:指令名,不包括v-前綴

    • value:指令的綁定值便贵,例如:v-my-directive="1 + 1" 中菠镇,綁定值為 2。

    • oldValue :指令綁定的前一個值承璃,僅在 updatecomponentUpdated 鉤子中可用。無論值是否改變都可用蚌本。

    • expression :字符串形式的指令表達式盔粹。例如 v-my-directive="1 + 1" 中,表達式為 "1 + 1"程癌。

    • arg:傳給指令的參數(shù)舷嗡,可選。例如 v-my-directive:foo 中嵌莉,參數(shù)為 "foo"进萄。

    • modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象為 { foo: true, bar: true }中鼠。

  • vnode:Vue 編譯生成的虛擬節(jié)點可婶。移步 VNode API 來了解更多詳情。

  • oldVnode:上一個虛擬節(jié)點援雇,僅在 updatecomponentUpdated 鉤子中可用矛渴。

Warning:

除了 el 之外,其它參數(shù)都應(yīng)該是只讀的惫搏,切勿進行修改具温。如果需要在鉤子之間共享數(shù)據(jù),建議通過元素的 dataset 來進行筐赔。

<template>
  <div class="test-page">
    <div v-demo:foo.a.b="message"></div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      message: 'hello!'
    }
  },
  directives: {
    demo: {
      bind: (el, binding, vnode) => {
        var s = JSON.stringify
        el.innerHTML =
          'name: ' + s(binding.name) + '<br>' +
          'value: ' + s(binding.value) + '<br>' +
          'expression: ' + s(binding.expression) + '<br>' +
          'argument: ' + s(binding.arg) + '<br>' +
          'modifier: ' + s(binding.modifiers) + '<br>' +
          'vnode keys: ' + Object.keys(vnode).join(', ')
      }
    }
  }
}
</script>

我們來看下結(jié)果:是不是很簡單參數(shù)就那些


image-20191221171512129.png

文檔中關(guān)于動態(tài)指令參數(shù)扬虚、字面量我就不接說了桂敛,大家自己看下文檔就可以了。

帶大家實現(xiàn)一個仿 element-UI 的 v-loading

上面的基本知識介紹了那么多,我們終于可以綜合運用來寫一個實用的例子了岭洲。

首先我們看下 element 的 v-loading 有哪些屬性


image-20191221172040629.png

但是這里我們不會實現(xiàn)上面那么多屬性,因為我懶逻翁,demo并非本人原創(chuàng)龙填,我只是做了修改。

我們今天的 demo 實現(xiàn):fullscreen text spinner background 等屬性尸曼,我們的自定義指令 我們就叫它 v-cloading 吧们何。需要loading的時候我們就創(chuàng)建一個實例,把它掛到父級元素上去控轿。

首先我們先準備一個 loading 的模板 mask.vue:

這個沒什么好講的冤竹,就是定義了一下 loading 的效果長什么樣

<template>
  <transition name="cv-loading-fade">
    <div
      v-show="visible"
      class="cv-loading-mask"
      :style="{ backgroundColor: background || ''}"
      :class="[customClass, { 'is-fullscreen': fullscreen }]">
      <div class="cv-loading-spinner">
        <div class="loading-animation-box">
          <span class="circle purple-circle"></span>
          <span class="circle green-circle"></span>
        </div>
        <span class="cv-loading-text">{{text}}</span>
      </div>
    </div>
  </transition>
</template>
<script>
export default {
  data () {
    return {
      text: null,
      background: null,
      fullscreen: true,
      visible: false,
      customClass: ''
    }
  },
  mounted () {
    if (this.fullscreen) {
      document.body.style.overflow = 'hidden'
    }
  },
  methods: {
    setText (text) {
      this.text = text
    }
  },
  destroyed () {
    document.body.style.overflowX = 'hidden'
  }
}
</script>
<style lang="scss" scoped>
@import "assets/styles/variables.scss";
.cv-loading-fade-enter,
.cv-loading-fade-leave-active {
  opacity: 0;
}
.cv-loading-mask {
  position: absolute;
  z-index: 2000;
  background-color: rgba(255, 255, 255, 0.9);
  margin: 0;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  transition: opacity 0.3s;
  &.is-fullscreen {
    position: fixed;
    .cv-loading-spinner {
      margin-top: -25px;
    }
  }
}
.cv-loading-spinner {
  top: 50%;
  margin-top: -21px;
  width: 100%;
  text-align: center;
  position: absolute;
  .loading-animation-box {
    position: relative;
    width: 64px;
    height: 64px;
    margin: 0 auto;
    .circle {
      position: absolute;
      display: inline-block;
      width: 14px;
      height: 14px;
      border-radius: 50%;
      top: 25px;
      transition: all;
      &.purple-circle {
        background-color: $primary_color;
        left: 10px;
        animation: leftAnimation 1.5s ease-in-out infinite;
      }
      &.green-circle {
        background-color: $sub_color;
        right: 10px;
        animation: rightAnimation 1.5s ease-in-out infinite;
      }
    }
  }
  .cv-loading-text {
    margin: 3px 0;
    font-size: 14px;
    color: #5D37EC;
  }
}
@keyframes leftAnimation {
  0% {
    transform: scale(1) translateX(0px);
    z-index: 1;
  }
  25% {
    transform: scale(1.5) translateX(15px);
    z-index: 5;
  }
  50% {
    transform: scale(1) translateX(30px);
    z-index: 5;
  }
  75% {
    transform: scale(0.5) translateX(15px);
    z-index: 5;
  }
  100% {
    transform: scale(1) translateX(0px);
    z-index: 1;
  }
}
@keyframes rightAnimation {
  0% {
    transform: scale(1) translateX(0px);
    z-index: 1;
  }
  25% {
    transform: scale(0.5) translateX(-15px);
    z-index: 1;
  }
  50% {
    transform: scale(1) translateX(-30px);
    z-index: 1;
  }
  75% {
    transform: scale(1.5) translateX(-15px);
    z-index: 5;
  }
  100% {
    transform: scale(1) translate(0px);
    z-index: 1;
  }
}
</style>

接下來我們看下最關(guān)鍵的部分,指令的實現(xiàn)部分茬射,其實這部分的代碼和 element v-loading 本身的實現(xiàn)比較相似鹦蠕。雖然這塊代碼還不算特別完善,但是基本的實現(xiàn)是可以的在抛,這塊我會重點講一下钟病。等我認真閱讀完 element-UI v-loading 的源碼后,會再進行完善的刚梭。

import Vue from 'vue'
import maskLoading from './mask.vue'

// 我們通過模板 構(gòu)造一個 Mask
const Mask = Vue.extend(maskLoading)
// Mask 是否需要更新肠阱,也就是 loading 展示效果是否需要更新
const toggleLoading = (el, binding) => {
  // 如果指令傳入的值為 true 或是有值,就顯示這個模板朴读,掛到父級元素上去或是body上
  if (binding.value) {
    Vue.nextTick(() => {
      if (binding.modifiers.fullscreen) {
        // 全屏的話就掛載到 body 上
        document.body.appendChild(el.mask)
      } else {
        // 非全屏就掛到當前組件上去
        let height = el.clientHeight
        let width = el.clientWidth
        let offsetTop = el.offsetTop
        el.mask.style.top = offsetTop + 'px'
        el.mask.style.height = height + 'px'
        el.mask.style.width = width + 'px'
        el.appendChild(el.mask)
      }
    })
  } else {
    // 如果傳入的值是 false屹徘,或是沒有值,就銷毀 Mask
    el.mask && el.mask.parentNode && el.mask.parentNode.removeChild(el.mask)
    el.instance && el.instance.$destroy()
  }
}

Vue.directive('cloading', {
  bind (el, binding) {
    // 指令第一次綁定到元素上時衅金,初始化一些屬性噪伊,這些屬性可以通過字面量的形式傳簿煌,也可以通過 dataset或是其他方式,我還沒想好鉴吹。
    let background = binding.value.background
    let text = binding.value.text
    let iconSrc = binding.value.iconSrc
    let iconWidth = binding.value.iconWidth
    let iconHeight = binding.value.iconHeight
    let color = binding.value.color
    let fontSize = binding.value.fontSize
    console.log('binding.value: ', binding.value)
    // 構(gòu)造了一個 Mask 實例
    const mask = new Mask({
      el: document.createElement('div'),
      data: {
        fullscreen: !!binding.modifiers.fullscreen,
        background: background || '255, 255, 255, 0.9',
        text: text || '加載中...',
        iconSrc: iconSrc || require('../../assets/images/icn_loading.png'),
        iconWidth: iconWidth || null,
        iconHeight: iconHeight || null,
        color: color || null,
        fontSize: fontSize || null
      }
    })
    el.instance = mask
    el.mask = mask.$el
    // 更新 Mask的展示
    toggleLoading(el, binding)
  },
  // 所在組件的 VNode 更新時調(diào)用
  update (el, binding) {
    if (binding.oldValue !== binding.value) {
      toggleLoading(el, binding)
    }
  },
  unbind (el) {
    el.mask && el.mask.parentNode && el.mask.parentNode.removeChild(el.mask)
    el.instance && el.instance.$destroy()
  }
})
<div
     :style="{height: '1000px', width: '100%'}"
     v-cloading.fullscreen="true"
     >
</div>

這樣寫下來姨伟,發(fā)現(xiàn)也沒什么可講的,一切都很自然拙寡。

鐺鐺~授滓,我們來看下效果:

q8mnk-doexw.gif

還蠻好看的。是不是很簡單肆糕。

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末般堆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子诚啃,更是在濱河造成了極大的恐慌淮摔,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件始赎,死亡現(xiàn)場離奇詭異和橙,居然都是意外死亡,警方通過查閱死者的電腦和手機造垛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門魔招,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人五辽,你說我怎么就攤上這事办斑。” “怎么了杆逗?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵乡翅,是天一觀的道長。 經(jīng)常有香客問我罪郊,道長蠕蚜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任悔橄,我火速辦了婚禮靶累,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘橄维。我一直安慰自己尺铣,他們只是感情好,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布争舞。 她就那樣靜靜地躺著,像睡著了一般澈灼。 火紅的嫁衣襯著肌膚如雪竞川。 梳的紋絲不亂的頭發(fā)上店溢,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音委乌,去河邊找鬼床牧。 笑死,一個胖子當著我的面吹牛遭贸,可吹牛的內(nèi)容都是我干的戈咳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼壕吹,長吁一口氣:“原來是場噩夢啊……” “哼著蛙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起耳贬,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤踏堡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咒劲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體顷蟆,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年腐魂,在試婚紗的時候發(fā)現(xiàn)自己被綠了帐偎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛔屹,死狀恐怖削樊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情判导,我是刑警寧澤嫉父,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站眼刃,受9級特大地震影響绕辖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜擂红,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一仪际、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧昵骤,春花似錦树碱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹦玫,卻和暖如春赎婚,著一層夾襖步出監(jiān)牢的瞬間刘绣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工挣输, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留纬凤,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓撩嚼,卻偏偏與公主長得像停士,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子完丽,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 先了解一下,在 vue 中,有很多內(nèi)置的指令. 比如: v-for 用于遍歷 v-if & v-show 用于隱藏...
    人話博客閱讀 22,754評論 6 67
  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,209評論 0 6
  • 從感性的角度講恋技,我是不屑于用VUE,覺得react套件用起來更順手舰涌,但是vue現(xiàn)在越來火猖任,所以也不得入vue(雜燴...
    zhoulujun閱讀 1,451評論 0 1
  • 一、了解Vue.js 1.1.1 Vue.js是什么瓷耙? 簡單小巧朱躺、漸進式、功能強大的技術(shù)棧 1.1.2 為什么學(xué)習(xí)...
    蔡華鵬閱讀 3,321評論 0 3
  • 不知道這些天都干嘛去了搁痛? 錢长搀、錢沒掙著,一分沒掙鸡典; 田地沒有種源请,一分田也沒有; ……………………………… 唉彻况,自己...
    人生若只如初16閱讀 504評論 0 0