vue文檔裏你沒撿起來的寶藏

第一次在掘金寫文章vue

  • 不一樣於在csdn上平日記錄給本身和別人解決問題,更想主動分享和討論
  • 我的能力有限,解決小問題,歡迎討論指正

第一篇文章想寫Vue的緣由是剛買了一本《深刻淺出 Vue.js 》,因此趁書沒到,打算把Vue的文檔從新看一遍(不得不讚Vue的文檔,當年從Angular轉Vue的時候看文檔簡直,舒服了~~)vuex

本文主要內容:數組

  • 來源於Vue文檔
  • 你可能看過
  • 可是你可能沒用過

vue的數據響應失效了

你知道什麼狀況下,vue的數據響應會是失效嗎? 官方舉了個例子:瀏覽器

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是響應性的
vm.items.length = 2 // 不是響應性的
複製代碼

在平常的業務的處理中,尤爲是數組的for循環渲染,當你使用完v-for以後,動態的經過操做index指定數組的值,不是響應的。 咱們使用實際業務代碼舉個例子:緩存

<template>
  <div>
    <div v-for="(item,key) in list" :key="key">
      {{item}}
    </div>
    <button @click="changeList">失效</button>
    <button @click="respondList">響應</button>
    {{list}}
  </div>
</template>

<script>
export default {
  name: 'ex',
  data () {
    return {
      list: [11, 12, { money: 17 }]
    }
  },
  methods: {
    changeList () {
      // 失效代碼
      this.list[0] = 16
      this.list.length = 0
    },
    respondList () {
      // 生效代碼
      this.list[2].money = 0
      this.list[0] = 16
    }
  }
}
</script>
複製代碼

而後咱們來看一下會發生什麼bash

在這裏插入圖片描述
這就頗有意思了,咱們能夠看到這個過程當中,執行changeList()方法,頁面上的11並無變成16且數組也沒有變爲空數組,可是執行第二個方法時,this.list已經爲空數組,致使報錯。也就驗證了官網所說沒錯,咱們不能夠直接操做數組的item值,你想要的響應並不會發生。

可是!你們可能會發現,好像本身項目裏常常有這種操做,可是沒有發生這種問題,那麼咱們來看一下是什麼致使咱們在項目中忽略了這個問題。 請看: 框架

在這裏插入圖片描述
我直接執行了respondList (),可是能夠看到this.list[0] = 16這句也跟着一塊兒響應了,這就是爲何咱們平常項目中沒有出現這個問題的緣由。

由於在平常項目中不多會有單獨寫一個方法去改list[index],一般會伴隨着其餘的對數組或者數組中對象的一些操做,而這些操做會觸發Vue的響應,Vue響應不是響應咱們的代碼過程,他響應的是結果,而咱們的代碼過程只是意味着是否會觸發Vue對代碼結果的響應。函數

  • 簡單說,執行第一個方法,裏面的2行代碼將list變爲了空數組,可是這2行代碼都不會觸發Vue去響應,顧,頁面不變。
  • 執行第二個方法,this.list[2].money = 0除了將money變爲了0還觸發了Vue的響應機制,也就是方法執行完以後Vue會對list進行更新,因此第2行this.list[0] = 16將整個list修改完以後,方法結束,Vue更新list

因此咱們要規避在Vue直接去單獨對數組的[index]和length去賦值,注意!是單獨ui

vue的數據響應又又失效了?

你沒看錯,vue的數據響應又要上演失效了,此次的失效可能你日常項目中寫過不少,可是 你仍是沒注意過! 該知識點來源於vue文檔的列表渲染裏面的一小段提示代碼:this

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 如今是響應式的

vm.b = 2
// `vm.b` 不是響應式的
複製代碼

闊怕,你歷來沒想過你在項目中obj.a=1會不生效,這其中文檔中有2句話很重要:

仍是因爲 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除。 對於已經建立的實例,Vue 不能動態添加根級別的響應式屬性。

相信個人加粗已經讓你意識到了問題所在,至於平常中爲何沒有感受到失效是和上個例子同樣的,固然官方爲這種單獨操做對象屬性方法

Vue.set(object, key, value)

具體使用方法能夠回看文檔。

不止在{{}}中可使用函數

我要表達的意思是不止在雙括號中可使用函數,v-for也能夠。 固然若是有人不知道雙括號可使用函數,咱們先來演示一遍:

<template>
  <div>
    <div v-for="(item,key) in list" :key="key">
      {{filterList(item)}}
    </div>
  </div>
</template>

<script>
export default {
  name: 'ex',
  data () {
    return {
      list: [0, 1, 2]
    }
  },
  methods: {
    filterList (item) {
      if (item > 0) {
        return '大於0'
      } else {
        return item
      }
    }
  }
}
</script>
複製代碼

在這裏插入圖片描述
好的,接下來,文檔告訴咱們一個技巧,直接看官網示例:

<li v-for="n in evenNumbers">{{ n }}</li>
複製代碼
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}
複製代碼

能夠直接用一個函數來代替v-for中的list,這樣能夠結合計算屬性避免咱們在每次獲取數據等業務場景下從新單獨處理list。

函數中直接調用當前元素的原生事件

首先說一下這個技巧適用於:

  1. 你要爲某個元素綁定一個事件
  2. 你的事件裏可能須要操做業務的同時,根據業務操做瀏覽器原生事件

綁定事件時能夠用特殊變量 $event 把它傳入方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>
複製代碼
// ...
methods: {
  warn: function (message, event) {
    // 如今咱們能夠訪問原生事件對象
    if (event) event.preventDefault()
    alert(message)
  }
}
複製代碼

該技巧適應場景有限,可是至少你要記住,vue能夠直接在實踐中綁定event,去操做原生事件,由於總有一天你會發現有些p需求須要你去實現……

Vue的修飾符不少你知道嗎

有v-once也有.once

你們知道vue推薦對低開銷的靜態內容使用v-once渲染,可是若是你仔細看過文檔你應該知道v-once,首先v-once的原理實際上是keep-alive,它會緩存v-once的組件,可是但願你再閱讀一次官方這句提示:

再說一次,試着不要過分使用這個模式。當你須要渲染大量靜態內容時,極少數的狀況下它會給你帶來便利,除非你很是留意渲染變慢了,否則它徹底是沒有必要的——再加上它在後期會帶來不少困惑。例如,設想另外一個開發者並不熟悉v-once 或漏看了它在模板中,他們可能會花不少個小時去找出模板爲何沒法正確更新

是的,除非你這個組件渲染的開銷已經嚴重到你以爲他明顯的慢,不然不要使用。

而後咱們來講事件的.once

<!-- 點擊事件只會執行一次 -->
<form @click.once="submit"></form>
複製代碼

要注意不能將其應用於按鈕的點擊以後,它不一樣於按鈕的loading,點擊按鈕打開loading若是執行錯誤能夠關閉loading,按鈕能夠再次執行。

而使用.once事件觸發過一次以後,不會再次執行,固然你能夠將它應用於其餘事件,可是你要記住存在一個能夠只讓你的事件只觸發一次的修飾符,總會用到的。

你認爲的type="number"

你們在表單中若是要是用數字類型的input的時候一般咱們會使用type=number,可是也許沒有人注意到input真正返回是什麼,好比:

<template>
  <div>
    {{age}}
    <input v-model.number="age" type="number" @change="lookAge">
    {{year}}
    <input v-model="year" type="number" @change="lookYear">
  </div>
</template>

<script>
export default {
  data () {
    return {
      age: null,
      year: null
    }
  },
  methods: {
    lookAge () {
      console.log(this.age)
    },
    lookYear () {
      console.log(this.year)
    }
  }
}
</script>
複製代碼

這一小段那代碼有什麼區別呢?

在這裏插入圖片描述
首先,在渲染上,至少結果都是正確的,console的結果也是沒問題的,可是console調試的時候,藍色數字和白色數字有什麼區別,也許不少人都沒注意過這個問題,回看看文檔就可讓你理解我剛纔提出的問題,文檔原文:

若是想自動將用戶的輸入值轉爲數值類型,能夠給 v-model 添加 number 修飾符:

<input v-model.number="age" type="number">

這一般頗有用,由於即便在 type="number" 時,HTML 輸入元素的值也總會返回字符串。若是這個值沒法被 parseFloat() 解析,則會返回原始的值。 是滴,我以爲這對於用ts的人極其和諧。

若是你看到了上面的.number修飾符,那你必定能夠在文檔中接着看到.trim修飾符:

若是要自動過濾用戶輸入的首尾空白字符,能夠給 v-model 添加 trim 修飾符:

<input v-model.trim="msg">

這個問題我以前還真是遇見過,惋惜我使用的方法是用js的trim去單獨處理了一遍,卻不知文檔如此簡單,我居然很差好閱讀!

最後一個小技巧了

首先講一講個人菜鳥路程,在使用prop的時候剛開始我都是這樣寫:

props: {
  title,
  author
}
複製代碼

後來我這樣寫:

props: {
  title: String,
  author: Object
}
複製代碼

再後來我這樣寫:

props: {
  title:{
      type: String,
      required: true
    },
  author:{
      type: Object,
      required: true
    }
}
複製代碼

而後我讀文檔發現還能夠這樣寫:

props: {
  // 帶有默認值的對象
  title:{
      type: String,
       // 對象或數組默認值必須從一個工廠函數獲取
      default: function () {
        return { message: 'hello' }
      }
    },
  // 自定義驗證函數
  author:{
      validator: function (value) {
        // 這個值必須匹配下列字符串中的一個
        return ['au', 'th', 'or'].indexOf(value) !== -1
      }
    }
}
複製代碼

是的,prop也帶有驗證功能,且可使用自定義驗證函數! 發現這算是個小技巧,可是最重要的在這段文檔後面:

當 prop 驗證失敗的時候,(開發環境構建版本的) Vue 將會產生一個控制檯的警告。

注意那些 prop 會在一個組件實例建立以前進行驗證,因此實例的屬性 (如 data、computed 等) 在 default 或validator 函數中是不可用的。

最關鍵一句在驗證函數中:data和計算屬性中的變量和方法都不可用。

到這就結束了,這是我最近利用上下班時間我vue文檔過了一遍,願意主動將裏面的一些遺漏或日常項目中不多用到,一直與忘記的小內容分享給各位。

若是有用給個評論,若是沒用不要吐槽我好很差,求大家了,哈哈。

第一次分享,排版通常,仍是但願有反饋的,若是有反饋,下次分享一篇基於某開源框架源碼下的vuex實用代碼分析

相關文章
相關標籤/搜索