感谢
感谢作者Kagol的无私分享,Vue DevUI即将发布1.0,欢迎大家关注,使用!
视频教程
上一次直播内容回顾
- 先是停下来,给上上次的tree组件(渲染嵌套的多层节点)增加单元测试
- 然后完善tree组件,实现展开/收起功能
- 并使用vue3的组合式API,对该功能进行重构,实现useToggle方法,将该功能从setup中抽离出来
最终实现的效果:
img
1 创建基础项目工程
yarn create vite vite-demo --template vue-ts
# or
# npm init vite@latest vite-demo -- --template vue-ts
$ yarn create vite vite-demo --template vue-ts
yarn create v1.22.10
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Installed "create-vite@2.6.6" with binaries:
- create-vite
- cva
Scaffolding project in /kagol/vite-demo...
Done. Now run:
cd vite-demo
yarn
yarn dev
✨ Done in 5.46s.
非常友好地提示了下一步要做什么
cd vite-demo
yarn
yarn dev
安装依赖
$ yarn
yarn install v1.22.10
warning package.json: No license field
info No lockfile found.
warning vite-demo@0.0.0: No license field
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile.
✨ Done in 7.33s.
本地启动
"dev": "vite",
$ yarn dev
yarn run v1.22.10
warning package.json: No license field
$ vite
Pre-bundling dependencies:
vue
(this will be run only when your dependencies or config have changed)
vite v2.6.5 dev server running at:
> Local: http://localhost:3000/
> Network: use `--host` to expose
ready in 402ms.
浏览器看效果
在浏览器地址栏输入以下链接查看效果:
img
构建生产包
"build": "vue-tsc --noEmit && vite build",
$ yarn build
yarn run v1.22.10
warning package.json: No license field
$ vue-tsc --noEmit && vite build
vite v2.6.5 building for production...
✓ 14 modules transformed.
dist/assets/logo.03d6d6da.png 6.69 KiB
dist/index.html 0.48 KiB
dist/assets/index.31b3d229.js 1.95 KiB / gzip: 1.03 KiB
dist/assets/index.459f8680.css 0.34 KiB / gzip: 0.24 KiB
dist/assets/vendor.2acfe60d.js 49.61 KiB / gzip: 19.93 KiB
✨ Done in 11.09s.
2 一些关键文件
使用tree
命令看下目录结构
$ tree -l 3
/kagol/vite-demo
├── README.md
├── index.html
├── package.json
├── public
| └── favicon.ico
├── src
| ├── App.vue
| ├── assets
| | └── logo.png
| ├── components
| | └── HelloWorld.vue
| ├── env.d.ts // vue-ts模板
| └── main.ts
├── tsconfig.json // vue-ts模板
└── vite.config.ts
directory: 4 file: 11
package.json
{
"name": "vite-demo",
"version": "0.0.0",
"scripts": {
"dev": "vite", // 本地启动
"build": "vue-tsc --noEmit && vite build", // 构建生产包,增加了vue-tsc类型检查 vue模板为 vite build
"serve": "vite preview" // 预览生产包效果
},
"dependencies": {
"vue": "^3.2.16"
},
"devDependencies": {
"@vitejs/plugin-vue": "^1.9.3", // 提供 Vue 3 单文件组件支持
"typescript": "^4.4.3", // vue-ts模板
"vite": "^2.6.4",
"vue-tsc": "^0.3.0" // volar的子包,vue3的ts类型检查工具(可选) vue-ts模板
}
}
一共有5个依赖
运行态依赖:vue 开发态依赖:
- vite
- @vitejs/plugin-vue 提供 Vue 3 单文件组件支持的vite插件
- typescript
- vue-tsc vue3的类型检查工具,可选
vite.config.ts
vite.config.ts/vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()]
})
tsconfig.json
{
// 编译选项 https://www.tslang.cn/docs/handbook/compiler-options.html
"compilerOptions": {
"target": "esnext", // 目标语言的版本
"useDefineForClassFields": true, // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier
"module": "esnext", // 指定生成代码的模块标准
"moduleResolution": "node", // 决定如何处理模块
"strict": true, // 启用所有严格类型检查选项
"jsx": "preserve", // 在.tsx文件里支持JSX https://www.tslang.cn/docs/handbook/jsx.html
"sourceMap": true, // 生成目标文件的sourceMap文件
"resolveJsonModule": true, // 为了import json文件方便
"esModuleInterop": true, // 为了import cjs文件方便 https://zhuanlan.zhihu.com/p/148081795
"lib": ["esnext", "dom"] // 编译过程中需要引入的库文件的列表
},
// 指定编译器需要编译的文件或文件夹
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
### env.d.ts
vue组件的类型声明,不添加该文件会提示
```plain
找不到模块“./App.vue”或其相应的类型声明。
3 添加 jsx 支持
希望能在项目中使用jsx编写的组件。
HelloWorld.tsx
export const HelloWorld = () => <div>Hello World jsx</div>
App.vue
import { HelloWorld } from './components/HelloWorld'
<HelloWorld />
报错:Uncaught ReferenceError: React is not defined
Uncaught ReferenceError: React is not defined
at HelloWorld (HelloWorld.tsx:1)
引入vite插件:@vitejs/plugin-vue-jsx
安装插件
yarn add -D @vitejs/plugin-vue-jsx
引入插件
vite.config.ts
import vueJsx from '@vitejs/plugin-vue-jsx'
plugins: [vue(), vueJsx()]
接上第一次直播的tree组件
tree.tsx
import { defineComponent, ExtractPropTypes, PropType } from 'vue'
interface TreeItem {
label: string
children?: TreeData
}
type TreeData = Array<TreeItem>
const treeProps = {
data: {
type: Array as PropType<TreeData>,
default: () => [],
}
}
type TreeProps = ExtractPropTypes<typeof treeProps>
export default defineComponent({
name: 'DTree',
props: treeProps,
setup(props: TreeProps) {
console.log('props:', props, props.data)
return () => {
return <div class="devui-tree">
{ props.data.map(item => <div>{ item.label }</div>) }
</div>
}
}
})
App.vue
import { ref } from 'vue'
import DTree from './components/tree'
const data = ref([{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}, ...])
<d-tree :data="data"></d-tree>