programing

Vue - 문자열 외 요소 렌더링

copysource 2022. 7. 21. 22:38
반응형

Vue - 문자열 외 요소 렌더링

데이터베이스의 문자열에서 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>

이 요소를 의도한 대로 렌더링할 수 있는 가장 좋은 방법은 무엇입니까?

여기 여러분이 일반적으로 원하는 것을 할 수 있는 훨씬 더 쉬운 방법들이 있습니다.좀 더 자세한 내용을 제시하면 다음 솔루션 중 하나의 전략 패턴이 올바른 방향일 수 있지만 다음 솔루션 중 하나가 원하는 것일 수 있습니다.

1) Vue에서는 개봉 즉시 컴포넌트를 동적으로 정의할 수 있습니다.이것에 의해, 다음의 행이 실현됩니다.

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

...이러한 오브젝트 배열에 컴포넌트 묶음을 그립니다(예: {name: 'myComponentName', 소품: {foo: 1, bar: 'baz'}).

2) v-timeout="timeout"을 추가하는 것만으로 HTML을 컴포넌트에 삽입할 수 있습니다.

예를 들어 동적 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를 통해 컴포넌트 템플릿을 동적으로 정의할 수 있습니다.$180.199:

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을 썼다.

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']
    }
  }
})

내가 알아낸 건

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
}

이 문제를 해결할 수 있는 더 나은 해결책이 아직 있을까요?

내가 비슷한 일을 해야 할 때 했던 일은 이렇다.

저는 그 구성 요소를 렌더링했습니다. 예를 들어,<my-component>보통이지만, 렌더링된 HTML만 필요했기 때문에, 나는 그것을 안에 감쌌다.<div class="hidden">다음과 같이 합니다.

<div class="hidden">
   <my-component />
</div>

CSS의 경우:

.hidden {
  display: none;
}

이렇게 하면 원소를 참조할 수 있습니다.$refs또는 DOM에서 요소를 가져올 수 있습니다.document.querySelector()최종 사용자에게 보이지 않게 하면서도 말이죠.

위의 예에서 렌더링된 HTML을 가져오려면 다음 작업만 수행하면 됩니다.

let el = document.querySelector('.hidden');
let renderedHTMLString = el.children[0].outerHTML;

하면 렌더링된HTML을 수 」와 .HTML을 얻을 수 있으며 이로 인해 발생하는 오버헤드 비용은 발생하지 않습니다.Vue.compile또는 기타 플러그인입니다.정상적으로 렌더링합니다. 숨겨라. 외부 액세스HTML.

v-html플레인 HTML만 렌더링합니다.https://vuejs.org/v2/guide/syntax.html#Raw-HTML 를 참조해 주세요.

. 사람들은 것을 것 .dangerouslySetInnerHTMLJSX 함수이 스레드 보기: 문자열을 jsx로 변환하려면 어떻게 해야 합니까?

어쩔 수 없는 경우도 있습니다만, 가능하면 백엔드에서 템플릿을 생성하지 않는 것이 가장 좋은 해결책이라고 생각합니다.이는 관심사(및 보안 문제)의 분리가 깨지기 때문입니다.

언급URL : https://stackoverflow.com/questions/50579006/vue-render-an-element-out-of-string

반응형