3

Editor Content

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

3 Answers 3

5

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;
    }
  }
Sign up to request clarification or add additional context in comments.

3 Comments

Hi, in this scenario, I can not do that. Because I get HTML STRING from the database, where I can dynamically change from Editor. I have edited the question.
@LimSocheat I have updated the code. Please check now.
Hi, Thanks for answering, your answer gives me the idea and solves my problem.
1

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>

Comments

0

you can achieve the same functionality using Vue Dynamic Components instead of v-html because for v-html you have to parse variable with in string using regex as explained by @Lim Socheat and @Vijay Joshi. but with Vue Dynamic Components you can pass variables from parent to child component. Hope this will help
I am defining a component in computed with data and Passing data from Parent Component to Child component.

<template>
    <v-container>
        <v-card>
            <v-card-title>Print</v-card-title>
            <v-divider></v-divider>
            <v-card-text>
                <component :is="dynamicComponent"></component>
            </v-card-text>
        </v-card>
    </v-container>
</template>

<script>
import { reactive, shallowRef, ref } from 'vue'
export default {
    data() {
        return {
            hello: "HELLO DATA",
            user: "Lim Socheat",
            content: shallowRef(null)
        };
    },

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

    computed: {
        id() {
            return this.$route.params.id;
        },
        dynamicComponent() {
            let $this = this;
            return {
                data: function () {
                    return {
                        hello: ref($this.hello),
                        user: ref($this.user),
                    }
                },
                template: $this.content ? $this.content : "loading..."
            };
        }
    },

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.