吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 845|回复: 6
收起左侧

[求助] vue3,动态渲染dom的问题

[复制链接]
cqwcns 发表于 2023-1-19 16:19
以下是一个简单的demo,来模拟vue3通过h()和render()创建dom元素。
说明,由于事件情景中,父元素.content是动态创建的,所以我不能直接在template中写我要的元素,才通过h()和render()创建。


问题:我希望h()和render()创建的元素,可以响应变量isMyBtn,从而实现样式上的变化。
例如当isMyBtn为true时,类和内容分别为mybtn、我的按钮,反之是yourbtn、你的按钮。


注意,isMyBtn变量在元素创建后仍会有变化,元素要响应isMyBtn后续变化。


这种需求如果是自己在template中写元素,通过三元表达式或v-if可以轻松实现,但通过h()和render()创建的元素我不知道应该怎么实现。


请各位大佬指教,感谢。

[JavaScript] 纯文本查看 复制代码
<template>
  <div class="content">
  </div>
</template>

<script setup>

import { onMounted, ref, h, render } from 'vue';

const isMyBtn = ref(true)

onMounted(() => {
  console.log('do render');
  const domParent = document.getElementsByClassName('content')[0];
  const domSon = h('button', { class: isMyBtn ? 'mybtn' : 'yourbtn' }, isMyBtn ? '我的按钮' : '你的按钮');
  render(domSon, domParent);
})

</script>

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

坏人。丶 发表于 2023-1-19 16:42
15行用错了isMyBtn.value
坏人。丶 发表于 2023-1-19 16:44
[JavaScript] 纯文本查看 复制代码
<template>
  <div class="content">
  </div>
</template>
 
<script setup>
 
import { onMounted, ref, h, render } from 'vue';
 
const isMyBtn = ref(true)
 
onMounted(() => {
  console.log('do render');
  const domParent = document.getElementsByClassName('content')[0];
  const domSon = h('button', { class: isMyBtn.value ? 'mybtn' : 'yourbtn' }, isMyBtn.value ? '我的按钮' : '你的按钮');
  render(domSon, domParent);
})
 
</script>

免费评分

参与人数 1热心值 +1 收起 理由
cqwcns + 1 谢谢@Thanks!

查看全部评分

 楼主| cqwcns 发表于 2023-1-19 21:15
坏人。丶 发表于 2023-1-19 16:44
[mw_shl_code=javascript,true]
  
  

你好,谢谢指教。

但以上代码,经过测试,后续isMyBtn改变后,元素不会随之改变。

只会认isMyBtn的初始值。
 楼主| cqwcns 发表于 2023-1-19 21:17
按照二楼大佬的指导,加上了.value。
但经过测试,这样只是会认初始值,isMyBtn后续改变,渲染的元素无法响应。

[JavaScript] 纯文本查看 复制代码
<template>
  <div class="content">
  </div>
  <button @click="doChange" style="background-color: blue;">切换({{ isMyBtn }})</button>
</template>
  
<script setup>

import { onMounted, ref, h, render } from 'vue';

const isMyBtn = ref(true)

onMounted(() => {
  console.log('do render');
  const domParent = document.getElementsByClassName('content')[0];
  const domSon = h('button', { class: isMyBtn.value ? 'mybtn' : 'yourbtn' }, isMyBtn.value ? '我的按钮' : '你的按钮');
  render(domSon, domParent);
})

const doChange = () => {
  isMyBtn.value = !isMyBtn.value;
}
</script>
坏人。丶 发表于 2023-1-19 23:41
cqwcns 发表于 2023-1-19 21:17
按照二楼大佬的指导,加上了.value。
但经过测试,这样只是会认初始值,isMyBtn后续改变,渲染的元素无法 ...

注意:setup语法糖是不可以使用render的,所以只有用setup选项才可以。
[JavaScript] 纯文本查看 复制代码
<script>
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>

免费评分

参与人数 1热心值 +1 收起 理由
cqwcns + 1 谢谢@Thanks!

查看全部评分

npc404 发表于 2023-1-20 00:18
本帖最后由 npc404 于 2023-1-20 01:26 编辑

你这样写的话,vue生成的vnode里并没有你后来插进去的元素,这也就是为什么你变量变动了插进去的元素也不会更新。你这种写法的话,可以用watch监听isMyBtn变量,回调就是重新执行你onMounted里的操作,再次render会比较新旧两个vnode(这个vnode是指你用h函数生成的那个),视图也就会更新了。不过话说你这么写好另类啊,换我的话,只有两种状态,我选择给要插入元素的父节点根据变量设置动态class,按钮文本用伪元素实现

免费评分

参与人数 1热心值 +1 收起 理由
cqwcns + 1 谢谢@Thanks!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表