vue3,动态渲染dom的问题
以下是一个简单的demo,来模拟vue3通过h()和render()创建dom元素。说明,由于事件情景中,父元素.content是动态创建的,所以我不能直接在template中写我要的元素,才通过h()和render()创建。
问题:我希望h()和render()创建的元素,可以响应变量isMyBtn,从而实现样式上的变化。
例如当isMyBtn为true时,类和内容分别为mybtn、我的按钮,反之是yourbtn、你的按钮。
注意,isMyBtn变量在元素创建后仍会有变化,元素要响应isMyBtn后续变化。
这种需求如果是自己在template中写元素,通过三元表达式或v-if可以轻松实现,但通过h()和render()创建的元素我不知道应该怎么实现。
请各位大佬指教,感谢。
<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');
const domSon = h('button', { class: isMyBtn ? 'mybtn' : 'yourbtn' }, isMyBtn ? '我的按钮' : '你的按钮');
render(domSon, domParent);
})
</script> 15行用错了isMyBtn.value <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');
const domSon = h('button', { class: isMyBtn.value ? 'mybtn' : 'yourbtn' }, isMyBtn.value ? '我的按钮' : '你的按钮');
render(domSon, domParent);
})
</script> 坏人。丶 发表于 2023-1-19 16:44
你好,谢谢指教。
但以上代码,经过测试,后续isMyBtn改变后,元素不会随之改变。
只会认isMyBtn的初始值。 按照二楼大佬的指导,加上了.value。
但经过测试,这样只是会认初始值,isMyBtn后续改变,渲染的元素无法响应。
<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');
const domSon = h('button', { class: isMyBtn.value ? 'mybtn' : 'yourbtn' }, isMyBtn.value ? '我的按钮' : '你的按钮');
render(domSon, domParent);
})
const doChange = () => {
isMyBtn.value = !isMyBtn.value;
}
</script> cqwcns 发表于 2023-1-19 21:17
按照二楼大佬的指导,加上了.value。
但经过测试,这样只是会认初始值,isMyBtn后续改变,渲染的元素无法 ...
注意:setup语法糖是不可以使用render的,所以只有用setup选项才可以。
<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> 本帖最后由 npc404 于 2023-1-20 01:26 编辑
你这样写的话,vue生成的vnode里并没有你后来插进去的元素,这也就是为什么你变量变动了插进去的元素也不会更新。你这种写法的话,可以用watch监听isMyBtn变量,回调就是重新执行你onMounted里的操作,再次render会比较新旧两个vnode(这个vnode是指你用h函数生成的那个),视图也就会更新了。不过话说你这么写好另类啊,换我的话,只有两种状态,我选择给要插入元素的父节点根据变量设置动态class,按钮文本用伪元素实现
页:
[1]