理理Vue細節

1. 動態屬性名:可以使用表達式來設置動態屬性名或方法名:

<!-- 屬性name -->
<a :[name]="url"> ... </a>
<!-- 計算屬性sss和s -->
<img :[sss]="/img/test.png"/>  
<!-- 方法change1和change2 -->
<img :[change1()]="change2()"/>

data: {
    name: 'href',
    sss: 'src'
}
複製代碼

注意:要避免空格和引號等,且須要小寫,可以使用計算屬性來應對複雜表達式,都須要使用[]html

2. computed/methods/watch

  • computed可以使用get/set
computed: {
       top() {
           return 'top'
       },
       name: {
           get () {
               return this.name
           },
           set (val) {
               this.name = val
           }
       }
   }
複製代碼
  • computed可緩存,但不可傳參,會根據data中的屬性變化而變化,便是根據響應式依賴來變化,而Date不是響應式依賴,即不會變化;method則每次都會進行計算,但可傳參。vue

  • watch用於處理異步或開銷較大的操做,如輸入搜索時。webpack

3. style綁定

  • 直接對象或變量對象
  • 計算屬性
  • 直接style或style對象
<!-- 屬性名可加引號也可不加,屬性小駝峯 -->
<div :style="{ 'color': 'red', fontSize: fontSize + 'px' }">樣式3</div>
複製代碼
  • 數組結合三目/數組結合對象
data: {
  isActive: true,
  activeClass: 'active'
}
<!-- 使用數組時變量和字符串須要經過引號來區分 -->
<div :class="[isActive ? activeClass : '', 'errorClass']"></div>
<!-- 使用對象時類名不加引號可表示變量也可表示字符串 -->
<div :class="[{ active: isActive }, 'errorClass']"></div>
複製代碼

4. v-if條件渲染

  • 可以使用template包裹元素,template會被當成不可見的包裹元素
<template v-if="ok">
    <h1>Title</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
</template>
複製代碼
  • 多條件判斷
<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
複製代碼

5. key

  • 添加key防止vue重複利用不想被重複利用的元素,以下的input若是不添加key,則vue會重複使用key,進而inputvalue值在切換後還會被保留,由於vue僅僅替換了placeholder
<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>
複製代碼

6. v-if和v-show

  • v-if是組件的銷燬和重建,若是初始條件爲false,則什麼都不作,直到變爲真,因此切換開銷高,運行條件不多改變時適用
  • v-showdisplay:noneblock之間的CSS切換,基於渲染,無論初始條件如何都會渲染,因此初始渲染開銷高,切換頻率高時適用

7. v-for

  • 可以使用in或者of
  • 也可遍歷對象:v-for="(value, key, index) in obj"
  • 可根據template渲染多個組合元素:
<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider"></li>
  </template>
</ul>
複製代碼

8. v-for和v-if

  • v-for優先級更高,因此v-if會重複運行於每一個v-for循環中,因此儘可能不要一塊兒使用,可先使用計算屬性對數據進行過濾再遍歷。

9. 更改響應式數據

  • Vue.set(object, key, value)
  • this.$set(object, key, value)
  • this.items.splice(index, 1, newValue)
  • 批量添加屬性:
// 不要直接Object.assign(this.items, {age: 18}
this.items = Object.assign({}, this.items, {
  age: 18,
  favoriteColor: 'Vue Green'
})
複製代碼

10. 事件修飾符

  • .passive:滾動的默認事件會當即出發,即告訴瀏覽器不想阻止默認事件的觸發,可提高移動端性能
<div @scroll.passive="onScroll">...</div>
複製代碼
  • .capture:添加事件監聽器時使用事件捕獲模式,即元素自身觸發的事件先在此處理,而後才交由內部元素進行處理
  • .self:只當在 event.target 是當前元素自身時觸發處理函數,即事件不是從內部元素觸發的
  • .once:點擊事件只會觸發一次
  • 鍵盤修飾符:<input @keyup.enter="submit">

11. v-model

  • 選擇框
<!-- 單選框時,picked爲字符串 "a",不是布爾值 -->
<input type="radio" value="a" v-model="picked">

<!-- 多選框時,toggle默認值設爲字符串或布爾值時獲得布爾值,設爲數組時獲得的是value值-->
<input type="checkbox" value="b" v-model="toggle">

<!-- 當選中第一個選項時,selected爲字符串value的值 "abc" -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>
複製代碼
  • 修飾符.lazy:在change時而非input時更新 <input v-model.lazy="msg" >

注:change事件是在input失去焦點時觸發,即用於單選、多選框和選擇框,而input事件是在value值變化時觸發,但腳本改變value值時不會觸發,即用於text和textareaios

  • 修飾符.number:輸入值轉爲數值
  • 修飾符.trim:過濾收尾空白字符

12. Prop

  • 使用v-bind="obj"會將對象的每一個屬性都做爲一個獨立的prop傳入進去,因此接受時也須要逐個屬性接收。
<test v-bind="obj"></test>
複製代碼
  • props雖然是單向數據流,但對於引用類型,子組件仍是能夠改變父組件的狀態。
  • props會在組件實例建立以前進行驗證,因此實例的屬性再defaultvalidator中是不可用的。

13. 自定義事件

  • 自定義事件須要注意事件名爲小寫或-分隔,由於$emit('BaseEvent')雖然事件名不會變,但在html中該事件名會被轉化爲小寫,不會監聽到。

14. slot

  • 具名插槽
<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>
<!-- 默認插槽也可不用加上template和v-slot -->
  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>
  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
複製代碼
  • 做用域插槽
<!-- current-user組件 -->
<span>
  <slot :user="user">
    {{ user.lastName }}
  </slot>
</span>

<!-- 父級組件經過自定義名稱訪問子級做用域 -->
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

<!-- 支持縮寫和解構 -->
<current-user>
  <template #default="{ user = { firstName: Gust } }">
    {{ user.firstName }}
  </template>
</current-user>
複製代碼

15. 組件通訊

  • vuex/eventBus
  • prop/$emit
  • $children/$parent
  • provide/inject
  • $refs
// 父或祖先級
provide: function () {
  return {
    getMap: this.getMap
  }
}

// 後代級
inject: ['getMap']
複製代碼

16. scope

  • scoped 屬性會自動添加一個惟一的屬性 (好比 data-v-21e5b78) 爲組件內 CSS 指定做用域,編譯的時候 .list-container:hover 會被編譯成相似 .list-container[data-v-21e5b78]:hover

17. 路由

  • 區分:this.$router指路由器,this.$route指當前路由web

  • 通配符:捕獲全部路由或 404 Not found路由vuex

// 含通配符的路由都要放在最後,由於優先級由定義順序決定
{
  // 會匹配全部路徑
  path: '*'
}
{
  // 會匹配以 `/user-` 開頭的任意路徑
  path: '/user-*'
}
複製代碼
  • 當使用一個通配符時,$route.params內會自動添加一個名爲 pathMatch 參數。它包含了 URL 經過通配符被匹配的部分:
// 給出一個路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 給出一個路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'
複製代碼
  • 點擊 <router-link :to="..."> 等同於調用 router.push(...)方法,由於<router-link>會在內部調用該方法,進而在history棧添加一個新的記錄json

  • 使用了push時,若是提供的path不完整,則params會被忽略,須要提供路由的 name 或手寫完整的帶有參數的 pathaxios

const userId = '123'
router.push({ name: 'user', params: { userId }})  // -> /user/123
router.push({ path: `/user/${userId}` })          // -> /user/123
// 這裏的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
複製代碼
  • router.push/router.replace/router.go 效仿於 window.history.pushState/window.history.replaceState/window.history.go數組

  • 命名視圖:router-view可設置名字,若是router-view沒有設置名字,那麼默認爲 default瀏覽器

<router-view></router-view>
<router-view name="a"></router-view>
<router-view name="b"></router-view>

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      } 
    }
  ]
})
複製代碼
  • 路由使用props:可將路由參數設置爲組件屬性
const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}
// 經過布爾值設置
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },

    // 對於包含命名視圖的路由,你必須分別爲每一個命名視圖添加 `props` 選項:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

// 經過函數設置query 
// URL /search?q=vue 會將 {name: 'vue'} 做爲屬性傳遞給 SearchUser 組件
const router = new VueRouter({
  routes: [
    { path: '/search', component: SearchUser, props: (route) => ({ name: route.query.q }) }
  ]
})
複製代碼
  • beforeRouteEnter:可以使用beforeRouteEnter來提早獲取接口數據,同時須要在next後才能訪問到實例:
beforeRouteEnter(to, from, next) {
  axios('/text.json').then(res => {
    next(vm => {
      vm.datas = res
    })
  })
}
複製代碼
  • 路由設置有參數時,若是跳轉頁面後再經過返回鍵返回時,路由會保留有參數,若是經過push跳轉返回,則不會保留該參數,這在第三方調用模塊傳參時須要注意。

18. loader

  • Vue Loader編譯單文件的template塊時,會將全部遇到的URL資源轉爲webpack模塊請求:
// <img src="../image.png">將會被編譯成爲:
createElement('img', {
  attrs: {
    src: require('../image.png') // 如今這是一個模塊的請求了
  }
})
複製代碼
  • 資源URL轉換規則
  1. 若是是絕對路徑,例如 /images/foo.png),則會原樣保留。
  2. 若是路徑以.開頭,將會被看做相對的模塊依賴,並按照你的本地文件系統上的目錄結構進行解析。
  3. 若是路徑以~開頭,其後的部分將會被看做模塊依賴。
  4. 若是路徑以 @ 開頭,也會被看做模塊依賴。

後續會持續更新,歡迎關注!

相關文章
相關標籤/搜索