首页 > 技术文章 > Vue 中渲染字符串形式的组件标签

shenjp 2019-04-08 15:28 原文

在vue中如果要渲染字符串形式的标签,vue 提供了 v-html  指令,可以很方便的渲染出来。但是如果这个标签是一个组件,或者element-ui 的组件时,就不能解析出来了,因为v-html 只能解析原生的属性。

那么就要使用jsx渲染来解析

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>

<body>
    <div id="app">
        <el-form v-model="form" label-width="100px" class="process-edit-form">
            <el-form-item v-for="item in formParams" :key="item.name" :label="item.name + ':'">
                <com1 :html="item.html" :form="form"></com1>
                <!-- 这里取 item.html并渲染-->
            </el-form-item>
        </el-form>
        {{ form }}
    </div>
</body>
<!-- 先引入 Vue -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
    Vue.component('com1', {
        props: {
            html: String,
            form: Object,
        },
        render(h) {
            const com = Vue.extend({
                template: this.html,
                props: {
                    form: Object,
                }
            })

            return h(com, {
                props: {
                    form: this.form
                }
            })
        }
    })

    var app = new Vue({
        el: "#app",
        data: {
            button: '<el-button type="primary">按钮</el-button>',
            form: {
                name: '',
                age: ''
            },
            formParams: [{
                    name: '名称',
                    type: 'name',
                    html: '<el-input v-model.trim="form.name"></el-input>'
                },
                {
                    name: '年龄',
                    type: 'age',
                    html: '<el-input v-model.trim="form.age"></el-input>'
                },
            ]
        },
        mounted() {
            this.$nextTick(function () {
                this.$forceUpdate();
            })
        }
    })
</script>

</html>

当然在开发过程中肯定不会像上面那么些,将采用以下方法:

<template>
    <div :class="$options.name">
        <cmp :html="el"></cmp>
    </div>
</template>

<script>
import Vue from 'vue';
import AudioPlay from '@/components/media/audioPlay';
Vue.component('audio-play', AudioPlay);

export default {
    name: 'audio',
    data() {
        return {
            el: '<div><audio-play></audio-play><p>hello world</p></div>'
        };
    },
    components: {
        cmp: {
            props: {
                html: String
            },
            render(h) {
                const com = Vue.extend({
                    template: this.html
                })
                return h(com, {})
            }
        }
      },
};
</script>

<style lang="sass" scoped>

</style>

 

 

参考社区回答  https://segmentfault.com/q/1010000015734369

推荐阅读