time: 2021.2.20
author: heyunjiang
今天在回顾 vue 全局注册组件时,看到 vue 文档中有一些自己没有用过的知识点,比如 v-once 做性能优化,x-template 编写模板等。
现在打算对 vue2 做个知识点完整回顾,对比源码查看,对一些不太熟悉的边角总结在这里。
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@Prop(Number) readonly propA: number | undefined
@Prop({ default: 'default value' }) readonly propB!: string
@Prop([String, Boolean]) readonly propC: string | boolean | undefined
}
疑问
通常在 vue 组件中使用生命周期,是在配置的 beforeDestroy 等属性方法中实现,vue 提供了程序化监听事件,编写方式如下
this.$on('hook:beforeDestroy', cb)
this.$once('hook:beforeDestroy', cb)
在递归渲染中,可以使用自身组件或其他组件
export default {
name: 'MyComponent',
template: `
<div>
<template v-if="count < 5">
<my-component></my-component>
</template>
</div>
`
}
<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>
此刻定义的模板,会替代子组件本身的模板(未验证),并且当前模板作用域是子组件的作用域,同 slot 不同,slot 是父组件作用域
另外,也可以使用 script + text/x-template 来替代 <template>
的写法,别名:inDomTemplate
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
export default {
template: '#hello-world-template'
}
通过设置 functional
在 template 根节点上,或添加 functional: true 属性,可以让当前组件变为函数式组件;
通过设置 v-once
在 template 根节点上,可以让内容只计算一次就缓存起来,后续不再更新。
2者有什么区别?
可以控制在初始、离开、进入、active 等时机的动画、相应的 @enter 等钩子函数,包括列表 flip 过度动画都可以实现。后续做动画相关的,可以深入研究这块
.vue 文件
:template 最终都会通过 vue-loader 编译为 render 函数,内部使用 compiler 模块编译template 选项
,会被 compileToFunctions 方法编译成 render、staticRenderFns 函数,内部使用 compiler 模块编译render 函数
,我们也可以直接写 render 函数,内部返回 createElement(‘div’, [createElement(‘span’, ‘hello’), this.$slots.default]) 来生成内容jsx
: 是因为有一个 babel 插件 @vue/babel-preset-jsx,在 babel 转换的时候,将 jsx 转换成普通 render 的 createElement 方法createElement 及函数参数
createElement({
// string | object | function,必填
'div',
// 与模板中 attribute 属性对应, 可选
{
class: {
foo: true,
bar: false
},
style: {
fontSize: '12px'
},
attrs: {
id: 'hello'
},
props: {},
key: 'key',
...
},
// children, string | array, 可选
[]
})
动态组件指 vue 内置的 component
组件,基本使用如下
<component :is="currentComponent" />
使用说明
使用场景:顾名思义,当前渲染的组件需要根据运行时环境条件来确定,是一个动态渲染的过程
问题:为什么不使用 v-if 来判断?
答:动态组件比 v-if 写法更简洁;对于一些异步加载的组件,组件名不能确定
原理概括
_c(_vm.currentComponents,{tag:"component"})
,处理还是回到 createElement 方法中去Ctor = resolveAsset(context.$options, 'components', tag)
获取组件配置对象,然后再 vnode = createComponent(Ctor, data, context, children, tag)
,同普通组件渲染流程一样vue-class-component vue class 写法
vue-property-decorator 对 vue-class-component 的 decorator 补充实现