扩展补充
Vite 插件 script setup name
说明:一款能让 script setup 添加组件名 name 的插件。
- 安装插件
yarn add vite-plugin-vue-setup-extend -D
- 配置插件:
vite.config.ts
import { defineConfig, Plugin } from 'vite'
import vue from '@vitejs/plugin-vue'
+ import vueSetupExtend from 'vite-plugin-vue-setup-extend'
export default defineConfig({
plugins: [
vue(),
+ vueSetupExtend()
],
})
- 组件中使用
+ <script setup lang="ts" name="App">
+ //
+ </script>
-<script lang="ts">
-export default {
- name: "App"
-}
-<script/>
<template>
<div>Hello App Name </div>
</template>
项目打包、预览、部署
拓展阅读:Vite官方文档
项目打包
本节目标:知道打包命令做了哪些工作,了解本地预览。
打包构建
yarn build
vue-tsc安全检查。- 打包文件并进行代码压缩。
本地预览
yarn preview
项目部署
说明:为了体验部署流程,我们把项目部署到码云 GiteePages。
🚨注意:工作中一般由运营负责部署,部署到公司的服务器。
- 在
vite.config.ts中设置正确的base。
export default defineConfig({
+ base: "./", // 设置打包路径,部署到 GiteePages 需要相对于仓库路径
...
});
- 新建
deloy.sh部署脚本
#!/usr/bin/env sh
# 确保脚本抛出遇到的错误
set -e
# 生成静态文件
npm run build
# 进入生成的文件夹
cd dist
# 如果是发布到自定义域名
# echo 'www.example.com' > CNAME
git init
git add -A
git commit -m 'deploy'
# 如果发布到 https://<USERNAME>.github.io/<REPO>
# git push -f git@gitee.com:<USERNAME>/<REPO>.git master:gh-pages
git push -f git@gitee.com:Megasu/rabbit-vue3-ts.git master:gh-pages
cd -
- 运行
deploy.sh - 在码云部署
gh-pages分支。
知识点拓展补充
处理异步请求渲染 - Suspense
我们时常需要:判断异步请求的状态,然后,根据这些请求来展示不同的界面 => Suspense 非常方便
vue3 推出了一个新的内置组件 Suspense , Suspense 是一个特殊的组件。
说明:
- 它会有两个
template slot,刚开始会渲染feedback内容,直到达到某个条件以后,才会渲染正式的内容, - 也就是 default 的内容。这样呢,进行异步内容的渲染就会变得特别简单。
功能1:异步 setup (支持顶层 await)
新建:setup 顶层 await 组件: TopAwaitCom.vue
<script setup lang="ts">
import { http } from '@/utils/request';
// 🚨 顶层 await 以前是不能渲染出组件内容的,所有的数据相当于都被 Promise 包装过
const res = await http('GET', '/home/banner');
console.log(res.data.result);
</script>
<template>
<h1>我是顶层 await 组件</h1>
</template>
导入使用,但需要套上 Suspense 组件。
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
import TopAwaitCom from "./TopAwaitCom.vue";
</script>
<template>
+ <Suspense
<TopAwaitCom />
+ <template #fallback>
+ <h1>Loading...</h1>
+ </template>
+ </Suspense>
</template>
功能2:异步组件加载
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
// 直接加载组件
// import TestAsyncCom from "./TestCom.vue";
// 异步加载组件
const TestAsyncCom = () => import("./TestCom.vue");
</script>
<template>
<Suspense>
<template #default>
<TestAsyncCom />
</template>
<template #fallback>
<h1>Loading...</h1>
</template>
</Suspense>
</template>
Vue3 响应式原理
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h2>双向绑定</h2>
<input type="text" value="" />
<button>点击改名</button>
<script>
// 目标对象
const obj = reactive({ name: 'zs', age: 18 });
function reactive(obj) {
// 目标对象的代理
return new Proxy(obj, {
get(...args) {
// return obj[prop];
return Reflect.get(...args);
},
set(obj, prop, value) {
// obj[prop] = value;
Reflect.set(obj, prop, value);
document.querySelector('h2').innerHTML = JSON.stringify(obj);
input.value = value;
},
});
}
console.log(obj);
const input = document.querySelector('input');
input.addEventListener('input', (e) => {
obj.name = e.target.value;
});
const button = document.querySelector('button');
button.addEventListener('click', () => {
obj.name += '呀';
});
</script>
</body>
</html>
Reflect 对象
Reflect 对象是 ES6 为了操作对象而提供的新 API,Reflect 提供的静态方法让对象的操作更加规范统一。
TS 遍历对象
🔔 经验: 在 TS 项目中,对象遍历配合 Reflect 会更香,用 obj[key] 写法会 TS 项目报错。
| Reflect 调用 | 传统操作 | |
|---|---|---|
| 获取 | Reflect.get(obj, key) | obj[key] |
| 设置 | Reflect.set(obj, key, value) | obj[key] = value |
| 删除 | Reflect.deleteProperty(obj, key) | delete obj[key] |
| 判断是否存在 | Reflect.has(obj, key) | key in obj |
代码写法升级:src\store\modules\cart.ts
// 🐛 TS 遍历对象,通过 lastCartInfo[key] 获取和修改对象会报错: key 为 any
for (const key in lastCartInfo) {
// 获取 value
const value = Reflect.get(lastCartInfo, key);
}
Reflect 与 Proxy
Reflect 可配合 Proxy 使用,Vue3 的 reactive 函数的源码有应用。
JSX/TSX 基础-React基础
概述
TSX/JSX 语法糖(React 团队设计发明的,Vue 也进行了支持)
- 在
Vue3中其实就是createVNode的语法糖,负责创建虚拟DOM用的。底层依赖babel插件支持。 - 我们在 Test 组件中,演示
jsx/tsx语法。
没有 jsx/tsx 创建虚拟DOM
代码演示1:
<script setup lang="ts">
import { createVNode } from 'vue';
const VDOM = createVNode('h1', { id: 'box' }, 'hello');
</script>
<template>
<VDOM />
</template>
代码演示2:
<script setup lang="ts">
import { createVNode } from 'vue';
const VDOM = createVNode("div", { id: "box" }, [
createVNode("p", {}, "我是一个段落1"),
createVNode("p", {}, "我是一个段落2"),
]);
</script>
思考:渲染以下结构?
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
写起来很麻烦,有没有更简单的写法呢?
有 jsx/tsx 创建虚拟DOM
本节目标:setup 中可以书写响应式数据,用于绑定到
tsx/jsx结构中。
基础用法
<script setup lang="tsx">
const VDOM = () => <h1>Hello TSX in Setup</h1>;
</script>
<template>
<VDOM />
</template>
TSX 的进阶用法
本节目标:内容绑定,属性绑定,事件绑定,条件渲染,列表渲染。
<script setup lang="tsx">
import { ref } from "vue";
const count = ref(0);
const isHide = ref(true);
const add = () => {
count.value += 1;
};
const list = ref([
{ id: 1, content: "吃饭", done: true },
{ id: 2, content: "睡觉", done: false },
{ id: 3, content: "打代码", done: true },
]);
// script - 数据绑定在 JSX 用一对花括号
const VDOM = () => {
return (
<div>
<h1>Hello TSX in Setup</h1>
<p>{count.value}</p>
<button onClick={add}>点击+1</button>
<button
onClick={() => {
isHide.value = !isHide.value;
}}
>
切换显示隐藏
</button>
<h2>条件渲染</h2>
{isHide.value ? <div>loading</div> : <div>结构2</div>}
<h2>列表渲染</h2>
<ul>
{list.value.map((item) => (
<li key={item.id}>{item.content}</li>
))}
</ul>
</div>
);
};
</script>
<template>
<VDOM />
</template>
函数式组件
Vue3 也支持函数式组件,可通过 .tsx/.jsx 后缀名文件创建组件,写法非常类似 React 的函数式组件语法。
现在 JSX/TSX 写法大家看不懂,学完 React 后看起来就轻松了 。
由于 JSX/TSX 不是 Vue 的主流语法,大家可以自行了解即可。