쇼트 코드에서 Vue 2 컴포넌트를 동적으로 주입합니다.
사용자가 쇼트 코드를 포함한 텍스트를 입력할 수 있는 폼이 관리 영역에 있습니다.
오븐을 [125 c=200]으로 가열합니다.
내가 원하는 것은 이다.temp
프런트 엔드에 표시되어 있는 경우는, 해석해 Vue 2 컴포넌트로 변환합니다.
여기 간략화된 것이 있습니다.Temperature.vue
컴포넌트:
<template>
<span class="temperature">
{{ celsius }}°C
</span>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
props: ['celsius'],
name: 'temperature'
}
</script>
그리고 여기 간단한 것이 있습니다.Instructions.vue
쇼트 코드로 텍스트를 해석 및 렌더링하는 컴포넌트:
<template>
<div v-html="parseShortcodes(text)"></div>
</template>
<script>
import ShortcodeParser from 'meta-shortcodes'
import Temperature from 'Temperature.vue'
export default {
data: () => {
return {
text: 'Heat oven at [temp c=200]',
parser: ShortcodeParser()
}
},
components: [
Temperature
],
methods: {
parseShortcodes(text) {
return this.parser.parse(text)
}
},
created() {
this.parser.add('temp', function(options) {
return '<temperature :celsius="'+options.c+'"></temperature>'
})
}
}
</script>
해석은 정상적으로 동작하며, 치환은 프런트 엔드로 인쇄됩니다.근데...<temperature>
태그는 Vue 컴포넌트가 아닌 문자 그대로 렌더링됩니다.이것은 어느 정도 예상되고 있습니다.
오븐을 <온도:420="200"><온도>로 가열
머리를 싸매지 못할 것 같은 것은 실제로 변모하기 위해 어떤 단계를 밟아야 하는가 하는 것입니다.Temperature
컴포넌트를 정의합니다.그게 가능하기나 해?제가 놓치고 있는 더 정통적인 방법이 있을까요?
또한 보안상의 문제가 있습니다.v-html
텍스트를 렌더링합니다.이게 꼭 거기 있는 건 아니지만, 내 생각엔 더 이상 기대하기 힘들 것 같아.Temperature
이스케이프된 문자열에서 표시되는 컴포넌트.데이터베이스에 삽입하기 전에 언제든지 데이터를 삭제할 수 있지만, 그래도 삭제는 피하고 싶다.v-html
가능하다면
예를 사용하려면 명령 구성요소의 렌더링 기능을 사용해야 합니다.렌더 함수에서는 새로운 Vue 컴포넌트(예를 들어 'instruction')를 작성할 수 있습니다.이것에 쇼트 코드 해석의 결과 문자열을 전달해 템플릿으로 사용할 수 있습니다.이 컴포넌트 선언에서는 Temperature 컴포넌트를 아이로 추가하여 통과한 프로포넌트를 렌더링합니다.그리고 이것이 마지막입니다.예를 다음에 나타냅니다.
지침들.표시하다
<script>
import ShortcodeParser from 'meta-shortcodes'
import Temperature from 'Temperature.vue'
export default {
data: () => {
return {
text: 'Heat oven at [temp c=200]',
parser: ShortcodeParser()
}
},
methods: {
parseShortcodes(text) {
return this.parser.parse(text)
}
},
render (createElement) {
const template = this.parseShortcodes(this.text) //returns something like this <div class="intruction">'Heat oven at <temperature :celsius="200"></temperature>'</div>
var component = Vue.component('instruction', {
template: template,
components: {
'temperature': Temperature
}
})
return createElement(
'div',
{
class: {
instructions: true
}
},
[
createElement(component)
]
)
}
}
</script>
이게 내 접근법이야. 그게 네가 원하는 건지 확실하지 않아.중간 컴포넌트를 도입하여 동적으로 렌더링합니다.또한, 저는 설명서를 수정했습니다.테스트를 위해 약간의 수정이 가능하며 쇼트 코드 파서에 맞게 수정할 수 있습니다.
지침들.표시하다
<template>
<div>
<input type="text" @input="parseInput" />
<DynamicComponent :type="parsedType" :props="parsedProps"></DynamicComponent>
</div>
</template>
<script>
import DynamicComponent from './DynamicComponent';
export default {
components: {
DynamicComponent
},
data() {
return {
parsedType: '',
parsedProps: ''
};
},
methods: {
parseInput(e) { // parse the input
if (e.target.value === '[temp c=200]') { // change this to use your parser
this.parsedType = 'Temperature';
this.parsedProps = { celsius: 200 };
} else {
this.parsedType = '';
this.parsedProps = '';
}
}
}
};
</script>
다이나믹 컴포넌트표시하다
<script>
import Temperature from './Temperature';
// import all other dynamically rendered components
export default {
components: {
// let it know what components are there
Temperature
},
props: ['type', 'props'],
render(h) {
return h(this.type, {
props: this.props
}, this.$slots.default);
}
};
</script>
현재 템플릿을 컴파일하는 단계가 없으므로 템플릿이 텍스트로 렌더링됩니다.텍스트를 컴포넌트로 대체하려면 다음과 같이 하십시오.
- 온도를 찾으면 html 요소로 랩합니다.
- JavaScript에서 새 Vue 인스턴스 생성(문자열의 html 템플릿이 아님)
- el 옵션 또는 $mount를 사용하여 해당 요소의 상단에 vue 인스턴스를 마운트합니다.
- XSS https://vuejs.org/v2/guide/syntax.html#Text를 방지하려면 v-module 대신 보간 사용
언급URL : https://stackoverflow.com/questions/40573011/dynamically-inject-vue-2-component-from-shortcode
'programing' 카테고리의 다른 글
java.lang의 원인ArrayIndexOutOfBoundsException과 이를 방지하는 방법 (0) | 2022.06.12 |
---|---|
C 프로그래밍에서 정적 구조를 사용하는 이유와 시기 (0) | 2022.06.11 |
어레이의 요소에 액세스하는 데 일정한 시간이 걸리는 이유는 무엇입니까? (0) | 2022.06.11 |
OpenJDK와 Adopt Open의 차이점JDK (0) | 2022.06.11 |
최종과 실제 최종의 차이 (0) | 2022.06.11 |