Vue3之ref取render形式组件jsx元素节点

  • Vue3之ref取render形式组件jsx元素节点已关闭评论
  • 114 次浏览
  • A+
所属分类:Web前端
摘要

一开始注意到组件 setup 和 render 一起使用的情况,好奇怎么通过 ref 取到 render 中 jsx 里的节点,一开始试了以下的尝试,结果是 undefined 的:


[2023 年 7 月 28 日 22:16:06]

ref 取 render 方式组件节点

一开始注意到组件 setup 和 render 一起使用的情况,好奇怎么通过 ref 取到 render 中 jsx 里的节点,一开始试了以下的尝试,结果是 undefined 的:

import { defineComponent, ref, onMounted } from "vue";  export default defineComponent({   setup() {     let chartRef = ref()      onMounted(() => {       console.log(chartRef.value); // undefined     })      return {       chartRef     }   },   render() {     return <div ref={this.chartRef} style="{{ width: 200px, height: 100px }}"></div>   }, }); 

后来经过大佬指点,改成以下形式:

import { defineComponent, ref, onMounted } from 'vue'  export default defineComponent({   setup() {     let chartRef = ref<HTMLDivElement | null>()      onMounted(() => {       console.log(chartRef.value) // Element div...     })      return {       chartRef     }   },   render() {     return <div ref={el => this.chartRef = el} style="{{width: 200px, height: 100px}}"></div>   } }) 

render 这一步就很像 react 里 jsx 的写法了,react 里也有回调 ref,都是一样写法。回调函数参数el引用了 div 元素节点,通过赋值到chartRef。这种方式在 react 里是保持引用响应的,vue3 也是。

这种方式在 vue3 官方文档的模板引用目录里是有注明的,这里容易漏,做下记录。

渲染函数 h 引申

在以往的 vue2 中我们会看到如下的代码:

new App({   el: "app",   render: (h) => h(App) }); 

是不是熟悉起来了? h 到底是什么意思,h => h(App)箭头函数,如果我把无语义的h参数替换成 createElement 呢?没错,就是这个意思,它是个函数,创建虚拟 dom 的函数,该函数传的参数也是有区分的:

  • 如果是组件,App就是一个组件,参数直接传组件就好;
  • 如果是标签,第一个参数是渲染的 dom 标签,第二个是渲染该标签内的内容,createElement('h1', 'Hello World!')

所以在 vue3 中,以上面的例子改写成如下:

import { defineComponent, ref, onMounted, h } from 'vue'  export default defineComponent({   setup() {     let chartRef = ref<HTMLDivElement | null>()      onMounted(() => {       console.log(chartRef.value) // Element div...     })      return {       chartRef     }   },   render() {     // return <div ref={(el) => this.chartRef = el} style="{{width: 200px, height: 100px}}"></div>     return h('div', {style : {width: '200px', height: '100px'}, ref: el => this.chartRef = el}, 'setup&render方式h函数渲染')   } }) 

setup&return 组件写法也是类似:

import { defineComponent, ref, onMounted, h } from 'vue'  export default defineComponent({   setup() {     let chartRef = ref<HTMLDivElement | null>()      onMounted(() => {       console.log(chartRef.value) // Element div...     })      return() => {       return h('div', {style : {width: '200px', height: '100px'}, ref: chartRef}, 'setup&return方式h函数渲染')     }   } }) 

相比下就是把setup外部的render配置项拿到了 setup 里用return匿名函数代替了,而且拿到setup里可以直接绑定 ref 属性。

待更正补充...