zoukankan      html  css  js  c++  java
  • vue render函数 函数组件化

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

    在这个例子中,我们标记组件为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!")])])}
    }
  • 相关阅读:
    Editor HYSBZ
    MooFest POJ
    Monkey King HDU
    Haruna’s Breakfast HYSBZ
    数颜色 HYSBZ
    Mato的文件管理 HYSBZ
    小Z的袜子(hose) HYSBZ
    javascript类的简单定义
    json格式
    javascript call apply
  • 原文地址:https://www.cnblogs.com/susanws/p/7427729.html
Copyright © 2011-2022 走看看