vue3組件中使用render函數


官方API見這里: https://v3.vuejs.org/api/options-dom.html#render

為了制作一個下面這樣的自定義組件,滿足: 傳入值作為heading的層級,並將自定義中的內容作為heading的內容。

<anchored-heading :level="1">Hello world!</anchored-heading>

如果不用render()函數,那么你的代碼可能是這樣的:

const { createApp } = Vue

const app = createApp({})

app.component('anchored-heading', {
  template: `
    <h1 v-if="level === 1">
      <slot></slot>
    </h1>
    <h2 v-else-if="level === 2">
      <slot></slot>
    </h2>
    <h3 v-else-if="level === 3">
      <slot></slot>
    </h3>
    <h4 v-else-if="level === 4">
      <slot></slot>
    </h4>
    <h5 v-else-if="level === 5">
      <slot></slot>
    </h5>
    <h6 v-else-if="level === 6">
      <slot></slot>
    </h6>
  `,
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

使用render(),你的代碼可能是這樣的:

const { createApp, h } = Vue

const app = createApp({})

app.component('anchored-heading', {
  render() {
    return h(
      'h' + this.level, // tag name
      {}, // props/attributes
      this.$slots.default() // array of children
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

我們再來看一個例子:

Goal

Implement the "example" component which given the following usage:

<example :tags="['h1', 'h2', 'h3']"></example>

which renders the expected output:

<div>
  <h1>0</h1>
  <h2>1</h2>
  <h3>2</h3>
</div>

Solution

Vue.component('example', {
  props: ['tags'],
  render (h) {
    // Note that the second argument (data object) can be omitted, and the
    // children argument can accept strings or numbers besides Array of vnodes.
    // api 可以參考 https://v3.vuejs.org/api/global-api.html#h
    return h('div', this.tags.map((tag, i) => h(tag, i)))
  }
})

我們還可以將一個組件作為第一個參數傳入render函數。下面的這個例子中,我們將一個[functional組件](https://v3.vuejs.org/guide/render-function.html#functional-components)作為參數傳入了render函數, 並將render函數結果作為這個組件的內容傳遞出去:

Goal

  1. Implement a Foo component which simply renders <div>foo</div>, and a Bar component which simply renders <div>bar</div> (using render functions, obviously).

  2. Implement an <example> component which renders the Foo component or the Bar component based on its ok prop. For if ok is true, the final rendered dom should be <div>foo</div>.

  3. Implement a button in the root component that toggles <example> between Foo and Bar by controlling its ok prop.

Solution

const Foo = {
  render (h) {
    return h('div', 'foo')
  }
}

const Bar = {
  render (h) {
    return h('div', 'bar')
  }
}

Vue.component('example', {
  props: ['ok'],
  render (h) {
    return h(this.ok ? Foo : Bar)
  }
})

new Vue({
  el: '#app',
  data: { ok: true }
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM