众所周知,Vue有两种版本,完整版(vue.js) 和 运行时版(vue.runtime.js)。
完整版:
-
- 完整版包含 编译器(
compiler)和 运行时(vue.runtime.js),功能强大,可以直接将html或者template中占位符进行替换,而运行时版本不行,只能通过render(h){}将想要显示的数据渲染到页面。
- 完整版包含 编译器(
-
- 编译器的功能是将模板字符串编译为
Javascript渲染函数(render(h))的代码
- 编译器的功能是将模板字符串编译为
-
- 运行时的功能包括创建
Vue实例、渲染并处理虚拟DOM等除了编译器的其它所有功能
- 运行时的功能包括创建
运行版:
- 只包含
vue.runtime.js
同时,这两个版本又都有开发环境和生产环境,开发环境的代码都是未经过压缩的,里面是正常的代码和注释,而生产环境中的代码就是将所有代码中间没有必要的空格、换行、注释都去掉,将所有代码压缩为一行。
对于用户(coders)其实更多关心的是,哪个能更快的加载出我想要的页面,这个时候运行时版本优点就出来了:
- 体积小,用户体验好,但只支持h函数
- 对于
coders们来说,只能写h函数,面对一些复杂的需求时,需要写出复杂的标签组合,开发体验不好, 因为没有compiler,coders们就不能写出更直观更语义化的HTML标签和template,所以我们需要一个compiler vue-loader就可以引入compiler,把Vue文件里的HTML标签和template会在构建时预编译成h函数
template 和 render 用法对比:
//需要编译器
new Vue({
template: '<div>{{ hi }}</div>'
})
//不需要编译器
new Vue({
render(h) {
return h(div'', this.hi)
}
})
说了这么多,终于到了,今天的主题vue的函数式组件,顾名思义,.vue文件也可以只起到一个函数的作用。
组件的定义:
Vue提供了一种可以让组件变为无状态、无实例的函数化组件,从原理上说,一般子组件都会经过实例化的过程,而单纯的函数组件并没有这个过程,它可以简单理解为一个中间层,只处理数据,不创建实例,也是由于这个行为,它的渲染开销会低很多。实际的应用场景是,当我们需要在多个组件中选择一个来代为渲染,或者在将children,props,data等数据传递给子组件前进行数据处理时,我们都可以用函数式组件来完成,它本质上也是对组件的一个外部包装。
该组件没有管理任何状态,也没有监听任何传递给他的状态,也没有生命周期访问,(理解为 没有常规组件的 data() 也没有 this,因此优点是 渲染开销低很多 轻量 灵活。
组件标志:
functional: true
没有this的影响:
- 没有
template标签,写上也不会编译 - 所有属性通过
render(h, context)的context传递,即context.props
组件的使用场景:
- 定义两个组件对象 demo1 demo2
let demo1 = {
props: ['msg'],
render: function(createElement, context) {
return createElement('h1', this.msg)
}
}
let demo2 = {
props: ['msg'],
render: function(createElement, context) {
return createElement('h2', this.msg)
}
}
- 定义一个函数组件,它会根据计算结果选中其中一个组件进行选项:
Vue.component('demo3', {
//函数式组件的标志,functional设置为true
funcitonal: true,
props: ['msg'],
render: function(createElement, context) {
var get = function() {
return demo1
}
return createElement(get(), context)
}
})
- 函数式组件的使用:
<demo3 :msg="msg" id="demo3"> </demo3>
new Vue({
el: '#app',
data: {
msg: 'demo'
}
})
最终渲染结果为:
<h2>demo</h2>