1.監聽第三方組件的生命週期鉤子
通過使用 @hook
: 前綴監聽生命週期中的鉤子,並指定回調函數。
舉個例子,如果你想要在第三方組件 v-runtime-template 渲染時做一些事情,那麼你可以監聽它的生命週期中的 updated 鉤子:
<v-runtime-template @hook:updated="doSomething" :template="template" />
2.用Object.freeze 方法阻止vue的data中數據響應
比如我們請求的數據是一個很大的數據列表。如地圖的標記點 markers 列表數據,這就是一個擁有很多對象的大型數組,我們不會對這些數據進行操作,其實可以理解成這是一個常量。
export default {
data: () => ({
users: {}
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
}
};
如果你確實有需要去修改請求得到的列表數據,那麼你仍然可以通過創建一個新的數組來實現。
this.users = Object.freeze([...this.users, user]);
3.Vue.js 2.6.0 中的新指令 v-slot
(1)作用域插槽
原方法:
<template>
<List :items="items">
<template slot-scope="{ filteredItems }">
<p v-for="item in filteredItems" :key="item">{{ item }}</p>
</template>
</List>
</template>
然而,我們可以直接在組件標籤上使用新指令v-slot
,避免了額外的嵌套:
記住 v-slot
指令只能用在組件或 template
標籤上,而不能使用在原生 html 標籤上
<template>
<List v-slot="{ filteredItems }" :items="items">
<p v-for="item in filteredItems" :key="item">{{ item }}</p>
</List>
</template>
(2)v-slot
指令也提供了一個綁定slot
和scope-slot
指令的方式,但是需要使用一個 : 來分割它們
原方法:
<template>
<Promised :promise="usersPromise">
<p slot="pending">Loading...</p>
<ul slot-scope="users">
<li v-for="user in users">{{ user.name }}</li>
</ul>
<p slot="rejected" slot-scope="error">Error: {{ error.message }}</p>
</Promised>
</template>
v-slot
指令重寫如下:
<template>
<Promised :promise="usersPromise">
<template v-slot:pending>
<p>Loading...</p>
</template>
<template v-slot="users">
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</template>
<template v-slot:rejected="error">
<p>Error: {{ error.message }}</p>
</template>
</Promised>
</template>
v-slot
以符號 # 作爲其指令的簡寫模式,v-slot
指令默認應該簡寫爲#default
:
<template>
<Promised :promise="usersPromise">
<template #pending>
<p>Loading...</p>
</template>
<template #default="users">
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</template>
<template #rejected="error">
<p>Error: {{ error.message }}</p>
</template>
</Promised>
</template>
4.$attrs/$listeners
使用
假設我們有一個基礎組件,比如說 BaseList,然後你想要在此基礎上創建一個有額外功能的相類似的組件,比如說 SortableList。我將其稱作爲自適應組件(或者是代理組件、包裝組件)。
注意如果父組件是通過rander出來的無效,爲啥?
//在父組件當中,最外層組件
<template>
<div>
<Child1 :child1Info="child1" :child2Info="child2" v-on:test1="onTest1" v-on:test2="onTest2">
</Child1>
</div>
</template>
<script>
import Child1 from './child1';
export default {
data() {
return {
child1:"hahha",
child2:"asdsdasd"
};
},
components: { Child1 },
methods: {
onTest1(msg) {
console.log('test1 running...',msg);
},
onTest2(msg) {
console.log('test2 running',msg);
}
}
};
</script>
inheritAttrs
屬性默認是true
就是$prop
和原生屬性(style ,value,placeholder)
都會傳遞下去設置爲flase
原生屬性除了class
都不會傳下去
//在子組件中
<template>
<div class="child-1">
<p>在子組件當中:</p>
<p>props-child1Info: {{child1Info}}</p>
<p>$attrs: {{$attrs}}</p>
<hr>
<!-- Child2組件中能直接觸發test的原因在於 B組件調用C組件時 使用 v-on 綁定了$listeners 屬性 -->
<!-- 通過v-bind 綁定$attrs屬性,Child2組件可以直接獲取到A組件中傳遞下來的props(除了child1組件中props聲明的) -->
<Child2 v-bind="$attrs" v-on="$listeners" inheritAttrs="false"></Child2>
</div>
</template>
<script>
import Child2 from './child2';
export default {
props: ['child1Info'], //$attr會剔除child1Info屬性
data() {
return {};
},
components: { Child2 },
mounted() {
this.$emit('test1','嘻嘻');
}
};
</script>
//在孫子組件當中:
<template>
<div class="child-2">
<p>在最裏層組件當中child2:</p>
<p>props-child2Info: {{child2Info}}</p>
<p> $attrs 的值: {{$attrs}}</p>
<hr>
</div>
</template>
<script>
export default {
props: ['child2Info'],
data() {
return {};
},
mounted() {
this.$emit('test2','哈哈');
}
};
</script>
5.動態組件 & is 的用法
Vue 文檔中關於動態組件部分的描述大概就是:使用保留的 元素配合動態綁定的 is 屬性就可以在同一個掛載點切換不同的組件
這裏面動態的關鍵在於 is 屬性,而不在於 ,換句話說,就是隨便你用什麼標籤,只要有 is 屬性,它就算是動態組件, 當然你也可以靜態地給 is 賦值一個字符串,不過這樣它就只能表示某一個組件,失去了動態的意義了。
文檔中有個render的列子
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // tag name
this.$slots.default // array of children
)
},
props: {
level: {
type: Number,
required: true
}
}
})
其實就單單這個例子來說,也可以使用 is + template 的方法,比 render function 還要簡潔直觀:
<script type="text/x-template" id="anchored-heading-template">
<component :is="'h' + level">
<slot></slot>
</component>
</script>
6.將組件插入body中
mounted放法中寫
this.$nextTick(() => {
const body = document.querySelector("body");
if (body.append) {
body.append(this.$el);
} else {
body.appendChild(this.$el);
}
});
7. 修改scoped樣式
// 普通樣式中
.a >>> .b { /* ... */ }
// sass 、less
.a{
/deep/ .b{
/* ... */
}
}
8.定時器清除
一般我們都是在beforeDestroy()
生命週期內清除定時器,但是下面這個方法更加簡潔
const timer = setInterval(() =>{
// 某些定時器操作
}, 500);
// 通過$once來監聽定時器,在beforeDestroy鉤子可以被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer);
})
類似於其他需要在當前頁面使用,離開需要銷燬的組件(例如一些第三方庫的picker組件等等),都可以使用此方式來解決