Learn vue3 by comparing the syntax of vue3 with that of vue2. Take a look at slot’s use in 2.x and 3.x.

2.x syntax

In 2.x, I mainly understand the usage of these two. , $slots, $scopedSlots

Vm.$slots template usage

• Type: {[name: string]:? Array

}

Default specifies that propsName is defined in $slots.propsname

// fahter
<template>
    <Book>
      <span>The default value</span>
      <span slot="header">header</span>
      <span slot="content">content1</span>
      <span slot="content">content2</span>
    </Book>
</template>
Copy the code
// child
<template>
  <div>
    <slot>default 1</slot>
    <slot name="header">default 2</slot>
    <slot name="content">default 3</slot>
  </div>
</template>
Copy the code
  • Slot the default
  • Slot name Indicates a named slot. In this way, multiple slots can be specified and arranged arbitrarily to achieve layout requirements.

$slots is used in the vm.$slots rendering function

Let’s first look at the syntax of the render function

createElement('div',{//... data object},[ 'some text', createElement('h1'), createElement(MyComponent,{props:{someProp:'foobar'}}) ])Copy the code

Parameter 1: Book 2: components, parameters is of the first parameter {HTML tag | component} parameter Settings, the specific reference createElement method parameters, 3: Children VNodes {String | Array} can String, there is more than one using the form of an Array

  render(h) {
    return h(Book,{},[
      h('span', {},'Default value'),
      h('span', {slot:'header'},'header'),
      h('span', {slot:'content'},'content1'),
      h('span', {slot:'content'},'content2')])}Copy the code

Implement custom defaults

export default {
  render(h) {
    return h('div', {},this.$slots.default || 'default1'.this.$slots.header  || 'default2'.this.$slots.content  || 'default3'])}}Copy the code

Vm.$scopedSlots template usage

Type: { [name: string]: props => Array<VNode> | undefined }

The difference from $slots is that $scopedSlots passes data from within the component to the parent scope.

<template>
  <div>
    <Child>
      <template v-slot:default="slotProps">
        {{ slotProps.user.name }}
      </template>
    </Child>
  </div>
</template>
Copy the code
<template>
  <div>
    <slot :user="user"></slot>
  </div>
</template>
Copy the code

Vm.$scopedSlots is used in the rendering function

  • $scopedslots. default is a function that passes data to the parent component
  • The parent component uses scopedSlots to receive data from the child component as follows:
  // fahter
  render(h) {
    return h(Book,{
            scopedSlots: {
              default:function(props){
                return [ 
                        props.user.name,
                        <div>text</div>.'sdfsdf']}}})}Copy the code
   // Book.vue
    render(h) {
      return h('div', {},this.$scopedSlots.default({
          user:this.user 
        })
      ])
    }
Copy the code

3.x syntax

• This.$slots now exposes slots as a function (2. X is an object) • Specify a function to define slot syntax for passing to child components :h(Component,{},{header ()=>Component), as follows:

// father
<script lang='ts'>
  import { h } from 'vue';
  import Child from './Child.vue'
  export default {
    components:{
      Child
    },
    render() {
      return h(Child,{},
        { 
          header:(props:{year:number}) = >{
            return h('div'.`this year is ${props.year}`)},title:() = > h('h1', {
            innerHTML:'title'.onClick(){
              console.log('Click on the title')},style: {color:'#f66'
            }
          })
        }
      )
    }
  }
</script>
Copy the code
// child
<script lang='ts'>
  import { h } from 'vue';
  export default {
    render() {
      return h('div'[this.$slots.title(),this.$slots.header({year:2021})])
    }
  }
</script>
Copy the code

• H is now imported globally instead of being passed as a parameter to the render function, see the official website for details. X defines a VNode directly,h(‘span’,{slot:’header’},’header’)

  • H (Child,{},{header:Function}) uses scopedSlots. The third argument must be an object
    • CreateElement method parameters for a third {String | Array}, guess there must be as the object is to think through propName to find the corresponding function to render we specify the header, the title VNode. If you have multiple child elements you can’t determine which one they are.

H render function

It is also important to note that in 3.x the syntax of the render function has changed as follows:

2. X syntax

In 2.x, domProps contains a nested list of VNode props:

// 2.x
{
  class: ['button'.'is-outlined'].style: { color: '#34495E' },
  attrs: { id: 'submit' },
  domProps: { innerHTML: ' ' },
  on: { click: submitForm },
  key: 'submit-button'
}
Copy the code

3. X syntax

In 3.x, the entire VNode props structure is flat, using the example above, and here is what it looks like now

/ / 3. X syntax
{
  class: ['button'.'is-outlined'].style: { color: '#34495E' },
  id: 'submit'.innerHTML: ' '.onClick: submitForm,
  key: 'submit-button'
}
Copy the code

reference

Chinese document