vueJsx

658 阅读1分钟

vue3-jsx和h函数渲染

//子组件
import { ref, h } from 'vue'

export default {
  setup (props, { slots }) {
    return () => {
      return h(
        'div',
        {
          class: ['color-#f00']
        },
        slots.default('来了')
      )
    }
  }
}

//父组件
import { ref, h } from 'vue'
import Child from './Child'

export default {
  setup () {
    return () => {
      return h(
        Child,
        {
          class: ['color-#f00']
        },
        {
          default (data) {
            console.log('结构', data)
            return h('div', {}, data)
          }
        }
      )
    }
  }
}

import child from "./child";
export default {
    data() {
        return {
            info: {
            title: "标题一"
        },
            info2: {
            title: "标题二"
        }
    };
},
render() {
    return (
        <child
            scopedSlots={{
            default: props => {
                return <div style="line-height: 30px;">{props.info.title}</div>;
            },
            other: props => {
                return <div style="line-height: 30px;">{props.info.title}</div>;
            }
            }}
        />
        );
    }
};

<child

scopedSlots={{
    default: props => {
        return <div style="line-height: 30px;">{props.info.title}</div>;
    },
    other: props => {
        return <div style="line-height: 30px;">{props.info.title}</div>;
    }
    }}
/>


//写了$scopedSlots就不用写$slots了

//this.$scopedSlots.default({})  //子组件传递值给父组件 默认
//this.$scopedSlots.other({})  :具名插槽
//this.$slots()


//具名插槽,没有值

父组件 scopedSlots={{
    footer: () => {
        return <div>footer</div>;
    }
}}


//子组件{this.$scopedSlots.footer()}

Vue.component('my-div', {
    render(createElement) {
        return createElement('div', [
            createElement('child', {
                scopedSlots: {
                    default(props) {
                        return [
                            createElement('span', props.text)
                        ]
                    }
                }
            })
        ])
    }
})
			
Vue.component('child', {
    render(createElement) {
        return createElement('strong', this.$scopedSlots.default({
            text: 'i am xutong'
        }))
    }
})

vue2函数式组件

添加functional: true这个属性,就成为函数式组件,在jsx中直没有this,render函数的第二个参数就是props和slot相关的值

const test2 = {
    functional: true,
    render(h, ctx) {
        // console.log('render', h, ctx.slots())
        console.log('render', h, ctx.scopedSlots.footer())
        return (
            <div>
                <div>我是test2组件</div>
                {/* {ctx.scopedSlots.default(666)} */}
                {ctx.slots().default}
                { ctx.scopedSlots.footer()}
            </div>
        )
    }
}

export default {
    render() {
        return (
            <div>
                <div>测试jsx组件</div>
                {/* {
                    h(test2)
                } */}
                {
                }
                <test2 city='重庆' scopedSlots={{
                    default: (data) => {
                        console.log('我是slot', data)
                        return <div>{data}</div>
                    },
                    footer() {
                        return <div>我是footer</div>
                    }
                }}>slotAA</test2>
            </div>
        )
    },
}

默认插槽可以通过slots().default或者scopedSlots.default()获取

  • 如果是具名插槽,只能通过scopedSlots获取
  • 默认插槽写在组件中的内容,可以通过scopedSlots获取或者slots().default获取
  • slots不能使用在作用域插槽,slots能使用的地方scopedSlots都能使用