我准备基于 Vue3 技术写一个富文本编辑器组件,并以组件库的形式打包上传 NPM 仓库,且有其他 Vue3 的项目下载并使用
以下是富文本编辑器的一个子组件,它是富文本编辑器的工具栏(Toolbar)部分,这部分功能为将工具栏的每个工具项通过循环的方式显示在界面,每个工具项都有专属的 ICON 图标(图标是:SVG),代码如下:
注意:为聚焦问题,将代码进行了简化,代码中的 ... 处指代省略代码部分
<template>
<div id="editorMenu" class="editor-menu">
<div
ref="menuItems"
v-for="(name, index) in menu"
...
>
<template>
<button ...>
<!-- 标题 -->
<template v-if="name === 'heading'">
'正文'
<svg class="icon arrow-down">
<use :xlink:href="`${remixicon}arrow-down`"></use>
</svg>
</template>
</button>
</template>
<div>
...
<div>
</template>
<script lang="ts" setup>
import remixicons from '@/assets/remixicon.symbol.svg';
const remixicon = computed(() => `${remixicons}#`);
const menu = computed(() => ['heading']);
...
</script>
以下为 SVG 图标文件,文件全路径为:src/assets/remixicon.symbol.svg,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="0" height="0" style="display:none;">
<symbol id="arrow-down" viewBox="0 0 24 24">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12 15l-4.243-4.243 1.415-1.414L12 12.172l2.828-2.829 1.415 1.414z"/>
</symbol>
</svg>
我采用的打包工具是 Vite,且 vite.config.js 配置如下:
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import { resolve } from 'path';
import { defineConfig, loadEnv } from 'vite';
import autoprefixer from 'autoprefixer';
import tailwindcss from 'tailwindcss';
import dts from 'vite-plugin-dts';
export default defineConfig(({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };
return {
resolve: {
alias: {
'@': resolve(__dirname, 'src/'),
},
},
plugins: [
vueJsx({ isCustomElement: (tag) => tag === 'iconpark-icon', include: ['../**/*.tsx'] }),
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => {
return tag === 'iconpark-icon';
},
},
},
customElement: 'iconpark-icon',
}),
dts({
outDir: './dist/types',
}),
],
css: {
postcss: {
plugins: [tailwindcss, autoprefixer]
},
preprocessorOptions: {
less: {
modifyVars: {
// "@prefix-base": "asw",
},
},
},
},
build: {
lib: {
name: 'Chapter',
entry: resolve(__dirname, 'src/index.ts'),
fileName: (format) => `index.${format}.js`,
},
target: 'esnext',
outDir: 'dist',
assetsDir: 'static',
sourcemap: true,
optimizeDeps: {
include: ['vue', 'vue-router', '@ant-design/icons-vue'],
},
rollupOptions: {
external: ['vue', 'ant-design-vue', 'ant-design-vue/dist/antd.css'],
output: {
entryFileNames: `[name].es.js`,
globals: {
vue: 'Vue',
'ant-design-vue': 'ant-design-vue',
},
},
},
},
esbuild: {
// minify: true,
treeShaking: true,
},
};
});
工程中 ts.config.js 的配置如下:
{
"compilerOptions": {
"rootDir": "./src",
"baseUrl": "./",
"paths": { "@/*": ["src/*"] },
"outDir": "./dist",
"target": "esnext",
"module": "esnext",
"lib": ["es2015", "es2016", "es2017", "esnext", "dom"],
"sourceMap": true,
"allowJs": true,
"incremental": false,
"strict": true,
"alwaysStrict": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/types",
"typeRoots": [
"node_modules/@types"
],
"moduleResolution": "node",
"esModuleInterop": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "test/**/*.ts", "test/**/*.d.ts", "test/**/*.tsx"],
"exclude": ["node_modules", "test", "reports", "dist"]
}
组件在 storybook 用例中显示正常,效果如下:
注意:前面代码循环中的,以及 svg 文件的 arrow-down,显示的就是这个向下箭头
该图标在浏览器控制台中查看的结果代码如下:
<button class="hover:bg-gray-100 heading">
正文
<svg class="icon arrow-down">
<use xlink:href="/src/assets/remixicon.symbol.svg#arrow-down"></use>
</svg>
</button>
但是当我用 Vite 将工具库打包发布 NPM,并在其他 Vue3 业务项目的页面中引用这个组件时,包括下拉箭头在内的各种图标都不显示。业务项目中的运行效果如下:
该图标在浏览器控制台中查看的结果代码如下:
<svg class="icon arrow-down">
<use xlink:href="data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='utf-8'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20xlink='http://www.w3.org/1999/xlink'%20width='0'%20height='0'%20style='display:none;'%3e%3csymbol%20id='bold'%20viewBox='0%200%2024%2024'%3e%3cpath%20fill='none'%20d='M0%200h24v24H0z'/%3e%3cpath%20d='M8%2011h4.5a2.5%202.5%200%201%200%200-5H8v5zm10%204.5a4.5%204.5%200%200%201-4.5%204.5H6V4h6.5a4.5%204.5%200%200%201%203.256%207.606A4.498%204.498%200%200%201%2018%2015.5zM8%2013v5h5.5a2.5%202.5%200%201%200%200-5H8z'/%3e%3c/symbol%3e%3csymbol%20id='italic'%20viewBox='0%200%2024%2024'%3e%3cpath%20fill='none'%20d='M0%200h24v24H0z'/%3e%3cpath%20d='M15%2020H7v-2h2.927l2.116-12H9V4h8v2h-2.927l-2.116%2012H15z'/%3e%3c/symbol%3e%3csymbol%20id='strike'%20viewBox='0%200%2024%2024'%3e%3cpath%20fill='none'%20d='M0%200h24v24H0z'/%3e%3cpath%20d='M17.154%2014c.23.516.346%201.09.346%201.72%200 ... ... ... ... cpath%20d='M3%204h18v2H3V4zm2%2015h14v2H5v-2zm-2-5h18v2H3v-2zm2-5h14v2H5V9z'/%3e%3c/symbol%3e%3csymbol%20id='align-right'%20viewBox='0%200%2024%2024'%3e%3cpath%20fill='none'%20d='M0%200h24v24H0z'/%3e%3cpath%20d='M3%204h18v2H3V4zm4%2015h14v2H7v-2zm-4-5h18v2H3v-2zm4-5h14v2H7V9z'/%3e%3c/symbol%3e%3csymbol%20id='arrow-down'%20viewBox='0%200%2024%2024'%3e%3cpath%20fill='none'%20d='M0%200h24v24H0z'/%3e%3cpath%20d='M12%2015l-4.243-4.243%201.415-1.414L12%2012.172l2.828-2.829%201.415%201.414z'/%3e%3c/symbol%3e%3csymbol%20id='check'%20viewBox='0%200%2024%2024'%3e%3cpath%20fill='none'%20d='M0%200h24v24H0z'/%3e%3cpath%20d='M10%2015.172l9.192-9.193%201.415%201.414L10%2018l-6.364-6.364%201.414-1.414z'/%3e%3c/symbol%3e%3csymbol%20id='color'%20viewBox='0%200%2024%2024'%3e%3cpath%20fill='none'%20d='M0%200h24v24H0z'/%3e%3cpath%20d='M15.246%2014H8.754l-1.6%204H5l6-15h2l6%2015h-2.154l-1.6-4zm-.8-2L12%205.885%209.554%2012h4.892zM3%2020h18v2H3v-2z'%20/%3e%3c/symbol%3e%3c/svg%3e#arrow-down"></use>
</svg>
请问:我怎样才能让这些图标在依赖该组件库的 VUE3 项目里正常显示?