Vue3 CDN模式下服务器动态模板无法绑定方法与数据的问题求助
Vue3动态模板绑定问题:方法与数据无法关联
使用CDN引入Vue3时,加载服务器生成的动态模板后,模板内的方法与组件数据无法完成绑定。点击模板中的触发按钮,控制台报错:vue@3:1807 Uncaught TypeError: test is not a function
复现代码如下:
// reproduction of the issue in vue3 vite import { compile, computed, h } from 'vue/dist/vue.esm-bundler'; // vite // import { compile, computed, h } from 'vue/dist/vue.esm-bundler'; // webpack export default { data() { return { htmlTemplate: '<span @click="test()">this is a test {{ testVariable }}</span>', // 模拟服务器返回的模板 testVariable: 'test variable', } }, methods: { test() { console.log('test'); } }, render() { const textCompRef = computed(() => ({ render: compile(this.htmlTemplate) })); console.log('textCompRef', textCompRef); return h(textCompRef.value); } }
曾尝试在created生命周期中设置this.$options.template为服务器返回内容,但该方案仅在第三次点击时生效,且模板更新后无法同步变更。
问题根源
编译后的渲染函数默认没有关联当前组件的上下文,导致模板无法访问组件内的方法和数据。
解决方向
1. 绑定组件上下文到渲染函数
修改render函数,将组件的proxy作为上下文传入编译后的渲染函数:
render() { const compiledRender = compile(this.htmlTemplate); return h({ render: (ctx) => compiledRender.call(this.proxy, ctx) }); }
这样模板就能直接访问组件data和methods中的内容。
2. 使用Composition API处理上下文绑定
如果采用Composition API,可直接将变量和方法注入渲染上下文:
import { compile, h, ref } from 'vue/dist/vue.esm-bundler'; export default { setup() { const htmlTemplate = ref('<span @click="test()">this is a test {{ testVariable }}</span>'); const testVariable = ref('test variable'); const test = () => { console.log('test'); }; return () => { const render = compile(htmlTemplate.value); return h({ render: (ctx) => { // 将需要访问的变量和方法挂载到上下文 Object.assign(ctx, { test, testVariable: testVariable.value }); return render(ctx); } }); }; } };
3. 动态组件结合props/emit传递
通过动态组件的props传递数据,emit触发方法,需要调整模板写法:
render() { const DynamicComp = { render: compile(this.htmlTemplate), props: ['testVariable'], emits: ['test'] }; return h(DynamicComp, { testVariable: this.testVariable, onTest: this.test }); }
对应模板修改为:
<span @click="$emit('test')">this is a test {{ testVariable }}</span>
内容的提问来源于stack exchange,提问作者Atila Nađ
相关产品推荐
相关产品推荐

