[英]Vue3 How to parse SFC string to a component?
我想將 sfc 字符串編譯為這樣的組件:
<script setup>
import { parseToComponent } from './';
const sfcString = `
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
<template>
<div class="label">{{ count }}</div>
<button @click="count++">increase</button>
</template>
<style scoped>
.label {
color: red;
}
</style>
`;
const parsedComponent = parseToComponent(sfcString);
</script>
<template>
<div>
<parsedComponent />
</div>
</template>
<style scoped>
</style>
我怎樣才能做到這一點?
我嘗試使用vue/compiler-sfc
解析和編譯sfcString
,但我不知道如何將其轉換為組件:
import { parse, compileTemplate, compileScript, compileStyle } from 'vue/compiler-sfc';
export function parseToComponent(sfcString) {
const { descriptor } = parse(sfcString);
const scriptOptions = ...;
const templateOptions = ...;
const styleOptions = ...;
// succeed, but how to use them to take a component?
const script = compileScript(descriptor, scriptOptions);
const template = compileTemplate(templateOptions);
const style = compileStyle(styleOptions);
}
我使用vue3-sfc-loader來實現它:
import * as Vue from 'vue';
import { loadModule } from 'vue3-sfc-loader';
export function parseToComponent(sfcString) {
const id = genRandomId(id);
const options = {
moduleCache: { vue: Vue },
async getFile(url) {
return Promise.resolve(sfcString);
},
addStyle(styleString) {
let style = document.getElementById(id);
if (!style) {
style = document.createElement('style');
style.setAttribute('id', id);
const ref = document.head.getElementsByTagName('style')[0] || null;
document.head.insertBefore(style, ref);
}
style.textContent = styleString;
}
};
const component = loadModule(`${id}.vue`, options);
return Vue.defineAsyncComponent(() => component);
}
在代碼中使用(需要markRaw()
):
<script setup>
import { markRaw } from 'vue';
import { parseToComponent } from './';
const sfcString = `...`;
const parsedComponent = markRaw(parseToComponent(sfcString));
</script>
<template>
<div>
<parsedComponent />
</div>
</template>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.