理解Vue中的Render渲染函数10bet

来源:http://www.chinese-glasses.com 作者:Web前端 人气:189 发布时间:2020-03-16
摘要:面板 CSS 样式如下: 对应的属性使用方法和上面一样既可以了,我们可以打开页面查看下效果也是可以的。如下 列表组件: 理解插槽 export default { functional: true, props: { // ... }, render(cr

面板 CSS 样式如下:

对应的属性使用方法和上面一样既可以了,我们可以打开页面查看下效果也是可以的。如下

列表组件:

理解插槽

export default { functional: true, props: { // ... }, render(createElement, context) { return createElement( 'div', '函数/无状态组件' ) }}

查看效果

10bet,文本组件:

createElement 参数

// @return {VNode}
createElement(
  // {String | Object | Function}
  // 一个HTML标签字符串,组件选项对象,或者一个返回值类型为String/Object的函数。该参数是必须的
  'div',

  // {Object}
  // 一个包含模板相关属性的数据对象,这样我们可以在template中使用这些属性,该参数是可选的。
  {

  },

  // {String | Array}
  // 子节点(VNodes)由 createElement() 构建而成。可选参数
  // 或简单的使用字符串来生成的 "文本节点"。
  [
    'xxxx',
    createElement('h1', '一则头条'),
    createElement(MyComponent, {
      props: {
        someProp: 'xxx'
      }
    })
  ]
)

template:

v-model

通常,缺乏经验的开发人员无法预测对状态管理的需求,以及如何实现状态管理,因此很难了解状态管理的重要性。如果基于状态的组件堆积起来,它们之间的数据管理和共享将成为一场噩梦。从长远来看,拥有的基于状态的组件越多,出现的问题就越多。

查看效果

Vue 提供了一种定义函数组件的简单方法。咱们只需要给个functional关键字就可以。在 2.5.0 及以上版本中,如果使用了单文件组件,那么基于模板的函数式组件可以这样声明::

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>

    </style>
  </head>
  <body>
    <div id="container">
      <tb-heading @input="inputFunc">
        Hello world!
      </tb-heading>
    </div>
  </body>
  <script src="./vue.js"></script>

  <script>
    Vue.component('tb-heading', {
      render: function(createElement) {
        var self = this;
        return createElement('input', {
          domProps: {
            value: '11'
          },
          on: {
            input: function(event) {
              self.value = event.target.value;
              self.$emit('input', self.value);
            }
          }
        })
      },
      props: {

      }
    });
    new Vue({
      el: '#container',
      methods: {
        inputFunc: function(value) {
          console.log(value)
        }
      }
    });
  </script>
</html>
// the wrapper panelconst panel = { functional: true, name: "panel", props: { title: String }, render(createElement, context) { const slots = context.slots(); const header = createElement('header', { attrs: { class: 'panel-header'} }, context.props.title); const body = createElement('main', { attrs: { class: 'panel-body'} }, slots.default); return createElement('section', { attrs: { class: 'panel' } }, [header, body]); }}// sample componentsconst cars = { name: 'cars', template: '#cars', props: { data: Array }}const loremIpsum = { name: 'lorem-ipsum', template: '#lorem-ipsum'}new Vue({ el: '.vue-app', components: { panel, cars, 'lorem-ipsum': loremIpsum }});

上面的data数据可能不太好理解,我们来看一个demo,就知道它是如何使用的了,如下代码:

template:

如上代码是根据参数 :level来显示不同级别的标题中插入锚点元素,我们需要重复的使用 <slot></slot>.

因此,函数组件是没有状态的组件,并且可以更改它。函数组件输出总是基于给定的输入。在 Vue 方面,这类组件会根据给定的props给出不同的输出。

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>

    </style>
  </head>
  <body>
    <div id="container">
      <tb-heading :level="2">
        Hello world!
      </tb-heading>
    </div>
  </body>
  <script src="./vue.js"></script>

  <script>
    Vue.component('tb-heading', {
      render: function(createElement) {
        var pElem = createElement('p', 'hello world');
        return createElement('div', [
          pElem, pElem
        ])
      },
      props: {
        level: {
          type: Number,
          required: true
        }
      }
    });
    new Vue({
      el: '#container'
    });
  </script>
</html>

状态管理通常在较小的项目并不需要,但是当涉及到更大的范围时,如企业级的应用大部分需要它了。简单的说,状态是一个包含应用程序使用的最新值的对象。但是,如果咱们从结构的、更抽象的角度来看待它,就会清楚地看到,状态是复杂应该中重要一块,它使能够构建干净的体系结构,并将关注点强有力地分离开来。

理解Vue中的Render渲染函数

export default { name: 'panel', functional: true, props: { title: String }, render(createElement, context) { const slots = context.slots(); const header = createElement('header', { attrs: { class: 'panel-header'} }, context.props.title); const body = createElement('main', { attrs: { class: 'panel-body'} }, slots.default); return createElement('section', { attrs: { class: 'panel' } }, [header, body]); }}

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

语法

查看效果

createElement 参数

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>

    </style>
  </head>
  <body>
    <div id="container">
      <tb-heading :level="2">
        <a href="#">Hello world!</a>
      </tb-heading>
    </div>
  </body>
  <script src="./vue.js"></script>

  <script>
    Vue.component('tb-heading', {
      render: function(createElement) {
        return createElement(
          'h' + this.level,    // tag name 标签名称
          this.$slots.default  // 组件的子元素
        )
      },
      props: {
        level: {
          type: Number,
          required: true
        }
      }
    });
    new Vue({
      el: '#container'
    });
  </script>
</html>
div  panel :title="'Car Manufacturers'" cars :data="['Mazda', 'Ford', 'Mercedes']"/cars /panel panel :title="'Lorem Ipsum'" lorem-ipsum/lorem-ipsum /panel/div

查看效果

原文:-the-deal-with-functional-components-in-vue-js-513a31eb72b0

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>

    </style>
  </head>
  <body>

    <div id="container">
      {{msg}}
      <choice>
        <item value="1">test</item>
      </choice>
    </div>

  </body>
  <script src="./vue.js"></script>

  <script>
    Vue.component('choice', {
      template: '<div><ul><slot></slot></ul></div>'
    });

    Vue.component('item', {
      functional: true,
      render: function(h, context) {
        return h('li', {
          on: {
            click: function() {
              console.log(context);
              console.log(context.parent);
              console.log(context.props)
            }
          }
        }, context.children)
      },
      props: ['value']
    })

    new Vue({
      el: '#container',
      data: {
        msg: 'hello'
      }
    });
  </script>
</html>

实例

在render函数中会被javascript的 if/else 和map重新实现。如下代码:

在这个示例中,咱们创建一个panel组件,它充当一个包装器,并提供所需的样式。子组件将在panel主体中渲染:

VUE一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数。
比如如下我想要实现如下html:

虚拟 DOM

查看效果

组件需要的一切都是通过context参数传递,它是一个包括如下字段的对象:

使用Javascript代替模板功能
 v-if 和 v-for
template 中有 v-if 和 v-for, 但是vue中的render函数没有提供专用的API。
比如如下:

css

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>

    </style>
  </head>
  <body>
    <div id="container">
      <tb-heading :level="2">
        Hello world!
      </tb-heading>
    </div>
  </body>
  <script src="./vue.js"></script>

  <script>
    var getChildrenTextContent = function(children) {
      return children.map(function(node) {
        return node.children ? getChildrenTextContent(node.children) : node.text
      }).join('')
    };
    Vue.component('tb-heading', {
      render: function(createElement) {
        var headingId = getChildrenTextContent(this.$slots.default)
          .toLowerCase()
          .replace(/W+/g, '-')
          .replace(/(^-|-$)/g, '')
        return createElement(
          'h' + this.level,
          [
            createElement('a', {
              attrs: {
                name: headingId,
                href: '#' + headingId
              },
              style: {
                color: 'red',
                fontSize: '20px'
              },
              'class': {
                foo: true,
                bar: false
              },
              // DOM属性
              domProps: {
                innerHTML: 'baz'
              },
              // 组件props
              props: {
                myProp: 'bar'
              },
              // 事件监听基于 'on'
              // 所以不再支持如 'v-on:keyup.enter' 修饰语
              // 需要手动匹配 KeyCode  
              on: {
                click: function(event) {
                  event.preventDefault();
                  console.log(111);
                }
              }
            }, this.$slots.default)
          ]
        )
      },
      props: {
        level: {
          type: Number,
          required: true
        }
      }
    });
    new Vue({
      el: '#container'
    });
  </script>
</html>

这是一个简单直接的 CSS,提供了一些padding和color。

查看效果

如果没有使用外部包进行状态管理,那么最好尽可能少地使用基于状态的组件,而展示组件则使用围绕它们构建的状态。

下面我们来尝试使用 render函数重写上面的demo;如下代码:

就它们的用法而言,因为函数式组件只是函数,所以渲染开销也低很多,这也意味着它们是非常高效的,不需要花太多时间渲染。同时,考虑高阶组件,它们不需要任何状态,它们所要做的就是用额外的逻辑或样式包装给定的子组件。

{
  // 和`v-bind:class`一样的 API
  'class': {
    foo: true,
    bar: false
  },
  // 和`v-bind:style`一样的 API
  style: {
    color: 'red',
    fontSize: '14px'
  },
  // 正常的 HTML 特性
  attrs: {
    id: 'foo'
  },
  // 组件 props
  props: {
    myProp: 'bar'
  },
  // DOM 属性
  domProps: {
    innerHTML: 'baz'
  },
  // 事件监听器基于 `on`
  // 所以不再支持如 `v-on:keyup.enter` 修饰器
  // 需要手动匹配 keyCode。
  on: {
    click: this.clickHandler
  },
  // 仅对于组件,用于监听原生事件,而不是组件内部使用 `vm.$emit` 触发的事件。
  nativeOn: {
    click: this.nativeClickHandler
  },
  // 自定义指令。注意事项:不能对绑定的旧值设值
  // Vue 会为您持续追踪
  directives: [
    {
      name: 'my-custom-directive',
      value: '2',
      expression: '1 + 1',
      arg: 'foo',
      modifiers: {
        bar: true
      }
    }
  ],
  // Scoped slots in the form of
  // { name: props => VNode | Array<VNode> }
  scopedSlots: {
    default: props => createElement('span', props.text)
  },
  // 如果组件是其他组件的子组件,需为插槽指定名称
  slot: 'name-of-slot',
  // 其他特殊顶层属性
  key: 'myKey',
  ref: 'myRef'
}

时间: 2019-11-16阅读: 130标签: 组件啥是应用程序状态,为什么咱们需要它?

在添加 functional: true 之后,组件的 render 函数之间简单更新增加 context 参数,this.$slots.default 更新为 context.children,之后this.level 更新为 context.props.level。
如下代码演示:

Vue 中的无状态组件其实就是函数组件。但函数组件又是啥呢? 要回答这个问题,咱们首先必须理解什么是函数式编程。

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

  },
  // Props 可选
  props: {

  }
})

子组件

查看效果

如上所述,此组件的唯一目的是提供类似于面板(卡片)的样式,它有header和main元素,分别保存面板标题和HTML内容。整个过程是通过使用render函数中的createElement参数在中完成。createElement是Vue核心中实现的虚拟 Dom 系统的一部分。

可以从 this.$slots 获取VNodes列表中的静态内容:如下代码:

本文由10bet发布于Web前端,转载请注明出处:理解Vue中的Render渲染函数10bet

关键词:

上一篇:没有了

下一篇:没有了

频道精选

最火资讯