Programing

Vue.js에서 사용자 지정 렌더 기능이 있는 텍스트 노드 생성

c10106 2022. 5. 24. 23:01
반응형

Vue.js에서 사용자 지정 렌더 기능이 있는 텍스트 노드 생성

A를 사용하고 있다.my-link다양한 품목에 대한 요구에 따라 앵커 태그를 포장하는 구성 요소.그 목적으로는 관습이 있다.render방법 사용 - 그러나createElement메소드는 HTML 노드만 만들 수 있으며, 일반 텍스트 노드 생성은 불가능해 보인다.

현재 시나리오

의 사용법my-link구성 요소

<template v-for="item in items">
  <h4>
    <my-link :url="item.url">{{ item.text }}</my-link>
  </h4>
</template>

구현my-link으로 구성되다.Link.vue

<script>
export default {
  name: 'my-link',
  props: { url: String },
  render(createElement) {
    if (this.url) {
      return createElement(
          'a', {
            attrs: { href: this.url }
          }, this.$slots.default
      );
    }

    return createElement(
        'span',
        this.$slots.default
    );
  }
};
</script>

결과 HTML

<h4>
  <a url="/some-link">This item is linked</a>
</h4>
<h4>
  <span>Plain text item</span>
</h4>

원하는 시나리오

span이 특정 시나리오의 태그는 불필요하며 피할 수 있다. 하지만, 나는 이것이 Vue.js를 통해 어떻게 그리고 어떻게 가능한지 확실하지 않다.일반적으로 사용자 정의를 사용하여 일반 텍스트 노드를 생성하는 방법을 알고 싶다.render방법의

<h4>
  <a url="/some-link">This item is linked</a>
</h4>
<h4>
  Plain text item
</h4>

사이드 노트:

  • 원래 VueJS v2.1 & v2.2-베타에 대한 질문이 제기되었다(2017년 2월)
  • 적절한 의미 노드(텍스트 노드 대 요소 노드)에 초점을 맞췄다.

Vue는 일반 텍스트 노드를 생성하는 _v라는 시제품에 내부 방법을 노출한다.렌더 함수에서 이 메서드를 호출한 결과를 반환하여 일반 텍스트 문자열을 렌더링하십시오.

render(h){
    return this._v("my string value");
}

이러한 방식으로 노출하면 밑줄이 접두사로 되어 있어 개인 API 방법으로 의도된 것일 수 있으므로 주의하여 사용하십시오.

기능 구성요소를 사용할 경우 "이것"도 사용할 수 없다.이런 경우에는 문맥을 불러야 한다._v(), 예:

functional: true,
render(h, context){
    return context._v("my string value")
}

이렇게 하면 슬롯에서 텍스트를 추출할 때(설명에서처럼 유용한 getChildrenTextContent를 사용) 원하는 결과를 얻을 수 있다.

MyLink 구성 요소의 구현을 기능 구성요소로 변경함으로써 위에서 언급한 _v 방법을 사용해야 하는 상황을 실제로 경험할 수 있으며(나중에 이름이 변경될 수 있는 내부 Vue 방법을 사용하지 않도록 할 수도 있음)기능 구성요소는 루트 요소를 필요로 하지 않기 때문에 링크되지 않은 요소 주위에 스팬을 배치해야 한다.

MyLink는 다음과 같이 정의될 수 있다.

const MyLink = {
  functional: true,
  name: 'my-link',
  props: { url: String },
  render(createElement, context) {
    let { url } = context.props
    let slots = context.slots()
    if (url) {
      return createElement(
          'a', {
            attrs: { href: url }
          }, slots.default
      );
    }
    else {
      return slots.default 
    }
  }
};

그런 다음 다른 구성 요소에서 이와 같은 작업을 수행할 수 있다.

<div>
  <h4 v-for="item in items">
    <my-link :url="item.url">{{ item.text }}</my-link>
  </h4>
</div>

https://codepen.io/hunterae/pen/MZrVEK?editors=1010을 참조하십시오.

또한, 사이드 노트로 원본 코드 스니펫에서 파일 이름을 Link.vue로 지정하고 있는 것으로 보인다.당신은 Vue의 템플리트 시스템을 사용하는 대신 당신만의 렌더 기능을 정의하고 있기 때문에 이론적으로 파일의 이름을 Link.js로 바꾸고 시작과 종료 스크립트 태그를 제거하고 완전한 JS 구성 요소 파일을 가질 수 있다.그러나 구성 요소에 사용자 지정 시스템(스니핏이 포함하지 않은 시스템)이 포함되어 있으면 이 방법은 작동하지 않는다.이게 도움이 되길 바래.

만약 누군가가 이 질문에 직면하여 현재 Vue 3을 사용하고 있는 경우: API가 변경되었다.현재 두 가지 옵션이 있음:

  • 설치하다@vue/compat접근하다_v()부에 2와 같이
  • 그렇지 않으면 을 선택한다.createTextVNode()대신:
import { createTextVNode, VNode } from 'vue';

export const renderMoney = (data: number): VNode =>
  createTextVNode(data.toLocaleString('en'));

이 예(형식)에서는 숫자를 전달하고 일반 텍스트를 얻을 수 있다.VNode뒤쪽에

어떤 사적인 방법을 쓸 필요 없이 이것을 하는 것은 사실 매우 간단하다.

A VNode텍스트가 정의되지 않은 모든 속성을 가진 렌더링 텍스트.

그러니까 그냥 하면 돼.

return { text: 'my text' };

만약 당신이 TypeScript를 사용하고 있다면, 당신은 그것이 VNode라고 주장할 필요가 있다.

구성 요소에 대한 루트 요소가 필요한 경우.너의 경우, 아마도 'h4'를 루트 요소로 사용할 수 있을 거야. 어차피 v-for loop에 포함시키니까.일단 그렇게 하고 나면, 이렇게 텍스트 노드를 만들 수 있다.

return createElement(
    'h3',
    {},
    ['Plain text item']
);

Vue 설명서에 따르면 createElement의 세 번째 인수는 문자열 또는 어레이일 수 있으며, 문자열일 경우 텍스트 노드로 변환된다.

https://vuejs.org/v2/guide/render-function.html#createElement-Arguments

Vue 2.5.x에서는 다음을 사용하여 텍스트 노드를 렌더링할 수 있다.

render(createElement) {
    return createElement(() => {
        return document.createTextNode('Text');
    });
}

참조URL: https://stackoverflow.com/questions/42414627/create-text-node-with-custom-render-function-in-vue-js

반응형