1 Star 4 Fork 0

guokai/vite-vue3-ts

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

vite + vue3 + ts

Build Setup

vite

npm install && npm run dev

记录

vite 部分

入口文件配置

index.html 和 main.ts 的关系

  • index.html 放置到了项目的根目录和 package.json 同级
  • index.html 中
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
    
  • script 标签的 src 引入的地址为入口文件的路径
  • 多页面应用暂不讨论(盲猜多页面应用会有多个 html 文件,每个文件引入不同的入口文件)

vite.config.js 配置

plugins 配置

  • 支持 vue 引入插件 '@vitejs/plugin-vue'
  • 支持 jsx 引入插件 '@vitejs/plugin-vue-jsx'
  • plugins 使用
plugins = [vue(), vueJsx()];

设置别名

  • 需要优先安装"@types/node",否则没有模块 path、dirname、require 等
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 的引入

<template>
  <div class="font_center"></div>
</template>
<script>
  import "/@/utils/cssModel/base.css";
</script>

模块化引入

<template>
  <div :class="flex_center"></div>
</template>
<script>
  // 此处引入的css必须以.module.css结尾
  import cssCommon from "/@/utils/cssModel/common.module.css";
  // 或者
  // import { flex_center } from "/@/utils/cssModel/common.module.css";
  // console.log(cssCommon.flex_center);
  import { defineComponent } from "vue";

  export default defineComponent({
    name: "App",
    components: {},
    setup() {
      return {
        ...cssCommon, //必须在setup导出才可以在模板中使用
        // flex_center
      };
    },
  });
</script>

预处理器

  • vite 中添加 css 预处理器会有默认配置(也可自定义)直接安装对应的依赖即可使用

  • 例如

  • 安装 npm install -D less

<!-- 直接在style申明lang='less'即可使用 -->
<style lang="less" scoped>
  .home {
    font-size: 24px;
    div {
      color: red;
    }
  }
</style>

静态资源处理

json 导入

  • 可以被直接导入 - 同样支持具名导入
// 导入整个对象
import res from "./res.json";
// 对一个根字段使用具名导入 - 有效运用 tree-shaking!
import { data } from "./res.json";

Glob 导入

配置本地启动 ip 地址

  • 只需在 package.json 的命令中添加后缀 --host 即可
  • 例如:
// 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 读取
  1. 命令配置
  • 添加后缀 --mode + 对应的环境(需要与 env 文件的后缀对应)
// 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"
},
  1. vite.config 中获取环境变量
// 导出一个函数,入参的 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({});
};

配置代理

// 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 文件
  • 导出主要的配置
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 构造函数上的方法太多
  • 同时如果存在多个实例也可以互不影响
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

  • 配置路由

import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
// 方法需从 vue-router导出
// 支持ts 可直接导出路由对象的接口 RouteRecordRaw
const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    component: () => import("../view/index.vue"),
  },
];
// createRouter变成一个方法,而不需要 new VueRouter
// hash还是history模式也变更为方法
const router = createRouter({
  history: createWebHashHistory(),
  routes,
});
export default router;

pinia

安装以及基本配置

// 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 挂载配置
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

相同点

  • 都可以描述一个对象或者函数
// 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 可以相互交叉继承
//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;
};
  1. type 可以而 interface 不可以
  • type 可以声明基本类型别名,联合类型,元组等类型
// 基本类型别名
type Name = string;

// 联合类型
interface Name {
  name: string;
}
interface Age {
  age: number;
}
type Message = Name | Age;

// 具体定义数组每个位置的类型
type MessageList = [Name, Age];
  • type 语句中还可以使用 typeof 获取实例的 类型进行赋值
let div = document.createElement("div");
type B = typeof div;
  • 其他操作
type StringOrNumber = string | number;
type Text = string | { text: string };
type NameLookup = Dictionary<string, Person>;
type Callback<T> = (data: T) => void;
type Pair<T> = [T, T];
type Coordinates = Pair<number>;
type Tree<T> = T | { left: Tree<T>; right: Tree<T> };
  1. interface 可以而 type 不行
  • interface 能够声明合并
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
const name = ref<string>("泛型T");

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/guokaiGit/vite-vue3-ts.git
git@gitee.com:guokaiGit/vite-vue3-ts.git
guokaiGit
vite-vue3-ts
vite-vue3-ts
master

搜索帮助