VueJS render property inside html string using v-h

2020-04-16 04:34发布

问题:

I have a string of html where I get from Editor and stored in the database.

<h3><a href="#" rel="noopener noreferrer nofollow"><em><strong>Profile Of User:</strong></em></a></h3><p></p><p>{{user}}</p>

I want to retrieve it from the database and render it as HTML. when I use v-html, it will be rendered as:

<v-card-text v-html="content"></v-card-text>

Profile Of User:

{{user}}

How to render {{hello}} from data property if I have data property like this:

data() {
        return {
            user: "Lim Socheat",
            content:"<h3><a href="#" rel="noopener noreferrer nofollow"><em><strong>Profile Of User:</strong></em></a></h3><p></p><p>{{user}}</p>"
        };
    },

Expected Result:

Profile Of User:

Lim Socheat

because {{ user }} will be rendered as Lim Socheat

回答1:

Make content a computed property. And then use it like this:

  computed: {
    content() {
       return '<h3><a href="#" rel="noopener noreferrer nofollow"><em><strong>Profile Of User:</strong></em></a></h3><p></p><p>' + this.user + '</p>';
    }
  }

You can use all variables defined in data in this way.

Update: Since OP is getting the HTML string from backend, they need to replace the variables in this case. We have kept a map of all variables that might come and then we are creating a Regex dynamically to replace the said key from code.

  computed: {
    content() {
      // keep a map of all your variables
      let valueMap = {
        user: this.user,
        otherKey: 250
      };
      let value = '<h3><a href="#" rel="noopener noreferrer nofollow"><em><strong>Profile Of User:</strong></em></a></h3><p></p><p>{{user}}</p>';
      let allKeys = Object.keys(valueMap);
      allKeys.forEach((key) => {
        var myRegExp = new RegExp('{{' + key + '}}','i');
        value = value.replace(myRegExp, valueMap[key]);
      });
      return value;
    }
  }


回答2:

I found the answer. hope it helps someone in the future.

Orginal post: https://forum.vuejs.org/t/evaluate-string-as-vuejs-on-vuejs2-x/20392/2

VueJS - Interpolate a string within a string

 <template>
        <v-container>
            <v-card>
                <v-card-title>Print</v-card-title>
                <v-divider></v-divider>
                <v-card-text v-html="parse(content)"></v-card-text>
            </v-card>
        </v-container>
    </template>

    <script>
    export default {
        data() {
            return {
                hello: "HELLO DATA",
                user: "Lim Socheat",
                content: ""
            };
        },

        methods: {
            getLayout() {
                this.$axios
                    .$get("/api/layout/reciept", {
                        params: {
                            type: "reciept"
                        }
                    })
                    .then(response => {
                        this.content = response.content;
                    })
                    .catch(error => {
                        this.$toast.error(error);
                    });
            },

            evalInContext(string) {
                try {
                    return eval("this." + string);
                } catch (error) {
                    try {
                        return eval(string);
                    } catch (errorWithoutThis) {
                        console.warn(
                            "Error en script: " + string,
                            errorWithoutThis
                        );
                        return null;
                    }
                }
            },
            parse(string) {
                return string.replace(/{{.*?}}/g, match => {
                    var expression = match.slice(2, -2);

                    return this.evalInContext(expression);
                });
            }
        },

        computed: {
            id() {
                return this.$route.params.id;
            }
        },

        watch: {
            id: {
                handler() {
                    this.getLayout();
                },
                immediate: true
            }
        }
    };
    </script>


标签: vue.js nuxt