# vite-vue3-ts **Repository Path**: guokaiGit/vite-vue3-ts ## Basic Information - **Project Name**: vite-vue3-ts - **Description**: vite-vue3-ts - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2021-05-24 - **Last Updated**: 2022-10-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vite + vue3 + ts ## Build Setup #### vite npm install && npm run dev # 记录 ## vite 部分 ### 入口文件配置 #### index.html 和 main.ts 的关系 - index.html 放置到了项目的根目录和 package.json 同级 - index.html 中 ```html
``` - script 标签的 src 引入的地址为入口文件的路径 - 多页面应用暂不讨论(盲猜多页面应用会有多个 html 文件,每个文件引入不同的入口文件) ### vite.config.js 配置 #### plugins 配置 - 支持 vue 引入插件 '@vitejs/plugin-vue' - 支持 jsx 引入插件 '@vitejs/plugin-vue-jsx' - plugins 使用 ```typescript plugins = [vue(), vueJsx()]; ``` #### 设置别名 - 需要优先安装"@types/node",否则没有模块 path、dirname、require 等 ```typescript import path from 'path' const resolve = (dir: string) => path.join(__dirname, dir) // resolve.alias属性 const resolve = { alias: [ // '@':resolve("src"), // 1 { // 2 find: /\/@\//, replacement: resolve("src"), }, ]; } ``` ### css 的引入以及预处理器 #### 普通 css 的引入 ```html ``` #### 模块化引入 ```html ``` #### 预处理器 - vite 中添加 css 预处理器会有默认配置(也可自定义)直接安装对应的依赖即可使用 - 例如 - 安装 npm install -D less ```html ``` ### 静态资源处理 - 可以引入成为一个变量,也可以添加一些参数做更多的处理 - 文档传送门 https://www.vitejs.net/guide/assets.html ### json 导入 - 可以被直接导入 - 同样支持具名导入 ```typescript // 导入整个对象 import res from "./res.json"; // 对一个根字段使用具名导入 - 有效运用 tree-shaking! import { data } from "./res.json"; ``` ### Glob 导入 - 批量导入,支持懒加载 - 文档传送门 https://www.vitejs.net/guide/features.html#glob-%E5%AF%BC%E5%85%A5 ### 配置本地启动 ip 地址 - 只需在 package.json 的命令中添加后缀 --host 即可 - 例如: ```typescript // package.json "scripts": { "dev": "vite --host", // 添加了host "build": "vue-tsc --noEmit && vite build", "serve": "vite preview" }, ``` ### 环境以及环境变量配置 1. env 文件配置 - env 文件中的配置默认为通用配置,可以被所有环境读取 - env 文件的各种后缀可以标志为各种环境 例如 env.development , env.production - env 带有后缀的文件内部的配置可以覆盖 env 文件中的配置 - 只有以 'VITE\_' 开头的配置才会被 vite 读取 2. 命令配置 - 添加后缀 --mode + 对应的环境(需要与 env 文件的后缀对应) ```typescript // package.json "scripts": { "dev": "vite --host --mode development", "pro": "vite --host --mode production", "test": "vite --host --mode test", "build": "vue-tsc --noEmit && vite build", "serve": "vite preview" }, ``` 3. vite.config 中获取环境变量 ```typescript // 导出一个函数,入参的 command, mode 为当前的环境和信息 import { defineConfig, loadEnv, ConfigEnv } from "vite"; export default ({ command, mode }: ConfigEnv) => { //command "build" | "serve" 打包还是编译 // mode 各种环境 const root = process.cwd(); //项目根目录寻找env文件时使用 const env = loadEnv(mode, root); // 获取配置的环境变量 // console.log(env); return defineConfig({}); }; ``` ### 配置代理 ```typescript // server选项配置代理,基本与webpack一致 server: { port: Number(env.VITE_PORT), // 端口号 proxy: createProxy(JSON.parse(env.VITE_PROXY)), hmr:true // 热更新 }, ``` ### 配置 rem - 下载安装 postcss-pxtorem - 与 package.json 同级目录创建 postcss.config.js 文件 - 导出主要的配置 ```javascript module.exports = { plugins: { "postcss-pxtorem": { rootValue: 37.5, propList: ["*"], unitPrecision: 5, }, }, }; ``` - 安装 amfe-flexible npm i amfe-flexible -D - main.ts 中导入 import 'amfe-flexible/index.js' - amfe-flexible 依赖 autoprefixer, 所以安装 npm i autoprefixer ## vue3 部分 ### main.ts #### main.ts 的改变 - vue3 的所有引入全部修改为函数式,最大化脱离 this 和静态方法(摇树优化) - 所有的方面会挂载到 createApp 执行后产生的 app 对象中。避免 Vue2.0 中 vue 构造函数上的方法太多 - 同时如果存在多个实例也可以互不影响 ```typescript import { createApp } from "vue"; import App from "./App.vue"; const app = createApp(App); app.mount("#app"); ``` ## 全家桶 ### vue-router #### 安装以及基本配置 - vue3 需要配套 vue-router4 以上的版本 - 安装命令 npm install vue-router@4 - 配置路由 ```typescript import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router"; // 方法需从 vue-router导出 // 支持ts 可直接导出路由对象的接口 RouteRecordRaw const routes: Array = [ { path: "/", component: () => import("../view/index.vue"), }, ]; // createRouter变成一个方法,而不需要 new VueRouter // hash还是history模式也变更为方法 const router = createRouter({ history: createWebHashHistory(), routes, }); export default router; ``` ### pinia #### 安装以及基本配置 ```typescript // store.js import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => { return { count: 0, b:12 } }, actions: { increment() { this.count++ }, }, }) // 具体使用 import { useCounterStore } from '/@/store/index'; import { storeToRefs } from 'pinia' //辅助函数 const counterStore = useCounterStore(); // 获取该仓库 // 变量需要使用storeToRefs包裹才可以生成副作用 这种写法可直接return b const { b } = storeToRefs(counterStore) // 方法可直接解构使用 const { increment } = counterStore // 重置store function reset() { counterStore.$reset() } // 修改的3种方式 function change(){ counterStore.$patch({ count:500, b:2 }) // or // counterStore.$state = { count: 500, b:2 } // or storeToRefs的方式才可使用 // b.value = 500 } // 或者计算属性控制 例如:count return { count: computed(() => counterStore.count), // 计算属性导出 b, increment, reset, change }; ``` - main.ts 挂载配置 ```typescript import { createApp } from "vue"; import App from "./App.vue"; import router from "./router/index"; import { createPinia } from 'pinia'; const pinia = createPinia(); const app = createApp(App); app.use(router); app.use(pinia); app.mount("#app"); ``` ## ts 部分 ### type 和 interface #### 相同点 - 都可以描述一个对象或者函数 ```typescript // interface interface User { name: string age: number } interface SetUser { (name: string, age: number): void; } // type type User = { name: string age: number }; type SetUser = (name: string, age: number): void; ``` #### 不同点 1. 拓展的语法不同,但是效果差不多 - interface extends interface (继承) - type & type (交叉) - type 和 interface 可以相互交叉继承 ```typescript //interface 继承 interface Name { name: string; } interface People extends Name { age: number; } // type交叉 type Name = { name: string; }; type People = Name & { age: number; }; // interface 继承 type type Name = { name: string; }; interface People extends Name { age: number; } // type与interface交叉 interface Name { name: string; } type People = Name & { age: number; }; ``` 2. type 可以而 interface 不可以 - type 可以声明基本类型别名,联合类型,元组等类型 ```typescript // 基本类型别名 type Name = string; // 联合类型 interface Name { name: string; } interface Age { age: number; } type Message = Name | Age; // 具体定义数组每个位置的类型 type MessageList = [Name, Age]; ``` - type 语句中还可以使用 typeof 获取实例的 类型进行赋值 ```typescript let div = document.createElement("div"); type B = typeof div; ``` - 其他操作 ```typescript type StringOrNumber = string | number; type Text = string | { text: string }; type NameLookup = Dictionary; type Callback = (data: T) => void; type Pair = [T, T]; type Coordinates = Pair; type Tree = T | { left: Tree; right: Tree }; ``` 3. interface 可以而 type 不行 - interface 能够声明合并 ```typescript interface People { name: string; age: number; } interface People { sex: string; } /* People 接口为 { name: string age: number sex: string } */ ``` #### 总结 - 一般来说,能用 interface 就用 interface,如果无法实现,则使用 type ### 泛型 T 以及 unknown 和 any #### unknown 和 any 1. 两者都为顶级类型可以表示所有类型 2. unknown 在使用时需要类型校验或者断言才可以使用,而 any 不会有任何类型校验 #### 泛型 T - 在定义函数,接口,类的时候,不预先指定具体的类型,而在使用的时候在去指定类型的一种特征 - 例如 vue3 的 ref ```typescript const name = ref("泛型T"); ```