Vue - визуализация элемента из строки - PullRequest
0 голосов
/ 29 мая 2018

Я хотел бы создать элемент vue из строки из моей базы данных.

В этом случае это должно быть сообщение со смайликом из смайлика.Я фактически сохраняю это как: Some text with Emoji: :santa::skin-tone-3:, и заменяю всю действительную строку между '::' на <Emoji emoji=':santa::skin-tone-3:' :size='16' />

<template>
  <span class=message v-html=convertedMessage></div>
</template>

<script>
  import { Emoji } from 'emoji-mart-vue'

  export default {
    components: {
      Emoji
    },
    computed:{
      convertedMessage(){
        return "Some text with Emoji: "+"<Emoji emoji=':santa::skin-tone-3:' :size='16' />"
      }
    }
  }
</script>

Но вместо отрендеренного элемента, который должен быть чем-то вроде:

<span data-v-7f853594="" style="display: inline-block; width: 32px; height: 32px; background-image: url(&quot;https://unpkg.com/emoji-datasource-apple@4.0.4/img/apple/sheets/64.png&quot;); background-size: 5200%; background-position: 15.6863% 41.1765%;"></span>

Я получаю только:

<emoji emoji=":santa::skin-tone-3:" :size="16"></emoji>

Какая лучшая возможность сделать этот элемент как задумано?

Ответы [ 3 ]

0 голосов
/ 29 мая 2018

Что я понял сейчас:

convertedMessage(){
    let el = Vue.compile("<Emoji emoji=':santa::skin-tone-3:' :size='16' />")
    el = new Vue({
        components: {
            Emoji
        },
        render: el.render,
        staticRenderFns: el.staticRenderFns
    }).$mount()
    return "Some text with Emoji: "+el.$el.innerHTML
}

Может быть, есть еще лучшее решение для этого?

0 голосов
/ 13 декабря 2018

Вот несколько более простых способов сделать то, что вы обычно хотите.Если вы дадите больше подробностей, ваше правильное направление может быть шаблоном стратегии перед одним из этих решений, но, вероятно, вам нужно одно из этих решений:

1) Vue позволяет динамически определять компоненты прямо из коробки, так что эта единственная строка:

<component v-for="(component, index) in components" :key="'component'+index" :is="component.name" v-bind="component.props" />

... будет рисовать группу компонентов в массиве объектов, таких как этот (например): {name: 'myComponentName', props: {foo: 1,bar: 'baz'}}.

2) Vue позволяет внедрять HTML в компоненты, просто добавляя v-html = "variable"

Например, вот компонент, который создает динамический SVGзначки, где содержимое SVG динамически вводится из переменных JavaScript ...

<template>
  <svg xmlns="http://www.w3.org/2000/svg"
    :width="width"
    :height="height"
    viewBox="0 0 18 18"
    :aria-labelledby="name"
    role="presentation"
  >
    <title :id="name" lang="en">{{name}} icon</title>
    <g :fill="color" v-html="path">
    </g>
  </svg>
</template>

<script>
import icons from '../common/icons'
export default {
  props: {
    name: {
      type: String,
      default: 'box'
    },
    width: {
      type: [Number, String],
      default: 18
    },
    height: {
      type: [Number, String],
      default: 18
    },
    color: {
      type: String,
      default: 'currentColor'
    }
  },
  data () {
    return {
      path: icons[this.name]
    }
  },
  created () {
    console.log(icons)
  }
}
</script>

<style scoped>
  svg {
    display: inline-block;
    vertical-align: baseline;
    margin-bottom: -2px;
  }
</style>

3) Vue позволяет динамически определять шаблон компонента с помощью этого. $ options.template:

export default {
  props: ['name', 'props'],
  template:  '',
  created(){
    this.$options.template = `<component :is="name" ${props.join(' ')} ></component>`
  },
}

4) Vue позволяет вам определить функцию рендеринга, поэтому прокси-компоненты или другие продвинутые махинации тривиальны:

Vue.component('component-proxy', {
  props: {
    name: {
      type: String,
      required: true
    },
    props: {
      type: Object,
      default: () => {}
    }
  },
  render(h) {
    // Note the h function can render anything, like h('div') works too.
    // the JS object that follows can contain anything like on, class, or more elements
    return h(this.name, {
      attrs: this.props
    });
  }
});

Умный гений написал для этого jsbin: http://jsbin.com/fifatod/5/edit?html,js,output

5) Vue позволяетчтобы создать компоненты с помощью Vue.extend или даже передать необработанные объекты JavaScript в раздел компонентов страницы или приложений, например, который создает компонент с именем «foo» из простой строки для шаблона и массива для реквизитов, вы также можетеРасширить данные, созданные, и т. д. таким же образом, используя только объект JS:

new Vue({
  el: '#app',
  data: {
    foo: 'bar',
    props: {a: 'a', b: 'b'}
  },
  components: {
    foo: {
      template: '<p>{{ a }} {{ b }}</p>',
      props: ['a', 'b']
    }
  }
})
0 голосов
/ 29 мая 2018

v-html отображает только обычный HTML, см. https://vuejs.org/v2/guide/syntax.html#Raw-HTML

В вашем случае вам, вероятно, стоит взглянуть на функции рендеринга и JSX.Я не эксперт, но кажется, что некоторые люди достигают того, что вы хотите, с помощью функции dangerouslySetInnerHTML JSX.Взгляните на эту ветку: Как мне преобразовать строку в jsx?

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

...