Vue3+Typescript+Vite2+element-plus二次封装组件
技术储备:
- es6+
- vue2/vue3
- typescript
- element-ui/element-plus
检查版本:
- npm -v
这里是创建项目
npm create vite@latest m-components -- --template vue-ts
创建完项目安装npm install 如果有淘宝镜像 那就cnpm install
安装路由和样式组件
cnpm i -S vue-router@next element-plus
注:新建router文件下写路由然后导出和main.ts里面去引入;
sass是css的预处理器
在样式里面,由于没有安装sass所以报错了! 那就去安装一下sass吧!
安装sass
cnpm i -D sass sass-loader
打开项目npm run dev
使用SVG图标
import * as Icons from '@element-plus/icons-vue'
使用包管理器
npm install @element-plus/icons-vue
//全局注册图标 牺牲一点性能
//el-icon-xxx
for(let i in Icons){
console.log((Icons as any)[i])
}
给图标改成驼峰命名
- 创建一个utils目录
- 在目录下面index.ts
//把驼峰转换成横杠链接
export const toLine = (value:string) =>{
return value.replace(/(A-Z)g/,'-$1').toLocaleLowerCase()
}
mian.ts
//全局注册图标
//el-icon-xxx
for(let i in Icons){
//注册全部组件
//app.component方法 用
//app.component(name,组件实例)
app.component(`el-icon-${toLine(i)}`,(Icons as any)[i])
}
头部和侧边栏
路径代码
import {createRouter,createWebHistory,RouteRecordRaw} from 'vue-router'
import Home from '../views/Home.vue'
import Container from '../components/container/src/index.vue'
const routes:RouteRecordRaw[]=[
{
path:'/',
component:Container,
children:[
{
path:'/',
component:Home
}
]
}
]
const router = createRouter({
routes,
history:createWebHistory()
})
export default router
组件文件
index.vue
<template>
<div class="common-layout">
<el-container>
<el-aside width="auto">
<nav-side :collapse="isCollapse"></nav-side>
</el-aside>
<el-container>
<el-header>
<nav-header v-model:collapse="isCollapse"></nav-header>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import NavHeader from './navHeader/index.vue'
import NavSide from './navSide/index.vue'
let isCollapse = ref(false)
</script>
<style lang="scss" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
</style>
navSide目录下的index.vue
<template>
<el-menu
:collapse="collapse"
default-active="2"
class="el-menu-vertical-demo"
>
<el-menu-item index="1">
<el-icon><el-icon-menu /></el-icon>
<span>导航1</span>
</el-menu-item>
<el-menu-item index="2">
<el-icon><el-icon-menu /></el-icon>
<span>导航2</span>
</el-menu-item>
<el-menu-item index="3">
<el-icon><el-icon-menu /></el-icon>
<span>导航3</span>
</el-menu-item>
</el-menu>
</template>
<script lang="ts" setup>
import {ref} from 'vue'
import NavHeader from '../navHeader/index.vue'
import NavSide from '../NavSide/index.vue'
let collapse = ref(false)
</script>
<style lang="scss" scoped>
</style>
navHeader文件下index.vue
<template>
<span @click="toggle">
<el-icon-expand v-if="collapse"></el-icon-expand>
<el-icon-fold v-else></el-icon-fold>
</span>
</template>
<script lang="ts" setup>
let props = defineProps<{
collapse:boolean
}>()
let emits = defineEmits(['update:collapse'])
let toggle = ()=>{
//需要修改父组件的数据
emits('update:collapse',!props.collapse)
}
</script>
<style lang="scss" scoped>
</style>
组件的使用
一般我们的组件都是在每个页面引过来的,如:
这是最基本的一种引入方式,为了更方便更简洁,
我们在组件的文件中先导出去。
这是components下面的index.ts
做成数组的形式,让main.ts引进去
在各个页面只需要写这个组件,不需要引入,就很简便。
我最后疏通一下这个顺序;我们在components文件下创建组件,写完组件。
- 第一种方式的每个页面都会引入。
- 第二种方法我们通过ts文件导出去,做成数组导出去,在mian.ts全局引入,页面就不用引入了,只写名字就行了。