【Vue3+Vite+TS】7.0 组件五:通知菜单

必备UI组件

将用到的组件:

Badge 徽章
Popover 弹出框/气泡卡片
Tabs 标签页
Avatar 头像
Tag 标签
Scrollbar 滚动条

组件设计

新建src\components\baseline\notification\index.ts

import { App } from 'vue'
import Notification from './src/index.vue'

export { Notification }

//组件可通过use的形式使用
export default {
    Notification,
    install(app: App) {
        app.component('bs-notification', Notification)
    },
}

新建src\components\baseline\notification\src\index.vue


<template>
    <el-badge
        style="cursor: pointer"
        :value="value"
        :max="max"
        v-bind="$attrs"
        :is-dot="isDot"
    >
        <component :is="icon"></component>
    </el-badge>
</template>
<script lang="ts" setup>
const props = defineProps({
    //说明:图标
    icon: {
        type: String,
        default: 'el-icon-bell',
    },
    //说明:通知数量
    value: {
        type: [String, Number],
        default: 0,
    },
    color: {
        type: String,
        default: 'el-icon-bell',
    },
    //徽章最大值
    max: {
        type: Number,
    },
    //是否显示小圆点
    isDot: {
        type: Boolean,
        default: false,
    },
})
</script>
<style lang="scss" scoped></style>

新建src\views\baseline\notification\index.vue

<template>
    <div class="bs-wrapper">
        <bs-notification value="50"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" max="30"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" :is-dot="true"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" icon="el-icon-chat-round"></bs-notification>
    </div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.bs-wrapper {
    .flex {
        display: flex;
    }
    div {
        margin-right: 0.1rem;
    }
}
</style>

修改src\router\index.ts

/*
 * @Author: bobokaka
 * @Date: 2021-12-19 11:26:38
 * @LastEditTime: 2021-12-24 23:34:35
 * @LastEditors: Please set LastEditors
 * @Description: 路由
 * @FilePath: \vue3-element-ui-baseline\src\router\index.ts
 */
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

import Home from '../views/Home/index.vue'
import Container from '../components/baseline/container/src/index.vue'

const routes: RouteRecordRaw[] = [
    {
        path: '/',
        component: Container,
        children: [
            {
                path: '/',
                component: Home,
            },
            {
                path: '/chooseIcon',
                component: () => import('../views/baseline/chooseIcon/index.vue'),
            },
            {
                path: '/chooseArea',
                component: () => import('../views/baseline/chooseArea/index.vue'),
            },
            {
                path: '/trend',
                component: () => import('../views/baseline/trend/index.vue'),
            },
            {
                path: '/notification',
                component: () => import('../views/baseline/notification/index.vue'),
            },
        ],
    },
]

const router = createRouter({
    routes,
    history: createWebHistory(),
})
export default router

打开网页http://localhost:8080/notification

image.png

实现点击打开一个列表组件

修改src\views\baseline\notification\index.vue

<template>
    <div class="bs-wrapper">
        <!-- <bs-notification value="50"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" max="30"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" :is-dot="true"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" icon="el-icon-chat-round"></bs-notification> -->
        <bs-notification value="50"></bs-notification>
    </div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.bs-wrapper {
    .flex {
        display: flex;
    }
    div {
        margin-right: 0.1rem;
    }
}
</style>

修改src\components\baseline\notification\index.ts

<template>
    <el-popover
        placement="bottom"
        title="Title"
        :width="200"
        trigger="click"
        content="this is content, this is content, this is content"
    >
        <template #reference>
            <el-badge
                style="cursor: pointer"
                :value="value"
                :max="max"
                v-bind="$attrs"
                :is-dot="isDot"
            >
                <component :is="icon"></component>
            </el-badge>
        </template>
    </el-popover>
</template>
<script lang="ts" setup>
const props = defineProps({
    //说明:图标
    icon: {
        type: String,
        default: 'el-icon-bell',
    },
    //说明:通知数量
    value: {
        type: [String, Number],
        default: 0,
    },
    color: {
        type: String,
        default: 'el-icon-bell',
    },
    //徽章最大值
    max: {
        type: Number,
    },
    //是否显示小圆点
    isDot: {
        type: Boolean,
        default: false,
    },
})
</script>
<style lang="scss" scoped></style>
image.png

从官网复制一个过来,点击图标的效果如上,这里我们不需要标题,删掉如下代码:

        title="Title"

整体修改后如下:

<template>
    <el-popover placement="bottom" :width="300" trigger="hover">
        <template #default>
            <slot></slot>
        </template>
        <template #reference>
            <el-badge
                style="cursor: pointer"
                :value="value"
                :max="max"
                v-bind="$attrs"
                :is-dot="isDot"
            >
                <component :is="icon"></component>
            </el-badge>
        </template>
    </el-popover>
</template>

修改src\views\baseline\notification\index.vue

<template>
    <div class="bs-wrapper">
        <!-- <bs-notification value="50"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" max="30"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" :is-dot="true"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" icon="el-icon-chat-round"></bs-notification> -->
        <bs-notification value="50">
            <template #default>这是一个标题</template>
        </bs-notification>
    </div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.bs-wrapper {
    .flex {
        display: flex;
    }
    div {
        margin-right: 0.1rem;
    }
}
</style>
image.png

菜单组件封装

新建src\components\baseline\list\src\index.vue

<template>List</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>

新建src\components\baseline\list\index.ts

import { App } from 'vue'
import List from './src/index.vue'

export { List }

//组件可通过use的形式使用
export default {
  List,
    install(app: App) {
        app.component('bs-list', List)
    },
}

修改src\views\baseline\notification\index.vue

import { App } from 'vue'
import ChooseArea from './chooseArea'
import ChooseIcon from './chooseIcon'
import Container from './container'
import Trend from './trend'
import Notification from './notification'
import List from './list'
const components = [
    ChooseArea,
    ChooseIcon,
    Container,
    Trend,
    Notification,
    List,
]
export { ChooseArea, ChooseIcon, Container, Trend, Notification, List }

//组件可通过use的形式使用
export default {
    install(app: App) {
        components.map(item => {
            app.use(item)
        })
    },
    ChooseArea,
    ChooseIcon,
    Container,
    Trend,
    Notification,
    List,
}

修改src\components\baseline\notification\src\index.vue

<template>
    <div class="bs-wrapper">
        <!-- <bs-notification value="50"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" max="30"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" :is-dot="true"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" icon="el-icon-chat-round"></bs-notification> -->
        <bs-notification value="50">
            <template #default><bs-list></bs-list></template>
        </bs-notification>
    </div>
</template>
......

运行效果如下:


image.png

列表组件

这里需要构建一个即将出场的列表组件。
新建src\components\baseline\list\src\index.vue

<template>List</template>
<script lang="ts" setup>
import { PropType } from 'vue'
import { ActionOptions, listOptions } from './type'
const props = defineProps({
    list: {
        type: Array as PropType<listOptions[]>,
        required: true,
    },
    //操作的内容
    actions: {
        type: Array as PropType<ActionOptions[]>,
        default: [],
    },
})
</script>
<style lang="scss" scoped></style>

新建src\components\baseline\list\src\type.ts

export interface ListItem {
    //头像
    avatar?: string
    //标题
    title?: string
    //描述
    desc: string
    //时间
    time?: string
    //标签内容
    tag?: string
    tagType?: 'success' | 'info' | 'warning' | 'danger'
}
/**
 * 列表
 */
export interface listOptions {
    title: string
    content: ListItem[]
}
export interface ActionOptions {
    text: string
    icon?: string
}

新建src\components\baseline\list\index.ts

import { App } from 'vue'
import List from './src/index.vue'

export { List }

//组件可通过use的形式使用
export default {
  List,
    install(app: App) {
        app.component('bs-list', List)
    },
}

初始化,完毕,开始使用改造:
准备数据,新建src\views\baseline\notification\data.ts

/*
 * @Author: your name
 * @Date: 2021-12-28 18:45:30
 * @LastEditTime: 2021-12-29 01:03:45
 * @LastEditors: Please set LastEditors
 * @Description: 模拟数据
 * @FilePath: \vue3-element-ui-baseline\src\views\baseline\notification\data.ts
 */
export const list = [
    {
        title: '通知',
        content: [
            {
                title: '鲁迅回复了你的邮件',
                time: '2021-12-24 17:47:54',
                avatar: 'https://upload-images.jianshu.io/upload_images/16102290-ce12da7b12204094.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
            },
            {
                title: '刘备邀请你参加会议',
                time: '2021-12-28 9:15:27',
                avatar: 'https://www.baidu.com',
            },
            {
                title: '诸葛孔明已批准了你的休假申请',
                time: '2021-12-27 16:47:33',
                avatar: 'https://www.baidu.com',
            },
        ],
    },
    {
        title: '关注',
        content: [
            {
                title: '鲁迅 评论了你',
                desc: '愿中国青年都摆脱冷气,只是向上走,不必听自暴自弃者的话。',
                time: '2021-12-24 17:47:54',
                avatar: 'https://www.baidu.com',
            },
            {
                title: '刘备 评论了你',
                desc: '惟贤惟德,能服于人!',
                time: '2021-12-28 9:15:27',
                avatar: 'https://www.baidu.com',
            },
            {
                title: '诸葛孔明 评论了你',
                desc: '恢弘志士之气,不宜妄自菲薄。',
                time: '2021-12-27 16:47:33',
                avatar: 'https://www.baidu.com',
            },
        ],
    },
    {
        title: '代办',
        content: [
            {
                title: '鲁迅发表文章,待审核',
                desc: '需要在2021-12-30 18:00:00前审核',
                avatar: 'https://www.baidu.com',
                tag: '未开始',
                tagType: '',
            },
            {
                title: '刘备出兵计划发起',
                desc: '刘备提交于2021-12-27 16:04:00 需要在2021-12-30 18:00:00前审核',
                time: '2021-12-28 9:15:27',
                avatar: 'https://www.baidu.com',
                tag: '即将过期',
                tagType: 'danger',
            },
            {
                title: '诸葛孔明科目二考试',
                desc: '需要在2021-12-29 18:00:00前审核',
                time: '2021-12-27 16:47:33',
                avatar: 'https://www.baidu.com',
                tag: '已过期',
                tagType: 'warning',
            },
            {
                title: '鲁迅发表文章,待审核',
                desc: '需要在2021-12-30 18:00:00前审核',
                avatar: 'https://www.baidu.com',
                tag: '未开始',
                tagType: '',
            },
            {
                title: '刘备出兵计划发起',
                desc: '刘备提交于2021-12-27 16:04:00 需要在2021-12-30 18:00:00前审核',
                time: '2021-12-28 9:15:27',
                avatar: 'https://www.baidu.com',
                tag: '即将过期',
                tagType: 'danger',
            },
            {
                title: '诸葛孔明科目二考试',
                desc: '需要在2021-12-29 18:00:00前审核',
                time: '2021-12-27 16:47:33',
                avatar: 'https://www.baidu.com',
                tag: '已过期',
                tagType: 'warning',
            },
        ],
    },
]
export const actions = [
    {
        text: '清空代办',
        icon: 'el-icon-delete',
    },
    {
        text: '查看更多',
        icon: 'el-icon-edit',
    },
]

修改src\views\baseline\notification\index.vue

<template>
    <div class="bs-wrapper">
        <!-- <bs-notification value="50"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" max="30"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" :is-dot="true"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" icon="el-icon-chat-round"></bs-notification> -->
        <bs-notification value="50">
            <template #default>
                <bs-list :list="list" :actions="actions"></bs-list>
            </template>
        </bs-notification>
    </div>
</template>
<script lang="ts" setup>
import { list, actions } from './data'
</script>
<style lang="scss" scoped>
.bs-wrapper {
    .flex {
        display: flex;
    }
    div {
        margin-right: 0.1rem;
    }
}
</style>

修改src\components\baseline\list\src\index.vue

<!--
 * @Author: your name
 * @Date: 2021-12-23 00:07:25
 * @LastEditTime: 2021-12-29 01:50:17
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \vue3-element-ui-baseline\src\components\baseline\trend\src\index.vue
-->
<template>
    <div class="bs-wrapper">
        <el-tabs class="tabs">
            <el-tab-pane
                v-for="(item, index) in list"
                v-model="activeName"
                :key="index"
                :label="item.title"
                :name="index + ''"
            >
                <div class="list">
                    <el-scrollbar max-height="3rem">
                        <!-- 待办信息 -->
                        <div
                            class="list__box"
                            v-for="(item2, index2) in item.content"
                            :key="index2"
                        >
                            <!-- 头像 -->
                            <div class="list__box__avatar">
                                <el-avatar
                                    size="small"
                                    :src="item2.avatar"
                                ></el-avatar>
                            </div>
                            <div class="list__box__content">
                                <div
                                    v-if="item2.title"
                                    class="list__box__content__title"
                                >
                                    <!-- 主题和报警 -->
                                    <div class="title">{{ item2.title }}</div>
                                    <el-tag
                                        class="tag"
                                        size="mini"
                                        v-if="item2.tag"
                                        :type="item2.tagType"
                                    >
                                        {{ item2.tag }}
                                    </el-tag>
                                </div>
                                <!-- 说明 -->
                                <div
                                    v-if="item2.desc"
                                    class="list__box__content__desc"
                                >
                                    {{ item2.desc }}
                                </div>
                                <!-- 时间 -->
                                <div
                                    v-if="item2.time"
                                    class="list__box__content__time"
                                >
                                    {{ item2.time }}
                                </div>
                            </div>
                        </div>
                    </el-scrollbar>
                </div>

                <div class="actions">
                    <div
                        class="actions__content"
                        :class="{ border: actionIndex + 1 !== actions.length }"
                        v-for="(actionItem, actionIndex) in actions"
                        :key="index"
                    >
                        <div
                            v-if="actionItem.icon"
                            class="actions__content__icon"
                        >
                            <component :is="actionItem.icon"></component>
                        </div>
                        <div class="actions__content__text">
                            {{ actionItem.text }}
                        </div>
                    </div>
                </div>
            </el-tab-pane>
        </el-tabs>
    </div>
</template>
<script lang="ts" setup>
import { ref, PropType } from 'vue'
import { ActionOptions, listOptions } from './type'
const props = defineProps({
    list: {
        type: Array as PropType<listOptions[]>,
        required: true,
    },
    //操作的内容
    actions: {
        type: Array as PropType<ActionOptions[]>,
        default: [],
    },
})
const activeName = ref('0')
// console.log('props.list', props.list)
// console.log('props.actions', props.actions)
</script>
<style lang="scss" scoped>
.bs-wrapper {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}
.tabs {
    //让tabs值占满格分布并横向摆放
    ::v-deep(.el-tabs__nav) {
        width: 100%;
        display: flex;
    }
    ::v-deep(.el-tabs__item) {
        flex: 1;
        text-align: center;
    }
    .list {
        padding-bottom: 0.04rem;
        &__box {
            display: flex;
            align-items: center;
            padding: 0.12rem 0.2rem;
            cursor: pointer; //鼠标悬浮变小手
            &:hover {
                background-color: #e6f6ff;
            }
            &__avatar {
                flex: 1;
            }
            &__content {
                flex: 3;
                &__title {
                    display: flex;
                    align-items: center; //垂直方向居中
                    justify-content: space-between; //水平方向两边排列
                    .title {
                    }
                    .tag {
                    }
                }
                &__desc,
                &__time {
                    font-size: 0.12rem;
                    color: #999;
                    margin-top: 0.04rem;
                }
            }
        }
    }

    .actions {
        height: 0.5rem;
        display: flex;
        align-items: center;
        &__content {
            height: 0.5rem;
            cursor: pointer; //鼠标悬浮变小手
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center; //水平方向两边排列
            border-top: 2px solid #eee;

            // &:hover {
            //     background-color: #e6f6ff;
            // }
            &__icon {
                margin-right: 0.08rem;
                position: relative;
                top: 0.02rem;
            }
            &__text {
            }
        }
    }
}
.border {
    border-right: 2px solid #eee;
}
</style>

修改src\style\ui.scss

//修改组件库内部的样式
//1.需要自定义一个类名空间
//2.浏览器中调试样式
//3.调试好的类名放在这个类名中
//4.在App.vue里面引入这个文件
//5.在组件内需要改样式的元素的父元素加上这个类名
.bk--choose-icon-dialog-body-height {
    .el-dialog__body {
        height: 5rem;
        overflow-y: scroll;
        overflow-x: auto;
    }
}
//去掉el-tabs盒子默认的padding
.el-popper {
    padding: 0 !important;
}

效果如下:

image.png

image.png

list组件完善

修改src\components\baseline\list\src\index.vue

<!--
 * @Author: your name
 * @Date: 2021-12-23 00:07:25
 * @LastEditTime: 2021-12-29 02:17:41
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \vue3-element-ui-baseline\src\components\baseline\trend\src\index.vue
-->
<template>
    <div class="bs-wrapper">
        <el-tabs class="tabs">
            <el-tab-pane
                v-for="(item, index) in list"
                v-model="activeName"
                :key="index"
                :label="item.title"
                :name="index + ''"
            >
                <div class="list">
                    <el-scrollbar max-height="3rem">
                        <!-- 待办信息 -->
                        <div
                            class="list__box"
                            v-for="(item2, index2) in item.content"
                            :key="index2"
                            @click="handleChickList(item2, index2)"
                        >
                            <!-- 头像 -->
                            <div class="list__box__avatar">
                                <el-avatar
                                    size="small"
                                    :src="item2.avatar"
                                ></el-avatar>
                            </div>
                            <div class="list__box__content">
                                <div
                                    v-if="item2.title"
                                    class="list__box__content__title"
                                >
                                    <!-- 主题和报警 -->
                                    <div class="title">{{ item2.title }}</div>
                                    <el-tag
                                        class="tag"
                                        size="mini"
                                        v-if="item2.tag"
                                        :type="item2.tagType"
                                    >
                                        {{ item2.tag }}
                                    </el-tag>
                                </div>
                                <!-- 说明 -->
                                <div
                                    v-if="item2.desc"
                                    class="list__box__content__desc"
                                >
                                    {{ item2.desc }}
                                </div>
                                <!-- 时间 -->
                                <div
                                    v-if="item2.time"
                                    class="list__box__content__time"
                                >
                                    {{ item2.time }}
                                </div>
                            </div>
                        </div>
                    </el-scrollbar>
                </div>

                <div class="actions">
                    <div
                        class="actions__content"
                        :class="{ border: actionIndex + 1 !== actions.length }"
                        v-for="(actionItem, actionIndex) in actions"
                        :key="index"
                        @click="handleChickActions(actionItem, actionIndex)"
                    >
                        <div
                            v-if="actionItem.icon"
                            class="actions__content__icon"
                        >
                            <component :is="actionItem.icon"></component>
                        </div>
                        <div class="actions__content__text">
                            {{ actionItem.text }}
                        </div>
                    </div>
                </div>
            </el-tab-pane>
        </el-tabs>
    </div>
</template>
<script lang="ts" setup>
import { ref, PropType } from 'vue'
import { ActionOptions, listOptions, ListItem } from './type'
const props = defineProps({
    list: {
        type: Array as PropType<listOptions[]>,
        required: true,
    },
    //操作的内容
    actions: {
        type: Array as PropType<ActionOptions[]>,
        default: [],
    },
})

const activeName = ref('0')
const emits = defineEmits(['chickList', 'chickActions'])
const handleChickList = (item: ListItem, index: number) => {
    emits('chickList', { item, index })
}
const handleChickActions = (item: ActionOptions, index: number) => {
    emits('chickActions', { item, index })
}

// console.log('props.list', props.list)
// console.log('props.actions', props.actions)
</script>
<style lang="scss" scoped>
.bs-wrapper {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}
.tabs {
    //让tabs值占满格分布并横向摆放
    ::v-deep(.el-tabs__nav) {
        width: 100%;
        display: flex;
    }
    ::v-deep(.el-tabs__item) {
        flex: 1;
        text-align: center;
    }
    .list {
        padding-bottom: 0.04rem;
        &__box {
            display: flex;
            align-items: center;
            padding: 0.12rem 0.2rem;
            cursor: pointer; //鼠标悬浮变小手
            &:hover {
                background-color: #e6f6ff;
            }
            &__avatar {
                flex: 1;
            }
            &__content {
                flex: 3;
                &__title {
                    display: flex;
                    align-items: center; //垂直方向居中
                    justify-content: space-between; //水平方向两边排列
                    .title {
                    }
                    .tag {
                    }
                }
                &__desc,
                &__time {
                    font-size: 0.12rem;
                    color: #999;
                    margin-top: 0.04rem;
                }
            }
        }
    }

    .actions {
        height: 0.5rem;
        display: flex;
        align-items: center;
        &__content {
            height: 0.5rem;
            cursor: pointer; //鼠标悬浮变小手
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center; //水平方向两边排列
            border-top: 2px solid #eee;

            // &:hover {
            //     background-color: #e6f6ff;
            // }
            &__icon {
                margin-right: 0.08rem;
                position: relative;
                top: 0.02rem;
            }
            &__text {
            }
        }
    }
}
.border {
    border-right: 2px solid #eee;
}
</style>

修改src\views\baseline\notification\index.vue

<!--
 * @Author: your name
 * @Date: 2021-12-23 00:07:25
 * @LastEditTime: 2021-12-29 02:16:52
 * @LastEditors: Please set LastEditors
 * @Description:组件五:通知菜单
 * @FilePath: \vue3-element-ui-baseline\src\components\baseline\trend\src\index.vue
-->
<template>
    <div class="bs-wrapper">
        <!-- <bs-notification value="50"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" max="30"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" :is-dot="true"></bs-notification>
        <br />
        <br />
        <bs-notification value="50" icon="el-icon-chat-round"></bs-notification> -->
        <bs-notification value="50">
            <template #default>
                <bs-list
                    :list="list"
                    :actions="actions"
                    @chickList="handleChickList"
                    @chickActions="handleChickActions"
                ></bs-list>
            </template>
        </bs-notification>
    </div>
</template>
<script lang="ts" setup>
import { list, actions } from './data'
const handleChickList = (val: any) => {
    console.log('handleChickList:', val)
}
const handleChickActions = (val: any) => {
    console.log('handleChickActions:', val)
}
</script>
<style lang="scss" scoped>
.bs-wrapper {
    .flex {
        display: flex;
    }
    div {
        margin-right: 0.1rem;
    }
}
</style>

这样就实现了点击响应.

如上代码为了兼容别名使用,修改vite.config.ts
增加如下代码:

    resolve: {
        alias: {
            '@': '/src',
            '@style': '/src/style',
            '@com': '/src/components',
            '@baseline': '/src/components/baseline',
            '@business': '/src/components/business',
        },
    },

完整代码如下:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [vue()],
    resolve: {
        alias: {
            '@': '/src',
            '@style': '/src/style',
            '@com': '/src/components',
            '@baseline': '/src/components/baseline',
            '@business': '/src/components/business',
        },
    },
    server: {
        port: 8080,
    },
})

修改tsconfig.json
增加如下代码:

     "types": ["vite/client"],
        // ++ 这里加上baseUrl 和 path即可 ++
        "baseUrl": "./",
        "paths": {
            // 根据别名配置相关路径
            "@/*": ["./src/*"],
            "@style/*": ["./src/style/*"],
            "@com/*": ["./src/components/*"],
            "@baseline/*": ["./src/components/baseline/*"],
            "@business/*": ["./src/components/business/*"]
        }

完整代码如下:

{
    "compilerOptions": {
        "target": "esnext",
        "useDefineForClassFields": true,
        "module": "esnext",
        "moduleResolution": "node",
        "strict": true,
        "jsx": "preserve",
        "sourceMap": true,
        "resolveJsonModule": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "importHelpers": true,
        "isolatedModules": true,
        "lib": ["esnext", "dom"],
        "types": ["vite/client"],
        // ++ 这里加上baseUrl 和 path即可 ++
        "baseUrl": "./",
        "paths": {
            // 根据别名配置相关路径
            "@/*": ["./src/*"],
            "@style/*": ["./src/style/*"],
            "@com/*": ["./src/components/*"],
            "@baseline/*": ["./src/components/baseline/*"],
            "@business/*": ["./src/components/business/*"]
        }
    },
    "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

结果如下:


image.png

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):