通过使用 @hook
: 前缀监听生命周期中的钩子,并指定回调函数。
举个例子,如果你想要在第三方组件 v-runtime-template 渲染时做一些事情,那么你可以监听它的生命周期中的 updated 钩子:
<v-runtime-template @hook:updated="doSomething" :template="template" />
比如我们请求的数据是一个很大的数据列表。如地图的标记点 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]);
(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>
$attrs
/$listeners
使用$attrs
与$listeners
的主要应用是实现多层嵌套传递。
组件A与组件B通信一般都会使用组件B中转,即A传递给B,B再给C,但是如果A到C组件之间嵌套的组件过多,需要传递的事件和属性较多,会导致代码繁琐,代码维护困难。在vue2.4中,为了解决该需求,引入了$attrs
和$listeners
,新增了inheritAttrs
选项
具体使用查看:$attrs
/$listeners
的使用
在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量
不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据。
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>
mounted放法中写
this.$nextTick(() => {
const body = document.querySelector("body");
if (body.append) {
body.append(this.$el);
} else {
body.appendChild(this.$el);
}
});
// 普通样式中
.a >>> .b { /* ... */ }
// sass 、less
.a{
/deep/ .b{
/* ... */
}
}
一般我们都是在beforeDestroy()
生命周期内清除定时器,但是下面这个方法更加简洁
const timer = setInterval(() =>{
// 某些定时器操作
}, 500);
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer);
})
类似于其他需要在当前页面使用,离开需要销毁的组件(例如一些第三方库的picker组件等等),都可以使用此方式来解决