为什么要封装组件
- 避免重复工作量(模块化)
- 代码连加清晰(抽象化)
- 超大型企业级应用(可扩展性)
准备工作
- 知识库 基础HTML,javaScript,Vue基础
- 项目准备 目录结构
- 组件封装 实际应用组件
- 项目npm发布
安装
平时都是vue cli这次以一种新的方式来搭建,先打开vite官网 搭建第一个 Vite 项目
npm init vite@latest
安装过程中提示选择vue、JavaScript
按照提示安装、运行,这样就一个项目安装成型了。
开始创建组件
- vue3逻辑复用之插件运用
使用插件 (Plugins) 将多个组件串连起来,方便多个组件引入使用
整理代码及插件 (Plugins) 使用
目录如下:
之前初始创建的那些多余代码及文件都删除,只保留核心目录及代码
创建F:\projects\vue3-components\packages\components\Icon.vue
<template>
<div>
这是一个测试文件
</div>
</template>
创建F:\projects\vue3-components\packages\index.js
import Icon from './components/Icon.vue'
const myPlugin = {
install(app) {
// 配置此应用
app.component('Icon', Icon)
}
}
export default myPlugin
F:\projects\vue3-components\src\App.vue
<template>
<div>
<Icon/>
</div>
</template>
F:\projects\vue3-components\src\main.js
import {createApp} from 'vue'
import App from './App.vue'
const app = createApp(App)
import myPlugin from "../packages/index.js";
app.use(myPlugin)
app.mount('#app')
改造icon文件,变成可复用的icon组件
ps:这个可根据自己的业务来做组件,下面做的步骤是针对icon封装记录的代码,不需要的可忽略掉
阿里巴巴iconfont symbol来实现
点击复制代码后,在项目根目录下F:\projects\vue3-components\index.html增加
<script src="//at.alicdn.com/t/c/font_4476687_545beinp8sd.js"></script>
在引入fonticon里查看使用帮助一步步操作
修改F:\projects\vue3-components\src\App.vue
<template>
<div>
<Icon iconName="icon-a-MATE_huaban1fuben112" @handleClick="handleClick"/>
</div>
</template>
<script>
import {defineComponent} from 'vue';
export default defineComponent({
setup() {
const handleClick = () => {
alert('我被点击了')
};
return {
handleClick
}
}
})
</script>
修改F:\projects\vue3-components\packages\components\Icon.vue
<template>
<div>
<svg :class="svgClass" aria-hidden="true" @click="handleClick">
<use :xlink:href="iconName"></use>
</svg>
</div>
</template>
<script>
import {defineComponent, ref} from "vue";
//icon的一个hooks
function useIcon(props, context) {
const svgClass = ref(`icon ${props.svgClass}`);
const iconName = ref(`#${props.iconName}`);
const handleClick = () => {
context.emit('handleClick')
}
return {
svgClass,
iconName,
handleClick
}
}
export default defineComponent({
props: {
svgClass: {
type: String,
default: ''
},
iconName: {
type: String,
required: true,//必传
}
},
setup(props, context) {
const useIconData = useIcon(props, context)
return {
...useIconData
}
}
})
</script>
<style scoped>
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
cursor: pointer;
}
</style>
ps:组件继承
- extends
打包脚本
创建F:\projects\vue3-components\build\lib.config.js
import {defineConfig} from "vite";
import {resolve} from 'path';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
build: {
outDir: 'dist',
lib: {
entry: resolve(__dirname, "../packages/index.js"),
name: 'my-components',
fileName: (format) => `my-components-${format}.js`//umd es
},
rollupOptions: { //打包
external: ['vue'],//不打包项
output: {
//UMD模式下为那些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue'
}
}
}
},
plugins: [
vue({
include: [/\.vue$/], //必须打包 包含.vue文件
})
]
})
发布npm包配置
修改F:\projects\vue3-components\package.json
发布npm
可参考 公用工具类js发布到npm 引入到vue 发布到npm
应用到项目
安装组件库
npm install vue3-component-examples
全局引用
项目根目录main.js里
import componentExamples from 'vue3-component-examples'
import 'vue3-component-examples/dist/style.css'; // 引入公共样式 这个是在组件打包库里生成的样式文件
app.use(componentExamples);