首页 > 其他分享 >Vue3组件库搭建及测试

Vue3组件库搭建及测试

时间:2024-03-01 15:34:36浏览次数:32  
标签:src vue default Vue3 ts 按钮 组件 import 搭建

一、 搭建Vite环境

1.创建目录&初始化包配置&安装Vite依赖

mkdir gresgying-ui
cd gresgying-ui
npm init
npm i vite -D

2.根目录创建index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gresgying UI</title>
</head>
<body>
  Hello Gresgying UI!
</body>
</html>

3.运行Vite

npx vite

结果如图:

浏览器查看网址,结果如图,可以正常显示,说明Vite已正确配置:

4.测试 TS:

创建文件 src/index.ts

const str: String = 'Hello Gresgying UI';
console.log(str)

在 index.html 的body标签中引入

<script src="./src/index.ts"></script>

保存后刷新浏览器,可以在控制台中看到如图显示,说明 TS 可以正常使用:

5.在根目录的 package.json 中添加启动命令

"scripts": {
	"dev": "vite"
},

运行命令 npm run dev 结果如图所示:

Vite环境搭建完成

二、开发一个组件

1.基础组件

  • 安装Vue
npm i vue
  • 实现一个简单的 Button,创建 src/button/index.ts 因为 vue 默认不支持模板编译功能,所以使用 Render 函数的写法
import { defineComponent, h } from 'vue';

export default defineComponent({
    name: 'GButton',
    render() {
        return h("button", null, "MyButton");
    }
})
  • 在index.html中增加根容器,展示组件
<div id="app"></div>
  • 在 src/index.ts 中创建 Vue 实例并使用组件
import { createApp } from 'vue'
import GButton from './button'

createApp(GButton).mount('#app')
  • 启动项目后,浏览器没有显示按钮,而且控制台报错

Uncaught SyntaxError: Cannot use import statement outside a module (at index.ts:1:1)

因为 src/index.ts中使用了 es6 的语法,所以在 index.html 中引入时需要指定为模块导入:

<script src="./src/index.ts" type="module"></script>
  • 修改后按钮显示了,但是在浏览器控制台会有以下告警

Feature flags VUE_OPTIONS_API, VUE_PROD_DEVTOOLS, VUE_PROD_HYDRATION_MISMATCH_DETAILS are not explicitly defined. You are running the esm-bundler build of Vue, which expects these compile-time feature flags to be globally injected via the bundler config in order to get better tree-shaking in the production bundle.

官方说明:当以带有构建步骤的方式使用 Vue 时,可以配置一些编译时标志以启用/禁用特定的功能。使用编译时标志的好处是,以这种方式禁用的功能可以通过 tree-shaking 从最终的打包结果中移除。即使没有显式地配置这些标志,Vue 也会正常工作。然而,建议始终对它们进行配置,以便在可能的情况下正确地删除相关功能。

解决办法:安装插件 npm i @vitejs/plugin-vue -D

根目录新建 vite.config.ts

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

export default defineConfig({
    plugins: [
        vue(), // VUE插件
    ],
})

启动项目时会出现如下提示

The CJS build of Vite's Node API is deprecated. See https://vitejs.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.

在 package.json 中增加 "type": "module"

运行项目,可以看到按钮,启动时和浏览器控制台就都没有警告了。

2.单文件组件

  • Vue3.0 默认不支持模板编译,Vite默认只支持 TS 文件编译,Vue的模板需要再编译阶段转为TS代码(渲染函数)才能运行。 所以需要安装上面解决问题是安装的 Vite 的 Vue 组件,该组件不仅提供了模板编译,还支持单文件组件编译。如果没有安装 @vitejs/plugin-vue 组件,先按照上面的步骤安装并使用该组件。

  • 实现单文件组件 src/SFCButton.vue

import { createApp } from 'vue'
// import GButton from './button'
import SFCButton from "./SFCButton.vue";
createApp(SFCButton).mount('#app')
  • 此时代码静态检查会出现告警:TS2307: Cannot find module  ./SFCButton.vue  or its corresponding type declarations. 这是因为 ts 默认不支持 vue类型的模块

  • 需要增加声明文件 src/shims-vue.d.ts

declare module "*.vue" {
    import { DefineComponent } from "vue";
    const component: DefineComponent<{}, {}, any>;
    export default component;
}
  • 根目录下增加 tsconfig.json 配置文件
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": false,
    "jsx": "preserve",
    "moduleResolution": "node"
  }
}
  • 运行 npm run dev 就可以看到如图结果:

3.JSX 组件

  • 安装支持jsx的插件
npm i @vitejs/plugin-vue-jsx -D
  • 修改 vite.config.ts 配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
    plugins: [
        vue(), // VUE 插件
        vueJsx() // JSX 插件
    ],
})
  • 创建 JSX 组件 src/JSXButton.tsx
import { defineComponent, h } from 'vue'

export default defineComponent({
    name: "JSXButton",
    render(){
        return <button>JSXButton</button>
    }
})
  • 在 src/index.ts 中使用
import { createApp } from 'vue'
// import GButton from './button'
// import SFCButton from "./SFCButton.vue";
import JSXButton from "./JSXButton";
createApp(JSXButton).mount('#app')
  • 运行后如图显示:

4.封装库文件

  • 组件库需要支持两种导入方式

    • 完整引入:一次性引入全部组件,通过 Vue.use 以 Vue 插件的方式引入

    • 按需引入:导入单个组件,使用Vue.component 注册

  • 创建入口文件 src/entry.ts

    • 导出全部组件

    • 实现一个 Vue 插件,插件中实现 install 方法,将所有组件安装到 Vue 实例

import { App } from "vue";
import GButton from "./button";
import SFCButton from "./SFCButton.vue";
import JSXButton from "./JSXButton";

// 导出单独组件
export { GButton, SFCButton, JSXButton }

// 实现 install 方法
export default {
    install(app: App) : void {
        app.component(GButton.name, GButton)
        app.component(SFCButton.name, SFCButton)
        app.component(JSXButton.name, JSXButton)
    }
}
  • 修改 vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

const rollupOptions = {
    external: ["vue", "vue-router"],
    output:{
        globals: {
            vue: "Vue"
        }
    }
}

export default defineConfig({
    plugins: [
        vue(), // VUE 插件
        vueJsx() // JSX 插件
    ],
    build: {
        rollupOptions,
		// 可以指定压缩工具terser, 需要安装后使用 npm i terser -D
        minify: false,
		// 是否生成 sourcemap 文件,方便debug
		sourcemap: true,
		// css 代码分割
		cssCodeSplit: true,
        lib: {
            entry: "./src/entry.ts",
            name: "GresgyingUI",
            fileName: "gresgying-ui",
			// 输出常用的三种模块类型
            formats: ["esm", "umd", "iife"]
        }
    }
})
  • 在 package.json 增加 build 命令打包
"scripts": {
    "dev": "vite",
    "build": "vite build"
},
  • 运行 npm run build 结果如图所示

根目录 dist 目录下也生成了对应的文件

  • 验证全量导入
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>全量加载组件</title>
</head>
<body>
    <div id="app"></div>
    <script type="module">
        import { createApp } from "vue/dist/vue.esm-bundler.js"
        import GresgyingUI from "../../dist/gresgying-ui.js"
		import "uno.css"

        createApp({
            template: `
            <GButton/>
            <SFCButton/>
            <JSXButton/>
            `
        }).use(GresgyingUI).mount("#app")
    </script>
</body>
</html>

运行后访问,如图所示:

  • 验证按需导入
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>按需加载组件</title>
</head>
<body>
    <div id="app"></div>
    <script type="module">
        import { createApp } from "vue/dist/vue.esm-bundler.js"
        import { GButton, SFCButton, JSXButton } from "../../dist/gresgying-ui.js"
		import "uno.css"

        createApp({
            template: `
            <GButton/>
            <SFCButton/>
            <JSXButton/>
            `
        }).component(GButton.name, GButton)
            .component(SFCButton.name, SFCButton)
            .component(JSXButton.name, JSXButton)
            .mount("#app")
    </script>
</body>
</html>

运行后访问,如图所示:

三、使用 UnoCSS 原子化 CSS

1.引入Unocss

  • 安装依赖
npm i unocss -D
# 字体图标库
npm i @iconify-json/ic -D
  • vite中增加 Unocss 插件配置
import Unocss from "unocss/vite"
import { presetUno, presetAttributify, presetIcons } from "unocss"

export default defineConfig({
    plugins: [
        ...
        Unocss({
            presets: [presetUno(), presetAttributify(), presetIcons()]
        })
    ]})
  • 运行时,提示[unocss] Entry module not found. Did you add import 'uno.css' in your main entry?

修改 src/index.ts 文件,增加

import 'uno.css'
  • 在 Button 组件中使用 Unocss, 将 src/button/index.ts 重命名为 src/button/index.tsx, 并修改内容为:
import { defineComponent, PropType, toRefs } from 'vue';
import 'uno.css'

export default defineComponent({
    name: 'GButton',
    setup(props, { slots }) {
        return () => <button
            class = {`
            py-2
            px-4
            font-semibold
            rounded-lg
            shadow-md
            text-white
            bg-green-500
            hover:bg-green-700
            border-none
            cursor-pointer
        `}>
        {slots.default ? slots.default(): ''}
        </button>
    }
})
  • 在 src/index.ts 中引用测试
import { createApp } from 'vue'
import GresgyingUI from './entry'
createApp({
    template: '<GButton>普通按钮</GButton>'
}).use(GresgyingUI).mount('#app')

运行后打开,没有显示按钮,且浏览器控制台显示告警:Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".

因为组件中包含了template 模版,Vue默认使用的是运行时版本,不能处理 template 是字符串的情况,需要使用包含运行时编译器的 vue 版本,修改 vite.config.ts

export default defineConfig({
    resolve: {
        alias: {
            vue: 'vue/dist/vue.esm-bundler.js'
        }
    },
    ...
})

结果如图所示:

2.组件使用属性定制样式

  • 定义属性类型&注册组件属性 src/button/index.tsx
import { defineComponent, PropType, toRefs } from 'vue';
import 'uno.css'

export type GColor = 'black' | 'gray' | 'red' | 'yellow' | 'green' | 'blue' | 'indigo' | 'purple' | 'pink'

export const props = {
    color: {
        type: String as PropType<GColor>,
        default: 'blue'
    }
}
export default defineComponent({
    name: 'GButton',
    props,
    setup(props, { slots }) {
        return () => <button
            class = {`
            py-2
            px-4
            font-semibold
            rounded-lg
            shadow-md
            text-white
            bg-${props.color}-500
            hover:bg-${props.color}-700
            border-none
            cursor-pointer
        `}>
        {slots.default ? slots.default(): ''}
        </button>
    }
})
  • 修改 src/index.ts 测试
import { createApp } from 'vue'
import GresgyingUI from './entry'
createApp({
    template: `
    <GButton color="blue">蓝色按钮</GButton>
    <GButton color="green">绿色按钮</GButton>
    <GButton color="gray">灰色按钮</GButton>
    <GButton color="yellow">黄色按钮</GButton>
    <GButton color="red">红色按钮</GButton>
    `
}).use(GresgyingUI).mount('#app')

可以看到并没有按照我们传入的颜色显示,是因为 UnoCSS 是按需生成的,只能生成代码中使用过的样式。

  • UnoCSS提供了安全列表选项,我们需要将样式中变量的取值添加到 Safelist中,新建 config/unocss.ts
import { presetUno, presetAttributify, presetIcons, defineConfig } from 'unocss'
import Unocss from "unocss/vite";

const colors = [
    "white",
    "black",
    "gray",
    "red",
    "yellow",
    "green",
    "blue",
    "indigo",
    "purple",
    "pink"
]

const safelist = [
    ...colors.map(v => `bg-${v}-500`),
    ...colors.map(v => `hover:bg-${v}-700`)
]

export default defineConfig({
   safelist,
   presets: [presetUno(), presetAttributify(), presetIcons()]
})
  • 在 vite.config.ts 中引入重构的 unocss 配置
export default defineConfig({
    ...
    plugins: [
        vue(), // VUE 插件
        vueJsx(), // JSX 插件
        UnoCSS({
            configFile: './config/unocss.ts'
        })
    ],
})

如图所示,可以正常显示我们传入的颜色

  • 如果运行时,提示[unocss] Entry module not found. Did you add import 'uno.css' in your main entry? 在 src/entry.ts中加入 import 'uno.css'

3.图标按钮组件

  • UnoCSS 中引入图标,只需要加载 @unocss/preset-icon 即可,它提供了大量的 iconify 图标,可以查看网址

Icônes

  • 这个在之前的实现中已经加载,现在只需要定制图标安全列表,修改 config/unocss.ts
const icons = [
    "search",
    "edit",
    "check",
    "message",
    "star-off",
    "delete",
    "add",
    "share"
]

const safelist = [
//新增
    ...icons.map(v => `i-ic-baseline-${v}`),
]
  • src/button/index.tsx 中注册icon属性, 并添加字体图标
export const props = {
    ...
    icon: {
        type: String,
        default: ''
    }
}
export default defineComponent({
    name: 'GButton',
    props,
    setup(props, { slots }) {
        return () => <button
            class = {`
            ...
        `}>
        {props.icon != "" ? <i class={`i-ic-baseline-${props.icon} p-3`}></i> : ""}
        {slots.default ? slots.default(): ''}
        </button>
    }
})
  • 修改测试文件 src/index.ts
import { createApp } from 'vue'
import GresgyingUI from './entry'

createApp({
    template: `
    <GButton color="blue" icon="search">蓝色按钮</GButton>
    <GButton color="green" icon="edit">绿色按钮</GButton>
    <GButton color="gray" icon="check">灰色按钮</GButton>
    <GButton color="yellow" icon="message">黄色按钮</GButton>
    <GButton color="red" icon="delete">红色按钮</GButton>
    `
}).use(GresgyingUI).mount('#app')

可以看到带图标的按钮:

四、Vitepress搭建文档网站

1.搭建文档网站

  • 安装依赖
npm i vitepress -D
  • 新建 vitepress 的 vite 配置 docs/vite.config.ts
import {defineConfig} from "vite"
import vueJsx from "@vitejs/plugin-vue-jsx";
import UnoCSS from "unocss/vite";

export default defineConfig({
    plugins: [
        vueJsx(),
        UnoCSS({
            configFile: './config/unocss.ts'
        })
    ],
    server:{
        port: 3000
    }
})
  • 创建文档首页 docs/index.md
## hello Vitepress

const str:String = "hello vitepress"

  • 增加文档启动脚本 package.json
"scripts": {
    ...
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs",
    "docs:serve": "vitepress serve docs"
},
  • 运行 npm run docs:dev

打开网址,效果如图:

2.引入组件并展示

  • 配置菜单 docs/.vitepress/config.ts
const sidebar = {
    '/': [
        {
            text: 'Guide',
            items: [
                { text: '快速开始', link: '/' },
                { text: '通用', link: '/components/button/' }
            ]
        }
    ]
}

const config = {
    themeConfig: {
        sidebar
    }
}

export default config
  • 引入组件 docs/.vitepress/theme/index.ts
import Theme from 'vitepress/dist/client/theme-default/index.js'
import GresgyingUI from '../../../src/entry'

export default {
    ...Theme,
    enhanceApp({ app }){
        app.use(GresgyingUI)
    }
}
  • 组件文档 docs/components/button/index.md
# Button 按钮
<div style="margin-bottom: 20px">
    <GButton color="blue">主要按钮</GButton>
    <GButton color="green">绿色按钮</GButton>
    <GButton color="gray">灰色按钮</GButton>
    <GButton color="yellow">黄色按钮</GButton>
    <GButton color="red">红色按钮</GButton>
</div>
  • 运行 npm run docs:dev ,结果如图所示:

3.引入组件代码

  • 修改菜单配置 docs/.vitepress/config.ts
const sidebar = {
    '/': [
        {
            text: 'Guide',
            items: [
                { text: '快速开始', link: '/' },
                { text: '通用', link: '/components/button/' }
            ]
        },
        {
            text: 'Components',
            items: [
                { text: '组件', link: '/components/' },
                { text: '按钮', link: '/components/button/' }
            ]
        }
    ]
}
  • 修改组件文档
# Button 按钮

常用操作按钮

## 基础用法

基础函数用法

<div style="margin-bottom: 20px">
    <GButton color="blue">主要按钮</GButton>
    <GButton color="green">绿色按钮</GButton>
    <GButton color="gray">灰色按钮</GButton>
    <GButton color="yellow">黄色按钮</GButton>
    <GButton color="red">红色按钮</GButton>
</div>

<div style="margin-bottom: 20px">
    <GButton color="blue" icon="search">搜索按钮</GButton>
    <GButton color="green" icon="edit">编辑按钮</GButton>
    <GButton color="gray" icon="check">成功按钮</GButton>
    <GButton color="yellow" icon="message">提示按钮</GButton>
    <GButton color="red" icon="delete">删除按钮</GButton>
</div>

<div style="margin-bottom: 20px">
    <GButton color="blue" icon="search"></GButton>
    <GButton color="green" icon="edit"></GButton>
    <GButton color="gray" icon="check"></GButton>
    <GButton color="yellow" icon="message"></GButton>
    <GButton color="red" icon="delete"></GButton>
</div>

::: details code
使用`size`、`color`、`pain`、`round`属性来定义 Button 样式。

```vue
<template>
  <div style="margin-bottom: 20px">
    <GButton color="blue">主要按钮</GButton>
    <GButton color="green">绿色按钮</GButton>
    <GButton color="gray">灰色按钮</GButton>
    <GButton color="yellow">黄色按钮</GButton>
    <GButton color="red">红色按钮</GButton>
  </div>

  <div style="margin-bottom: 20px">
    <GButton color="blue" icon="search">搜索按钮</GButton>
    <GButton color="green" icon="edit">编辑按钮</GButton>
    <GButton color="gray" icon="check">成功按钮</GButton>
    <GButton color="yellow" icon="message">提示按钮</GButton>
    <GButton color="red" icon="delete">删除按钮</GButton>
  </div>

  <div style="margin-bottom: 20px">
    <GButton color="blue" icon="search"></GButton>
    <GButton color="green" icon="edit"></GButton>
    <GButton color="gray" icon="check"></GButton>
    <GButton color="yellow" icon="message"></GButton>
    <GButton color="red" icon="delete"></GButton>
  </div>
</template>

:::

图标按钮

带图标的按钮可以增加辨识度或者不显示文字

搜索

::: details code

设置icon属性即可

<template>
    <div class="flex flex-row">
        <GButton icon="edit" plain></GButton>
        <GButton icon="delete" plain></GButton>
        <GButton icon="share" plain></GButton>
        <GButton icon="search" plain round>搜索</GButton>
    </div>
</template>

:::

API

Props

参数 说明 类型 默认值
color 按钮颜色, 可选值black gray red yellow green blue indigo purple pink String blue
icon 按钮图标 String -
  • 运行效果如图

五、Jest 单元测试

1.搭建 Jest 环境

  • 安装依赖 npm i jest -g

  • 根目录创建测试文件 add.js

const add = (a, b) => a + b;
module.exports = add;
  • Jest 测试函数 /src/tests/add.test.js
const add = require('../../add.js')
describe("测试 Add 函数", () => {
    test("add(1, 2) === 3", () => {
        expect(add(1, 2)).toBe(3)
    });
    test("add(1, 1) === 2", () => {
        expect(add(1, 1)).toBe(2)
    })
})

运行 jest,结果如图所示:

2.Mock数据测试无法执行的函数

  • 安装 axios npm i axios -D

  • 根目录创建测试文件 fetch.js

const axios = require('axios')
exports.getData = () => axios.get('/abc/bcd')
  • 测试文件 /src/tests/fetch.test.js
const { getData } = require('../../fetch.js')
const axios = require('axios')
jest.mock('axios')
it("fetch", async () => {
    axios.get.mockResolvedValueOnce('123')
    axios.get.mockResolvedValue('456')
    const data1 = await getData()
    const data2 = await getData()
    expect(data1).toBe('123')
    expect(data2).toBe('456')
})
  • 执行 jest, 结果如图

  • 使用 jest.fn() 创建 mock 函数, 在 /src/tests/fetch.test.js 中实现:
test('测试jest.fn()调用', () => {
    let mockFn = jest.fn()
    let result = mockFn(1, 2, 3)
    // 断言 mockFn 执行返回undefined
    expect(result).toBeUndefined()
    // 断言 mockFn 会被调用
    expect(mockFn).toBeCalled()
    // 断言 mockFn 会被调用一次
    expect(mockFn).toBeCalledTimes(1)
    // 断言 mockFn 传入的参数为1, 2, 3
    expect(mockFn).toHaveBeenCalledWith(1, 2, 3)
})
  • 结果如图:

3.测试前端页面

  • 安装 dom 仿真依赖 jsdom, npm i jsdom -D

  • 配置jsdom, 根目录下创建 jsdom-config.js

const jsdom = require('jsdom')
const { JSDOM } = jsdom

const dom = new JSDOM('<!DOCTYPE html><head/><body></body>',{
    url: 'http://localhost/',
    referrer: 'https://example.com/',
    contentType: 'text/html',
    userAgent: 'Mellblomenator/9000',
    includeNodeLocations: true,
    storageQuota: 10000000,
})
global.window = dom.window
global.document = window.document
global.navigator = window.navigator
  • 根目录下创建被测文件 dom.js
exports.generateDiv = () => {
    const div = document.createElement("div")
    div.className = 'cc'
    document.body.appendChild(div)
}
  • 编写测试文件 src/tests/dom.test.js
const { generateDiv } = require('../../dom.js')
require('../../jsdom-config.js')

describe('DOM 测试', () => {
    test('测试 dom 操作', () => {
        generateDiv()
        expect(document.getElementsByClassName('cc').length).toBe(1)
    })
});
  • 运行 jest 效果如图

六、Vitest 单元测试

1.搭建环境

  • 安装依赖
// 测试框架, 用于执行整个测试过程并提供断言库、mock、覆盖率
npm i vitest -D
// 用于提供在 node 环境中的 Dom 仿真模型
npm i happy-dom -D
// 测试工具库
npm i @vue/test-utils
  • vite 配置修改 vite.config.ts ,最上面需要增加声明
/// <reference types="vitest" />

export default defineConfig({
    ...
    test: {
        globals: true,
        environment: 'happy-dom',
        transformMode: {
            web: [/.[tj]sx$/],
        },
    }
})
  • 重构组件,将 src/button/index.tsx 重命名为 Button.tsx , 然后再 src/button/ 下新增入口文件 src/button/index.ts
import Button from './Button'
export default Button;

2.编写测试用例

  • 测试用例文件 src/button/__tests__Button.test.ts
import Button from "../Button";
import {shallowMount} from "@vue/test-utils";
import {describe, expect, test} from "vitest";

describe('Button', () => {
    test('mount @vue/test-utils', () => {
        const wrapper = shallowMount(Button, {
            slots: {
                default: 'Button'
            }
        })
        expect(wrapper.text()).toBe('Button')
    })
})
  • 修改运行脚本 package.json
"scripts": {
    ...
    "test": "vitest"
},
  • 启动测试 npm run test ,结果之前的测试用例跑不过了,需要修改一下

src/tests/add.test.js

import add from '../../add.js'
describe("测试 Add 函数", () => {
    test("add(1, 2) === 3", () => {
        expect(add(1, 2)).toBe(3)
    });
    test("add(1, 1) === 2", () => {
        expect(add(1, 1)).toBe(2)
    })
})

src/tests/dom.test.js

import { generateDiv } from '../../dom.js'
import '../../jsdom-config.js'

describe('DOM 测试', () => {
    test('测试 dom 操作', () => {
        generateDiv()
        expect(document.getElementsByClassName('cc').length).toBe(1)
    })
});

src/tests/fetch.test.js

vi.mock('axios');

test('测试jest.fn()调用', () => {
    let mockFn = vi.fn()
    let result = mockFn(1, 2, 3)
    // 断言 mockFn 执行返回undefined
    expect(result).toBeUndefined()
    // 断言 mockFn 会被调用
    expect(mockFn).toBeCalled()
    // 断言 mockFn 会被调用一次
    expect(mockFn).toBeCalledTimes(1)
    // 断言 mockFn 传入的参数为1, 2, 3
    expect(mockFn).toHaveBeenCalledWith(1, 2, 3)
})
  • 再次运行,结果如图所示,可以看到 Vitest 兼容了大部分 Jest 的用法。

  • 上面只是测试了按钮的默认状态,组件重要的是对于不同的 props 实现不同的样式,这里以 color 为例,在 src/button/tests/Button.test.ts 中继续增加测试用例
// 增加以下代码
describe('color', () => {
    test('default', () => {
        const wrapper = shallowMount(Button, {
            slots: {
                default: 'Button'
            }
        });
        expect(wrapper.classes().map(v => v.replace('\n', '')).includes('bg-blue-500')).toBe(true);
    })
    test('red', () => {
        const wrapper = shallowMount(Button, {
            slots: {
                default: 'Button'
            },
            props: {
                color: 'red'
            }
        })
        expect(wrapper.classes().map(v => v.replace('\n', '')).includes('bg-red-500')).toBe(true);
    })
})
  • 运行后结果如图

标签:src,vue,default,Vue3,ts,按钮,组件,import,搭建
From: https://www.cnblogs.com/caicai521/p/18047175

相关文章

  • 在K8S中,如何查看kubelet组件的日志?
    在Kubernetes(K8S)中,查看kubelet组件的日志可以通过几种不同的方法。以下是详细的步骤:使用journalctl命令:如果kubelet是通过systemd方式部署的,你可以使用journalctl命令来查看其日志。执行journalctl-ukubelet将显示kubelet的日志信息。如果需要查看实时更新的日志,可以添加-f......
  • Superset3 前后端搭建详解
    Superset3搭建目录Superset3搭建后端:方法1、在Windows本地搭建方法2:运维线上搭建前端:前端搭建Superset数据库其他Superset框架是一套包括前后端代码的框架,后端语言为Python,前端语言为React,superset启动后包括一个前端地址+端口,一个后端地址+端口的服务,后端这个服务是带......
  • 在K8S中,节点状态哪个组件负责上报的?
    在Kubernetes(K8s)中,节点状态是由kubelet组件负责定期上报的。kubelet是运行在每个节点上的代理程序,它与KubernetesMaster节点上的控制面组件紧密协作,以确保节点上的Pod能够正确运行。kubelet的主要职责之一就是与KubernetesAPI服务器保持通信,定期向API服务器报告节点的状态信息,......
  • 搭建一个大模型API服务
    搭建一个大模型API服务本文将介绍如何使用SWIFT框架搭建一个大模型API服务,以方便后续做RAG、Agent的开发工作。环境准备基础环境操作系统:Ubuntu18.04.5LTS(GNU/Linux3.10.0-1127.el7.x86_64x86_64)Anaconda3:Anaconda3-2023.03-1-Linux-x86_64根据服务器网络情况配置好......
  • vue3——环境变量的配置
    vue3环境变量的配置开发环境(development)测试环境(testing)生产环境(production)项目根目录分别添加开发、生产和测试环境的文件!.env.development.env.production.env.test文件内容变量必须以VITE_为前缀才能暴露给外部读取NODE_ENV='development'VITE_APP_TITLE=......
  • Vue 3.0 应用&组件实例
    #创建一个应用实例每个Vue应用都是通过用 createApp 函数创建一个新的应用实例开始的: constapp=Vue.createApp({/*选项*/})  该应用实例是用来在应用中注册“全局”组件的。我们将在后面的指南中详细讨论,简单的例子: constapp=Vue.createApp({})ap......
  • Linux 环境下搭建 ElasticSearch
    centos8环境下搭建ElasticSearch7.8一、安装:复制下载链接地址,并使用wget命令下载对应的压缩包。例如:wgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.8.0-linux-x86_64.tar.gz下载完成后,解压压缩包:tar-xzvfelasticsearch-7.8.0-linux-x86......
  • Vue UI组件库系列之概述
    概述UI组件库:提供了一些如输入框、布局、按钮等在网页UI布局中常用的元素,并将这些元素以组件的形式提供给我们。一般会说UI组件库是基于哪个框架【Vue/React/...】的、PC端/移动端什么项目适合用UI组件库,什么项目不适合?【UI组件库的应用场景】不适合【页面中包含很多定制化、......
  • Vue Router系列之(十)缓存路由组件
    缓存路由组件完善路由的技巧作用:让不展示的路由组件保持挂载,不被销毁。​ 正常情况下,进行了路由跳转后,之前的组件会被销毁,如果之前的组件中存在input框之类的表单类组件,输入的内容也就消失了,也就是说,要保证路由跳转后不销毁之前的组件具体编码://缓存的对象:并不是所有路......
  • Vue CLI 系列之(十一)组件自定义事件
    组件自定义事件区别于js内置事件,内置事件是给html元素用的,而自定义事件是给组件用的1.给组件实例对象绑定自定义事件给组件绑定自定义事件v-on:自定义事件名="回调函数"比如:<Studentv-on:atguigu="demo"/>上面代码的含义为:由于v-on是在Student这个组件标签上,所以是给stu......