本文已参与「新人创作礼」活动,一起开启掘金创作之路。
六、动态组件
1、在动态组件上使用keep-alive
<component v-bind:is="currentTabComponent"></component>
在一个多标签的界面上使用is特性来切换不同的组件。当在这些组件之间切换的时候,会反复重新渲染。
当你想保持这些组件的状态时,即标签的组件实例能够被在它们第一次被创建的时候缓存下来,可以使用<keep-alive>元素将其动态组件包裹起来。
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
2、异步组件
以下工厂函数方式定义的组件,只有在这个组件需要被渲染的时候才会触发该工厂函数。
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack自动将你的构建代码切割成多个包,这些包会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
resolve 回调函数会在你从服务器得到组件定义的时候被调用。
七、处理边界情况
1、访问元素、组件
①访问根实例:
在每个 new Vue 实例的子组件中,其根实例可以通过 $root 属性进行访问。
this.$root.foo = 2 //写入根组件数据
②访问父级组件实例:
$parent 属性可以用来从一个子组件访问父组件的实例。
③在JS里直接访问一个子组件:
通过 ref 特性为这个子组件赋予一个 ID 引用,例如输入聚焦
<base-input ref="usernameInput"></base-input>
this.$refs.usernameInput //访问base-input实例
$refs 只会在组件渲染完成之后生效,并且它们不是响应式的,应避免在模板或计算属性中访问
2、依赖注入
依赖注入用到了两个新的实例选项:provide 和 inject
provide 选项允许我们指定我们想要提供给后代组件的数据/方法。
在任何后代组件里,都可以使用 inject 选项来接收想要添加在这个实例上的属性
3、事件侦听
通过 $on(eventName, eventHandler) 侦听一个事件
通过 $once(eventName, eventHandler) 一次性侦听一个事件
通过 $off(eventName, eventHandler) 停止侦听一个事件
4、循环引用
①递归组件:
组件在自己的模板中调用自身,通过name:‘组件名’ 来实现,注意确保递归调用是条件性的
②循环引用:
当父引用子,子引用父时,通过Vue.component全局注册组件是没问题,但是若通过webpack则会出错
此时可以通过以下两种方式解决
beforeCreate: function () {
this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue').default
} //等到生命周期钩子beforeCreate时去注册它
components: {
TreeFolderContents: () => import('./tree-folder-contents.vue')
} //在本地注册组件时使用 webpack 的异步 import
5、内联模板
当 inline-template 特性出现在一个子组件上时,这个组件将会使用其里面的内容作为模板。
内联模板需要定义在 Vue 所属的 DOM 元素内。
<my-component inline-template> ... </my-component>
6、X-Template
X-Template需要定义在 Vue 所属的 DOM 元素外。
在一个<script>元素中,并为其带上 text/x-template的类型,然后通过一个 id 将模板引用过去。
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})
7、通过v-once创建低开销的静态组件
组件包括了大量的静态内容,可以在根元素上添加v-once特性,确保这些内容只计算一次后缓存起来