• vue3渲染函数(h函数)的变化


    vue3 渲染函数(h函数)的更改

    h函数的更改总结
    1==>h 现在全局导入,而不是作为参数传递给渲染函数
    2==>渲染函数参数更改为在有状态组件和函数组件之间更加一致
    3==>vnode 现在有一个扁平的 prop 结构
    

    h函数的三个参数详细说明

    第一个参数是必须的。【跟原来的是一样的。没有发生变化】
    类型:{String | Object | Function} 
    一个 HTML 标签名、一个组件、一个异步组件、或一个函数式组件。
    是要渲染的html标签。
    第一个参数div  是表示创建一个div的元素 
    
    第二个参数是可选的。 
    【第二个参数的格式发生了变化, 现在是一个扁平的 prop 结构】
    类型:{Object} 主要是当前html中的各种属性。
    在开发时。建议传,实在没有传的时候,传入 null
    
    第三个参数可选的。(第三个参数建议使用函数返回,否者会有警告)
    类型:{String | Array | Object} children
    虚拟子节点(vnodes),当前html标签的元素。
    
    ps:第三个参数建议使用函数返回。否者在控制有警告
    Non-function value encountered for default slot. Prefer function slots for better performance. 
    

    VNode Props 格式化 vue2.x 语法

    {
      class: ['button', 'is-outlined'],
      style: { color: '#34495E' },
      attrs: { id: 'submit' },
      domProps: { innerHTML: '' },
      on: { click: submitForm },
      key: 'submit-button'
    }
    

    VNode Props 格式化 vue3.x 语法

    {
      class: ['button', 'is-outlined'],
      style: { color: '#34495E' },
      //属性不需要放在 attrs domProps on这些字段下了。
      id: 'submit',
      innerHTML: '',
      onClick: submitForm,
      key: 'submit-button'
    }
    

    vue2中render 函数将自动接收 h 函数 (它是 createElement 的常规别名) 作为参数

    render(h){
        return h('div',{
          //第二个参数
          class:{
            'is-red': true
          }
        },
        //第三个参数  
        [h('p','这是一个render')]
    );
    

    vue3 h函数-绑定事件

    //renderTest.vue
    <script lang="ts">
    import { h, reactive } from 'vue'
    export default {
      setup(props, { slots, attrs, emit }) {
        const state = reactive({
          count: 0
        })
    
        function increment() {
          state.count++
        }
        // 返回render函数
        return () =>
          h(
            'button',
            {
              onClick: increment //这里绑定事件
            },
            state.count
          )
      }
    }
    script>
    

    vue3 render函数简单的循环 map

    <script lang="ts">
    import { h, reactive } from 'vue'
    export default {
        setup() {
          const state = reactive({
            listArr: [
              { name: '三悦有了新工作', like: '工作答辩-你为什来这个-为了钱',id:'00' },
              { name: '三悦有了新工作', like: '没有最好的选择,那不太坏的选择也可以吧', id: '01' },
              { name: '三悦有了新工作', like: '没有最好的选择,那不太坏的选择也可以吧', id: '02' },
              { name: '三悦有了新工作', like: '没有那么好,就是比什么都不做多做了一点点而已',id: '03' },
              { name: '三悦有了新工作', like: '能好好说话是因为爱,不能好好说话,是因为太熟悉了就忘了边界', id: '04' }
            ]
          })
          // 返回render函数
          return () =>
            h(
              'ul',
              null,
              [
                state.listArr.map(item => { //通过map进行循环
                  return h('li', { key: item.id }, ['剧名:',item.name,'我喜欢的句子:', item.like])
                })
              ]
            )
        }
    }
    script>
    

    vue3 默认插槽-slots.default?.()

    //renderTest.vue 文件
    <script lang="ts">
    import { h } from 'vue'
    export default {
      setup(props, { slots }) {
        return () =>
          h(
            'div',
            null,
            [  
              h('h1', null, '我组件的默认内容'), 
              h('h2', null, [slots.default?.()]), 
            ]
          )
      }
    }
    script>
    
    //页面使用 renderTest.vue这个组件
    <template>
        <div class="father-div">
            <renderTest>
                <p>默认插槽p>
            renderTest>
        div>
    template>
    <script setup lang="ts">
    import renderTest from './renderTest.vue'
    script>
    

    具名插槽

    //renderTest.vue 文件
    <script lang="ts">
    import { h } from 'vue'
    export default {
      setup(props, { slots }) {
        return () =>
          h(
            'div',
            null,
            [  
              //第三个参数建议使用函数返回.
              h('h1', null, '我组件的默认内容'), 
              h('h2', null, [slots.details?.()]), 
            ]
          )
      }
    }
    script>
    
    //页面使用 renderTest.vue这个组件
    <template>
        <div class="father-div">
            <renderTest>
               <template #details>
                 <p>我是具名插槽中的内容p>
               template>
            renderTest>
        div>
    template>
    <script setup lang="ts">
    import renderTest from './renderTest.vue'
    script>
    

    props 父传子
    //renderTest.vue
    <script lang="ts">
    import { h } from 'vue'
    export default {
      props: {
        title: {
          type: String
        }
      },
      setup(props, { slots }) {
        return () =>
          h(
            'div',
            null,
            //接受父组件 props传递过来的数据,第三个参数建议使用函数返回
            props.title
          )
      }
    }
    script>
    
    //页面使用 renderTest.vue这个组件
    <template>
      <div class="father-div">
        <renderTest title="父组件给的数据">renderTest>
      div>
    template>
    <script setup lang="ts">
    import renderTest from './renderTest.vue'
    script>
    

    emit 子传父

    //renderTest.vue 文件
    <script lang="ts">
    import { h } from 'vue'
    //把按钮作为标签需要导入
    import { ElButton } from 'element-plus'
    export default {
      props: {
        title: {
          type: String
        }
      },
      setup(props, { emit }) {
        return () =>
          h(
            'div',
            null,
            [ 
              //把按钮作为标签需要导入
              h(ElButton, {
                type:"primary",
                // 注意这里需要使用箭头函数,
                onClick: () => emit('myClick', '123')
              }, 
                //第三个参数建议使用函数返回。否者在控制有警告
                // Non-function value encountered for default slot. Prefer function slots for better performance. 
                ()=>'点击我'
              )
      
            ]
          )
      }
    }
    script>
    
    //页面使用 renderTest.vue这个组件
    <template>
      <div class="father-div">
        <renderTest @myClick="myClick">renderTest>
      div>
    template>
    <script setup lang="ts">
    import renderTest from './renderTest.vue'
    const myClick = (mess:string) => { 
        console.log('子组件给的数据', mess)
    }
    script>
    

    需要注意的点

    1.如果使用ElButton作为标签。需要引入import { ElButton } from 'element-plus'。
    否则在页面中无法正常解析。
    
    2. 第三个参数建议使用函数返回。否者在控制有警告
    Non-function value encountered for default slot. Prefer function slots for better performance. 
    
    详细地址 :https://cn.vuejs.org/guide/extras/render-function.html#v-if
    
  • 相关阅读:
    数据分析学习记录--用EXCEL完成简单的单因素方差分析
    83.(cesium之家)cesium示例如何运行
    基于SpringBoot的校园社团信息管理系统
    事务的特性
    Python实现猎人猎物优化算法(HPO)优化Catboost回归模型(CatBoostRegressor算法)项目实战
    并发编程基础底层原理学习(二)
    【力扣】128. 最长连续序列 <哈希、Set>
    Linux服务器下搭建SFTP服务
    【含泪提速!】一文全解相似度算法、跟踪算法在各个AI场景的应用(附代码)
    gpg: keyserver receive failed: Cannot assign requested address
  • 原文地址:https://www.cnblogs.com/IwishIcould/p/16830127.html