vue的函数组件和模块组件

133 阅读2分钟

Vue提供了一种称为函数式组件的组件类型,用来定义那些没有响应数据,也不需要有任何生命周期的场景,它只接受一些props来显示组件。

什么是函数组件?

把函数式组件想象成组件里的一个函数,入参是渲染上下文(render context),返回值是渲染好的HTML(即render中定义的内容)。 对于函数式组件,可以定义:

  • Stateless(无状态):组件自身没有状态
  • Instanceless(无实例):组建自身没有实例,即没有this
    由于函数式组件有这两个特性,就可以把他用作高阶组件。(高阶组件:可以生成其他组件的组件。)

1、使用方法

在.js文件中,/创建一个名为FunctionButton.js的函数式组件:

export default {
    name: 'functional-button',
    functional: true,
    render(createElement, context) {
        return createElement('button', 'click me')
    }
}

函数式组件没有this,参数就是靠context来传递 Render context

  • props:提供所有的prop对象
  • children:VNode子节点的数组
  • slots:一个函数,返回了包含所有插槽的对象
  • scopedSlots: (2.6.0+)一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽
  • parent:对父组件的引用
  • listeners:包含了所有父组件为当前组件注册的事件监听的对象。是data.on的别名
  • injections:如果使用了inject选项,则该对象包含了应当被注入的属性;
  • data(包含了其他属性的引用,nibility):传递给组件的整个数据对象,作为createElement的第二个参数传入组件

2、引用

app.vue中引入上面的函数式组件:

<template>
    <FunctionalButton>
        click me
    </FunctionButton>
</template>

上面的click me就是FunctionButton.jschildren属性了,可以在render中改造context(上下文),由.vue来定义组件的button按钮

render(createElement, { children }) {
    // context用于传递上下文,包括了children属性
    return createElement('button', children)
}

3、事件定义

函数式组件没有实例,事件只能由父组件传递

<template>
  <FunctionalButton @click="log">
    Click me
  </FunctionalButton>
</template>

FunctionButton.js:

render(createElement, { props, listeners, children }) {
    return createElement(
      'button',
      {
        attrs: props,
        // createElement中click事件对应的事件属性就是on
        on: {
          click: listeners.click
        }
      },
      children
    );
  }

上面涉及到的props、listeners要传递很多,可以统一把这个属性集成在data中,可改成:

render(createElement, { data, children }) {
    return createElement( 'button', data, children );
}

通过向createElement传入context.data作为第二个参数,就把子组件上的所有attribute和事件监听都传递下去了。 eg:自带hello的button按钮 createElement('button', data, ['hello', ...children])