1. 動態屬性名:可使用表示式來設定動態屬性名或方法名:
<!-- 屬性name -->
<a :[name]="url"> ... </a>
<!-- 計算屬性sss和s -->
<img :[sss]="/img/test.png"/>
<!-- 方法change1和change2 -->
<img :[change1()]="change2()"/>
data: {
name: 'href',
sss: 'src'
}
複製程式碼
注意:要避免空格和引號等,且需要小寫,可使用計算屬性來應對複雜表示式,都需要使用[]
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
則每次都會進行計算,但可傳參。 -
watch
用於處理非同步或開銷較大的操作,如輸入搜尋時。
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
,進而input
的value
值在切換後還會被保留,因為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-show
是display:none
和block
之間的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和textarea
- 修飾符
.number
:輸入值轉為數值 - 修飾符
.trim
:過濾收尾空白字元
12. Prop
- 使用
v-bind="obj"
會將物件的每個屬性都作為一個獨立的prop
傳入進去,所以接受時也需要逐個屬性接收。
<test v-bind="obj"></test>
複製程式碼
props
雖然是單向資料流,但對於引用型別,子元件還是可以改變父元件的狀態。props
會在元件例項建立之前進行驗證,所以例項的屬性再default
或validator
中是不可用的。
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
指當前路由 -
萬用字元:捕獲所有路由或
404 Not found
路由
// 含萬用字元的路由都要放在最後,因為優先順序由定義順序決定
{
// 會匹配所有路徑
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
棧新增一個新的記錄 -
使用了
push
時,如果提供的path
不完整,則params
會被忽略,需要提供路由的name
或手寫完整的帶有引數的path
:
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轉換規則
- 如果是絕對路徑,例如
/images/foo.png)
,則會原樣保留。 - 如果路徑以
.
開頭,將會被看作相對的模組依賴,並按照你的本地檔案系統上的目錄結構進行解析。 - 如果路徑以
~
開頭,其後的部分將會被看作模組依賴。 - 如果路徑以
@
開頭,也會被看作模組依賴。