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

简介: 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

遇见问题,这是你成长的机会,如果你能够解决,这就是收获。

相关文章
|
8天前
|
敏捷开发 人工智能 JavaScript
Figma-Low-Code:快速将Figma设计转换为Vue.js应用,支持低代码渲染、数据绑定
Figma-Low-Code 是一个开源项目,能够直接将 Figma 设计转换为 Vue.js 应用程序,减少设计师与开发者之间的交接时间,支持低代码渲染和数据绑定。
30 3
Figma-Low-Code:快速将Figma设计转换为Vue.js应用,支持低代码渲染、数据绑定
|
2月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
154 64
|
2月前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
124 60
|
18天前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
67 3
|
2月前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
45 8
|
2月前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
41 1
|
2月前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
49 1
|
2月前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
2月前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
54 0
|
12天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
78 1