source

HTML 내의 Vue 컴포넌트를 다른 Vue 컴포넌트에 추가하려면 어떻게 해야 합니까?

factcode 2022. 8. 31. 22:33
반응형

HTML 내의 Vue 컴포넌트를 다른 Vue 컴포넌트에 추가하려면 어떻게 해야 합니까?

거대한 동적 HTML 문자열을 로드하고 있습니다.divVue 컴포넌트 내에 있습니다.HTML 문자열은 기본적으로 WYSIWYG 에디터의 콘텐츠입니다.원래는 그냥...v-html그래도 괜찮았어요

그러나 현재 HTML 문자열의 일부를 실제 Vue 컴포넌트로 교체해야 하는 경우가 있는데, 이를 위한 최선의 방법을 잘 모르겠습니다.

예를 들어 HTML 문자열에 다음과 같은 마크업이 있을 수 있습니다.

||map:23||

이 컴포넌트를 다음과 같은 Vue 컴포넌트로 교체합니다.

<map-component :id="23"></map-component>

라라벨에서 미리 스트링 변환을 시도했고v-htmlVue 컴포넌트에서 콘텐츠를 주입하지만 Vue 컴포넌트가 로드되지 않는 것 같습니다.

그 후 HTML 콘텐츠에 슬롯을 사용하려고 했습니다만, 그것은 동작합니다만, Vue가 올바르게 렌더링 할 수 있을 때까지 1, 2초간 화면에 포맷되지 않은 HTML 콘텐츠를 표시하는 불쾌한 부작용이 있습니다.

그래서 제가 묻고 싶은 것은, 이것을 할 수 있는 (더 우아한) 다른 방법이 있을까요?HTML 컨텐츠와 함께 Vue 컴포넌트를 로드한 후, 예를 들어,||map:23||마크업에서 인스턴스를 올바른 Vue 컴포넌트로 동적으로 치환합니다만, 가능하다면 Vue 문서에서는 아무것도 찾을 수 없었습니다.

이게 가능한지 아는 사람 있어요?감사합니다.

를 사용하여 템플릿 문자열(vue 구성 요소 포함)을 컴파일할 수 있습니다.

그런 다음 이 컴포넌트와 결합할 수 있습니다.render()method, 템플릿을 렌더링하는 방법:

// this component will dynamically compile the html
// and use it as template for this component.
Vue.component("dynamic-html", {
  props: ["html"],
  computed: {
    template() {
      if(this.html)
        return Vue.compile(this.html).render;
      return null;
    }
  },
  render() {
    if(this.template)
      return this.template();
    return null;
  }
});

이를 통해 vue 구성 요소를 포함할 수도 있는 arbirary 템플릿 문자열을 렌더링할 수 있습니다.

<dynamic-html html="<some-component></some-component>">
</dynamic-html>

또한 이를 사용하여 소품/이벤트 핸들러를 문자열 내의 컴포넌트에 전달할 수도 있습니다.

<!-- Passing down props -->
<dynamic-html
    html='<some-component :prop="$attrs.myprop"></some-component>'
    :myprop="12"
></dynamic-html>

<!-- passing down events -->
<dynamic-html
    html='<some-component @click="$emit('foo', $event)"></some-component>'
    @foo="doSomething"
></dynamic-html>

(사용자는$attrs소품에는 접근할 수 없지만props의 정의dynamic-html컴포넌트)

풀 코드 예시:

// this component will dynamically compile the html
// into a vue component
Vue.component("dynamic-html", {
  props: ["html"],
  computed: {
    template() {
      if(this.html)
        return Vue.compile(this.html).render;
      return null;
    }
  },
  render() {
    if(this.template)
      return this.template();
    return null;
  }
});

Vue.component("red-bold-text", {
  props: ["text"],
  template: '<span class="red">{{text}}</span>'
});

new Vue({
  el: '#root',
  data: {
    html: null,
    myBoundVar: "this is bound from the parent component"
  },
  mounted() {
    // get the html from somewhere...
    setTimeout(() => {
      this.html = `
        <div>
          WELCOME!
          <red-bold-text text="awesome text"></red-bold-text>
          <red-bold-text :text="$attrs.bound"></red-bold-text>
          <button @click="$emit('buttonclick', $event)">CLICK ME</button>
        </div>
      `;
    }, 1000);
  },
  methods: {
    onClick(ev) {
      console.log("You clicked me!");
    }
  }
});
.red { color: red; font-weight: bold; margin: 6px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="root">
  <div>This will load dynamically:</div>
  <dynamic-html :html="html" :bound="myBoundVar" @buttonclick="onClick"></dynamic-html>
</div>

Turtlefight의 대답은 매우 완전한 그러나 누구든지 빠르고 간단한 해답을 찾는, 리터럴을 사용한다 도움이 된다.component으로 구성하다와 요소이다.:is다른 동적 구성 요소로 HTML콘텐츠 뷰 구성 요소가 포함된 예산을 투입할 수는 다음과 같다.뷰 컴포넌트를 포함하는 HTML콘텐츠를 동적 컴포넌트에 삽입하려면 다음과 같이 하십시오.

// htmlStrWithVueComponents is a large string containing HTML and Vue components.
<component
    :is="{
        template: `<div>${htmlStrWithVueComponents}</div>`
    }"
>
</component>

다음은 이 기술을 설명하는 몇 가지 소스입니다.


편집: 주의할 점은component :is상당히 당신은 무엇을 할 수 있는 것에 한계 있다.할 수 있는 일이 상당히 한정되어 있습니다.당신은 매우 복잡한 그렇게수는 없다 만들 복잡하게할 수 없다.template주로 끈이나 추가 문자열 또는추가된 문자열mounted방법 등방법 등

특히, 이 보다 복잡한 작업이 필요했기 때문에, 위의 간단한 답변과 Turtlefight의 답변이 혼재된 다음과 같이 되었습니다.

// This code goes within the parent component's mounted method or wherever is makes sense:
Vue.component('component-name-here', {
    // Can add much more complex template strings here.
    template: `
        <div class="someClass">
            ${content}
        </div>
    `,
    // Can add lifecycle hooks, methods, computed properties, etc.
    mounted: () => {
        // Code here
    }
});

const res = Vue.compile(`
    <component-name-here>
    </component-name-here>
`);

new Vue({
    render: res.render,
    staticRenderFns: res.staticRenderFns
}).$mount('dom-selector-for-dom-element-to-be-replaced-by-vue-component');

언급URL : https://stackoverflow.com/questions/57277705/how-can-i-add-a-vue-component-within-some-html-to-another-vue-component

반응형