之前创建的锚点标题组件是比较简单,没有管理或者监听任何传递给他的状态,也没有生命周期方法,它只是一个接受参数的函数

在这个例子中,我们标记组件为functional,这意味它是无状态(没有data),无实例(没有this上下文)

一个函数化组件就像这样:

Vue.component('my-component', {
functional: true,
// 为了弥补缺少的实例
// 提供第二个参数作为上下文
render: function (createElement, context) {
// ...
},
// Props 可选
props: {
// ...
}
})
 

注意:在2.3.0之前的版本中,如果一个函数式组件想要接受props,则props选项是必须的,在2.3.0及以上的版本中,你可以省略props选项,所有组件上的属性都会被自动解析为props。

组件需要的一切都是通过上下文传递的,包括:

  • props:提供props对象
  • children:VNode子节点的数组
  • slots:slots对象
  • data:传递给组件的data对象
  • parent:对父组件的引用
  • listeners:(2.3.0+)一个包含了组件上所注册的v-on侦听器的对象。这只是一个指向data.on的别名
  • injections:(2.3.0+)如果使用了inject选项,则该对象包含了应当被注入的属性

在添加functional:true之后,锚点标题组件的render函数之间简单更新增加context参数,this.$slots.default更新为context.children,之后this.level更新为context.props.level.

因为函数化组件只是一个函数,所以渲染开销也低很多。然而,对持久化实例的缺乏也意味着函数化组件不会出现在vue devtools的组件树里。

在作为包装组件时它们也非常有用,比如你需要做这些时:

  • 程序化的在多个组件中选择一个
  • 在将children,props,data传递给子组件之前操作它们。

下面是一个依赖传入props的值的smart-list组件例子,它能代表更多具体的组件:

var EmptyList = { /* ... */ }
var TableList = { /* ... */ }
var OrderedList = { /* ... */ }
var UnorderedList = { /* ... */ }
 
Vue.component('smart-list', {
functional: true,
render: function (createElement, context) {
function appropriateListComponent () {
var items = context.props.items
 
if (items.length === 0) return EmptyList
if (typeof items[0] === 'object') return TableList
if (context.props.isOrdered) return OrderedList
 
return UnorderedList
}
 
return createElement(
appropriateListComponent(),
context.data,
context.children
)
},
props: {
items: {
type: Array,
required: true
},
isOrdered: Boolean
}
})

slots()和children对比

你可能想知道为什么同时需要slots()和children。slots().default不是和children类似的吗?在一些场景中,是这样,但是如果是函数式组件和下面的这样的children呢?

<my-functional-component>
<p slot="foo">
first
</p>
<p>second</p>
</my-functional-component>
对于这个组件,children会给你两个段落标签,而slots().default只会传递第二个匿名段落标签,slots().foo会传递第一个具名段落标签。同时拥有children和slots(),因此你可以选择让组件通过slot()系统分发或者简单的通过children接收,让其他组件去处理。
 
模板编译
你可能有兴趣知道,vue的模板实际上是编译成了render函数。这是一个实现细节,通常不需要关心,但如果你想看看模板的功能是如何编译出来的,你会发现非常有趣,下面是一个使用vue.compile来实时编译模板字符串的简单demo:

<div>
<header>
<h1>I'm a template!</h1>
</header>
<p v-if="message">
{{ message }}
</p>
<p v-else>
No message.
</p>
</div>

render:

function anonymous() {
with(this){return _c('div',[_m(0),(message)?_c('p',[_v(_s(message))]):_c('p',[_v("No message.")])])}
}
staticRenderFns:
_m(0): function anonymous() {
with(this){return _c('header',[_c('h1',[_v("I'm a template!")])])}
}

vue render函数 函数组件化的更多相关文章

  1. vue render 渲染函数

    vue render 渲染函数 经常看到使用render渲染函数的示例,而且在一些特殊情况下,确实更好使用,可以更加有效地细分组件,因而借助vue-element-admin来学习一波 render函 ...

  2. vue(9)—— 组件化开发 - webpack(3)

    前面两个终于把webpack相关配置解析完了.现在终于进入vue的开发了 vue组件化开发预热 前期准备 创建如下项目: app.js: footer.js: main.js: webpack.con ...

  3. vue项目中使用组件化开发

    最近在使用vue-cli结合webpack打包工具开发一个后台管理系统,使用vue难免需要运用组件化思想,而这也正是vue的一大特点. 在之前做的vue项目中,稍微有一点组件化的思想,可能是对组件化不 ...

  4. Vue全家桶之组件化开发

    Vue全家桶之组件化开发   一.组件 组件 (Component) 是 Vue.js 最强大的功能之一 组件可以扩展 HTML 元素,封装可重用的代码   二. 组件注册 2.1 全局注册 Vue. ...

  5. vue(8)—— 组件化开发 - webpack(2)

    webpack的常用loder和插件 loder和插件是什么,现在暂且不表,看到后面你就懂了 引入css问题 直接用link标签导入css 在前面的 vue(7)—— 组件化开发 — webpack( ...

  6. 大话大前端时代(一) —— Vue 与 iOS 的组件化

    序 今年大前端的概念一而再再而三的被提及,那么大前端时代究竟是什么呢?大前端这个词最早是因为在阿里内部有很多前端开发人员既写前端又写 Java 的 Velocity 模板而得来,不过现在大前端的范围已 ...

  7. Vue的指令以及组件化开发

    一. 自定义指令 如何: 1. 创建指令 Vue.directive("指令名",{ inserted(elem){//指令所在的元素被加载到DOM树上后自动执行指令 //elem ...

  8. Vue源码之组件化/生命周期(个人向)

    大致流程 具体流程 组件化 (createComponent) 构造⼦类构造函数 const baseCtor = context.$options._base // plain options ob ...

  9. 从DOM操作看Vue&React的前端组件化,顺带补齐React的demo

    前言 接上文:谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo 上次写完博客后,有朋友反应第一内容有点深,看着迷迷糊糊:第二是感觉没什么使用场景,太过业务化,还不如直接写Vue ...

  10. vue的数据绑定和组件化

    组件:就是自定义标签, 也是Vue的实例对象; 组件好处:就像工作分工,函数封装等 组件分为全局组件和局部组件: 全局组件,在Vue身上的组件,所有的vue挂载的元素内都可以使用:正是因为这一点,co ...

随机推荐

  1. 查看SQLServer的QUOTED_IDENTIFIER等配置

    DBCC USEROPTIONS SELECT SESSIONPROPERTY('QUOTED_IDENTIFIER') quotedidentifier SELECT SESSIONPROPERTY ...

  2. window环境下备份与恢复(实际操作)

    C:\Documents and Settings\xuzhengzhu>sqlplus /nolog SQL*Plus: Release 10.2.0.1.0 - Production on ...

  3. vue中watch的用法总结以及报错处理Error in callback for watcher "checkList"

    首先确认 watch是一个对象,一定要当成对象来用. 对象就有键,有值. 键:就是你要监控的那个家伙,比如说$route,这个就是要监控路由的变化,或者是data中的某个变量. 值可以是函数:就是当你 ...

  4. Lidgren Network Library

    Lidgren Network Library Classes   Class Description NetAESEncryption AES encryption NetBitVector Fix ...

  5. Android秒级编译工具Freeline

    Freeline 是 Android 平台上的秒级编译方案,Instant Run 的替代品,由蚂蚁聚宝Android 团队开发,它可以充分利用缓存文件,在几秒钟内迅速地对代码的改动进行编译并部署到设 ...

  6. 代码可读性艺术在Andorid中的体现

    前言 最近接手的一些项目,不同的人编码风格迥异,类里的变量.方法的定义穿插,注释极为稀少,更有一些变量和方法的命名非常近似,例如表示播放队列的"playQueue"和表示歌单的&q ...

  7. CosmosEngine - Unity3D /2D 轻量级游戏开发框架

    CosmosEngine https://github.com/mr-kelly/CosmosEngine 快速入门 简介 特性 约定 整体架构图 使用经验 工作流 未来功能 快速入门 1.将NGUI ...

  8. Firefly 性能测试 通报

    http://bbs.gameres.com/forum.php?mod=viewthread&tid=220516 Firefly 性能测试 主要考虑点 网络IO的并发 进程间通信压力 数据 ...

  9. 应用LR监控Apache性能

    1)对Apache服务器中的http.conf进行如下配置修改Apache中Httpd.conf文件,添加如下代码(该文件中都有,只要取消注释就好了)<Location /server-stat ...

  10. Linux相关面试题&答案

    Linux相关面试题&答案 Linux面试题&答案 假设apache日志格式为:118.78.199.98 – - [09/Jan/2010:00:59:59 +0800] " ...