美文网首页
23. 渲染函数和jsx

23. 渲染函数和jsx

作者: 论宅 | 来源:发表于2019-06-04 18:28 被阅读0次

通常情况下,在我们使用模板的时候,不太方便在模板内部根据需要切换不同的标签,如:提供一个参数,根据这个参数模板返回h1-h7的标签,并填上内容,一般情况下会是这样——

var component1 = {
        data:function(){
          return {
            hdata:"你好啊",
            level:2
          }
        },
        template: `
      <div>
          <h1 v-if='level==1'>{{hdata}}</h1>
          <h2 v-if='level==2'>{{hdata}}</h2>
          <h3 v-if='level==3'>{{hdata}}</h3>
          <h4 v-if='level==4'>{{hdata}}</h4>
      
      </div>
      `
      };

但这样会使得内容过于繁重,所以出现了渲染函数。
渲染函数可以将如上的模板代码,用js代码写出来,使得内容变得简练:

var component2 = {
      data: function () {
        return {
          hdata: "你好啊2",
          level: 2
        }
      },
      render: function (createEle) {
        var arr = [createEle("div", "ccc"), createEle("div", "ccc")]
        return createEle(
          "h" + this.level, { class: "aaa" },
          arr
        )


      }
    }

如上,使用render函数代替了template,该参数接受一个createElement方法参数,调用这个方法会生成html代码。
这个方法接受三个参数,第一个是标签名,第二个是这个标签的属性,第三个是标签内容。

createEle可以理解为创建节点的方法,可以创造一个标签,赋予标签的属性,并且填入内容。
其内容是可以其他createEle创造出来的元素。
如上例。

节点,树和虚拟dom

标签,标签的内容,标签的属性都可以算作节点,而这些节点组合起来的就是树,而vue使用的节点并非实际的dom,而是虚拟的vue节点。

虚拟dom创造方法:createElement

这个方法会告诉vue页面需要渲染什么样的节点。

该方法的三个参数分别需要:

// {String | Object | Function}
  // 一个 HTML 标签名、组件选项对象,或者
  // resolve 了上述任何一种的一个 async 函数。必填项。
  'div',
 // {Object}
  // 一个与模板中属性对应的数据对象。可选。
  {
    // (详情见下一节)
  },
/ {String | Array}
  // 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
  // 也可以使用字符串来生成“文本虚拟节点”。可选。

上下两个参数理解起来较为简单,中间的参数比较复杂:

{
  // 与 `v-bind:class` 的 API 相同,
  // 接受一个字符串、对象或字符串和对象组成的数组
  'class': {
    foo: true,
    bar: false
  },
  // 与 `v-bind:style` 的 API 相同,
  // 接受一个字符串、对象,或对象组成的数组
  style: {
    color: 'red',
    fontSize: '14px'
  },
  // 普通的 HTML 特性
  attrs: {
    id: 'foo'
  },
  // 组件 prop
  props: {
    myProp: 'bar'
  },
  // DOM 属性
  domProps: {
    innerHTML: 'baz'
  },
  // 事件监听器在 `on` 属性内,
  // 但不再支持如 `v-on:keyup.enter` 这样的修饰器。
  // 需要在处理函数中手动检查 keyCode。
  on: {
    click: this.clickHandler
  },
  // 仅用于组件,用于监听原生事件,而不是组件内部使用
  // `vm.$emit` 触发的事件。
  nativeOn: {
    click: this.nativeClickHandler
  },
  // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
  // 赋值,因为 Vue 已经自动为你进行了同步。
  directives: [
    {
      name: 'my-custom-directive',
      value: '2',
      expression: '1 + 1',
      arg: 'foo',
      modifiers: {
        bar: true
      }
    }
  ],
  // 作用域插槽的格式为
  // { name: props => VNode | Array<VNode> }
  scopedSlots: {
    default: props => createElement('span', props.text)
  },
  // 如果组件是其它组件的子组件,需为插槽指定名称
  slot: 'name-of-slot',
  // 其它特殊顶层属性
  key: 'myKey',
  ref: 'myRef',
  // 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
  // 那么 `$refs.myRef` 会变成一个数组。
  refInFor: true
}
``

理解了以上参数之后,渲染便可以这样书写:

var getChildrenTextContent = function (children) {
return children.map(function (node) {
return node.children
? getChildrenTextContent(node.children)
: node.text
}).join('')
}

Vue.component('anchored-heading', {
render: function (createElement) {
// 创建 kebab-case 风格的 ID
var headingId = getChildrenTextContent(this.slots.default) .toLowerCase() .replace(/\W+/g, '-') .replace(/(^-|-)/g, '')

return createElement(
  'h' + this.level,
  [
    createElement('a', {
      attrs: {
        name: headingId,
        href: '#' + headingId
      }
    }, this.$slots.default)
  ]
)

},
props: {
level: {
type: Number,
required: true
}
}
})


### 渲染函数的利弊
渲染函数不能使用相当的组件,如v-model,对应的逻辑必须自己手动去实现:
v-if,v-for

props: ['items'],
render: function (createElement) {
if (this.items.length) {
return createElement('ul', this.items.map(function (item) {
return createElement('li', item.name)
}))
} else {
return createElement('p', 'No items found.')
}
}


v-model

props: ['value'],
render: function (createElement) {
var self = this
return createElement('input', {
domProps: {
value: self.value
},
on: {
input: function (event) {
self.$emit('input', event.target.value)
}
}
})
}


### 插槽
你可以通过`this.$slots`来访问静态插槽的内容,每个插槽都是一个vnode数组。
可以通过`this.$scopedSlots`访问作用域插槽。

### JSX

相关文章

  • 23. 渲染函数和jsx

    通常情况下,在我们使用模板的时候,不太方便在模板内部根据需要切换不同的标签,如:提供一个参数,根据这个参数模板返回...

  • Render渲染函数和JSX

    render函数 h( 元素,属性,值 ) 中 h 不能少 使用 list组件中调用 函数式组件 定义函数式组件 ...

  • 渲染函数&JSX

    1.基础 render函数提供javascript完全编程能力 2.节点,树以及虚拟DOM 虚拟DOM:vue通过...

  • 渲染函数&JSX

    渲染函数 背景 Vue推荐在绝大多数情况下使用模版来创建你的HTML。然后在一些场景中,你真的需要JavaScri...

  • vue 渲染函数 & JSX

    渲染函数 render 通过渲染函数渲染组件 渲染后: JSX 通过以上方式创建虚拟DOM,语法比较繁琐。可以使用...

  • react语法结构

    1.react JSX语法原理 react是函数式编程,使用jsx语法来渲染组件。jsx语法是合法的JavaScr...

  • react之setState的异步及合并执行更新组件

    前言须知 jsx的渲染过程jsx会经过babel编译成createElement函数的结构,然后createEle...

  • vue 渲染函数&jsx

    jsx react模板渲染语法

  • vue渲染函数 & JSX

    1. 渲染 input 2. v-for 3. v-if 条件, 多个需要用【

    】包裹起来 4...

  • Vue 渲染函数 & JSX

    Vue - template Vue 官方推荐使用template语法来创建应用,虽然写法像html,但Vue最终...

网友评论

      本文标题:23. 渲染函数和jsx

      本文链接:https://www.haomeiwen.com/subject/ujrrxctx.html