vue.js - 从短代码动态注入(inject) Vue 2 组件

标签 vue.js vuejs2

我在管理区有一个表单,用户可以在其中输入带有简码的文本:

Heat oven at [temp c=200]

我想要的是temp在前端显示时要解析并转换为 Vue 2 组件的简码。

这是一个简化的 Temperature.vue组件:

<template>
    <span class="temperature">
        {{ celsius }}&deg;C
    </span>
</template>

<script>
    import { mapGetters, mapActions } from 'vuex'

    export default {
        props: ['celsius'],
        name: 'temperature'
    }
</script>

这是一个简化的 Instructions.vue将使用短代码解析和呈现文本的组件:

<template>
    <div v-html="parseShortcodes(text)"></div>
</template>

<script>
    import ShortcodeParser from 'meta-shortcodes'
    import Temperature from 'Temperature.vue'

    export default {

        data: () => {
            return {
                text: 'Heat oven at [temp c=200]',
                parser: ShortcodeParser()
            }
        },
        components: [
            Temperature
        ],
        methods: {
            parseShortcodes(text) {
                return this.parser.parse(text)
            }
        },
        created() {
            this.parser.add('temp', function(options) {
                return '<temperature :celsius="'+options.c+'"></temperature>'
            })
        }
    }
</script>

解析工作正常,替换在前端打印。但是 <temperature>标签按字面意思呈现,而不是作为 Vue 组件呈现,这有点符合预期。

Heat oven at <temperature :celsius="200"></temperature>

我似乎无法理解的是我应该采取什么步骤才能真正转变为 Temperature我定义的组件。有可能吗?是否有更多我缺少的正统方法?

使用 v-html 也存在安全问题渲染文本。我不一定希望它在那里,但我猜期望 Temperature 更牵强。从转义字符串中出现的组件。我总是可以在插入数据库之前进行清理,但我仍然想避免 v-html如果可能的话。

最佳答案

为了使您的示例正常工作,您需要使用 Instructions 组件的渲染函数。在渲染函数中,您可以创建一个新的 Vue 组件,假设为“指令”,您将向其传递短代码解析产生的字符串以用作模板。在该组件声明中,您将附加 Temperature 组件作为子组件,它将呈现您传递的 Prop 。就是这样。示例如下:

Instructions.vue

<script>
    import ShortcodeParser from 'meta-shortcodes'
    import Temperature from 'Temperature.vue'

    export default {

        data: () => {
            return {
                text: 'Heat oven at [temp c=200]',
                parser: ShortcodeParser()
            }
        },
        methods: {
            parseShortcodes(text) {
                return this.parser.parse(text)
            }
        },
        render (createElement) {

            const template = this.parseShortcodes(this.text) //returns something like this <div class="intruction">'Heat oven at <temperature :celsius="200"></temperature>'</div>

            var component = Vue.component('instruction', {
                template: template,
                components: {
                    'temperature': Temperature
                }
            })

            return createElement(
                'div',
                {
                    class: {
                        instructions: true
                    }
                },
                [
                    createElement(component)
                ]
            )
       }
    }
</script>

关于vue.js - 从短代码动态注入(inject) Vue 2 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40573011/

相关文章:

vue.js - 如何使用 Prettier 禁用元素标签中的属性中断

vuejs2 - 为什么 v-bind 是单向数据绑定(bind),而 v-for 可以更新 vue.js 中子组件的数据?

unit-testing - 使用 jest 和 avoriaz 时如何在 Vuejs 的组件中测试异步方法

javascript - VueJS 2.0服务端渲染: How to get data only once using preFetch and beforeRouteEnter?

javascript - 使用 Vuex,当项目是对象数组的一部分时,如何从数组中删除它们?

javascript - 语言切换器不应用新的区域设置

vue.js - 使用 nuxt/pwa 进行离线通知

javascript - vue 2.0 中的自定义过滤器不返回任何内容

javascript - 使用 SheetJS 将 JSON 对象数组导出到 Excel

javascript - 注销时 vuex 为空状态