Как отобразить данные внутри html-строки в Vue до их отображения?

#vue.js #vue-component

Вопрос:

У меня есть html-строка, содержащая некоторые переменные, завернутые в {{}}. Есть ли способ запустить синтаксический анализ html для замены {{}} значениями, которые уже присутствуют в командной таблице

 <div v-html="desc"></div>
 
 desc = "<p>Some text {{aVar}}</p>"
 

Я хотел бы иметь возможность делать что-то вроде

 v-html="parse(desc)" 
 

и {{aVar}} будет заменено фактическим значением, которое доступно
Надеюсь, для этого есть метод Vue, но я определенно могу использовать пользовательский метод и заменить значения самостоятельно.

Спасибо

Ответ №1:

На данный момент я решил эту проблему с помощью

 function parseHtml(html = "") {
      const expose = {
        player,
      };
      return html.replace(/{{(. ?)}}/g, (_, g) => {
        return _get(expose, g);
      });
    }
 

где _get-это lodash _.получить

Ответ №2:

Вот так?

 <script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
const parse = (text) => (`<span style="color:red">${text}<span>`)
</script>
<template>
  <input type="text" v-model="msg">
  <div v-html="parse(msg)"></div>
</template>
 

Комментарии:

1. Ну, не уверен, мой настоящий текст «Привет, мир» — это что-то вроде «Привет, мир»! {{test.var1}} и я хочу заменить {{test.var1}} значением внутри test = {var1: «некоторый текст var 1» }

2. С Vue это невозможно.

3. похоже, динамические компоненты могут заставить это работать, просто не знаю, как. Примеры показывают, что у меня не получилось, но я все еще работаю над этим(или над пользовательским анализатором).

Ответ №3:

Вдохновленный вашим примером @orbitory, что насчет этого?

API опций

 <script>
export default {
  data() {
    return {
      template: `<p> {{ message }} {{ message2 }}</p>`,
      message: "hello",
      message2: "world",
    };
  },
  methods: {
    parse(html) {
      return html.replace(/{{(. ?)}}/g, (_, g) => {
        return this[g.trim()];
      });
    },
  },
};
</script>

<template>
    <input v-model="message">
    <input v-model="message2">
    <div v-html="parse(template)" />
</template>
 

Демонстрационный пример с полями реактивного ввода.

https://codesandbox.io/s/how-do-i-render-data-inside-an-html-string-in-vue-before-it-is-displayed-x8oq1?file=/src/App.vue


API композиции

 <script setup>
import { ref } from 'vue'
let template = "<p> {{ message }} {{ message2 }} </p>"
let message = ref('hello')
let message2 = ref('world')

let data = { message, message2 }
function parse(html) {
  return html.replace(/{{(. ?)}}/g, (_, g) => {
    return this[g.trim()].value;
  });
}
parse = parse.bind(data)
</script>

<template>
  <input v-model="message">
  <input v-model="message2">
  <div v-html="parse(template)"></div>
</template>
 

Демонстрация с полями реактивного ввода — на примере @tauzN.

Ссылка

Комментарии:

1. Я использую api композиции, .это недоступно для меня, поэтому пришлось выставить некоторые переменные. Может быть, есть другой способ раскрыть это, но я думаю, что просто иметь отдельный объект может быть лучше. Для меня путь к объекту выглядит так game.player.name или опонент.выносливость

2. Я также обновил пример API композиции. @орбитальный