让我们一起用vite2、vue3、Ts搭建一个项目~

293 阅读6分钟

vite2+vue3(TS、JS)

(个别vscode中编写TS会报红 介意设置Javascript validate打开将勾选全部取消)

(官方文档:cn.vitejs.dev/)

注意:vite安装插件支持一命令安装多个

创建vite2项目

开启选项

npm init @vitejs/app

使用 Yarn:

yarn create @vitejs/app

可以使用多命令

例如:vite+ts+vue3

npm init @vitejs/app my-vue-app --template vue-ts

到这里我们项目就已经搭建好了,接下来我们开始配置文件

vite.config.ts(js)配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from "path"// https://vitejs.dev/config/
export default defineConfig({
  //自定义配置 将常用的地址提前配置好 便于开发中便捷
  alias: {
    '@': path.resolve(__dirname, "src"),
    comps: path.resolve(__dirname, "src/components"),
    apis: path.resolve(__dirname, "src/apis"),
    views: path.resolve(__dirname, "src/view")
  },
      // 引入第三方的配置,会将引入的第三方文件移动到E:\gitcode\工程目录\node_modules.vite_opt_cache目录中
    optimizeDeps: {
      include: ["echarts"]
    },
  plugins: [vue()]
})
​

在vue页面中使用

<template>
  <div>
    <img alt="Vue logo" src="./assets/logo.png" />
    <HelloWorld msg="第一次测试"></HelloWorld>
    <router-link to="Login"> 111</router-link>
    <router-view></router-view>
  </div>
</template>
​
<script lang="ts">
import { defineComponent } from "vue";
import HelloWorld from "comps/HelloWorld.vue";
export default defineComponent({
  name: "App",
  components: {
    HelloWorld,
  },
});
</script>

配置路由

npm install vue-router@4 --save

在src下新建router目录,新建index.ts文件

import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
​
// import Login from "../view/pic/pic.vue";
// import Homina from "../view/home/index.vue"
const home = () => import(/* webpackChunkName: "home" */ '../view/home/index.vue')
const Login = () => import(/* webpackChunkName: "pic" */ '../view/pic/pic.vue')
const routes: Array<RouteRecordRaw> = [
    {
        path: "/",
        name: "Home",
        meta: {
            title: "首页",
            keepAlive: true
        },
        component: home,
    },
    {
        path: "/login",
        name: 'Login',
        meta: {
            title: "登录",
            keepAlive: true
        },
        component: Login
    }
​
];
​
const router = createRouter({
    history: createWebHashHistory(),
    routes
});
​
export default router;

vuex(4.x)

npm i vuex@next --save

vuex配置

在src下创建store目录,并在store下创建index.ts

import { createStore } from "vuex";
export default createStore({
    state: {
        listData: { 1: 10 },
        num: 10
    },
    mutations: {
        setData(state, value) {
            state.listData = value
        },
        addNum(state) {
            state.num = state.num + 10
        }
    },
    actions: {
        setData(context, value) {
            context.commit('setData', value)
        },
    },
    modules: {}
});

配置jsx

安装

npm i @vitejs/plugin-vue-jsx

在vite.config.ts中引入

import { defineConfig } from 'vite'  //获得代码提示的支持
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'  //jsx
import path from "path"// https://vitejs.dev/config/
export default defineConfig({
  //自定义配置 将常用的地址提前配置好 便于开发中便捷
  // css: {},  //css配置
  // esbuild: {}, //打包配置
  alias: {
    '@': path.resolve(__dirname, "src"),
    "comps": path.resolve(__dirname, "src/components"),
    "apis": path.resolve(__dirname, "src/apis"),
    "views": path.resolve(__dirname, "src/view")
  },
  plugins: [vue(), vueJsx()]
})
​

(注意:可能会出现安装失效,安装失败的情况,安装的很慢,坑很多----打开package.json文件将@vitejs/plugin-vue-jsx放在开发人员配置项中--'devDependencies')

image-20210301221101154.png

Mock插件应用(已经支持vite2)

安装

//cross-env是插件 配置时需要用到

npm i vite-plugin-mock cross-env -D
yarn add mockjs -S //详情见文档

如果不使用ts写,需要改配置,在vite.config.ts中

//1.先导入
import {viteMockServe} from 'vite-plugin-mock'
//2.配置
 plugins: [viteMockServe({supportTs:false})] //如果使用ts则不需要配置supportTs

配置完之后在一级目录下创建mock文件夹,名字去user.js(名字都是任意起的)

export default [
    {
       url:'/api/getUsers',
       method:'get',
       response:() => {
           return{
              code:0,
               message:'ok',
               data:['tom','jerry']
              }
       }
    }
]
注意建议按照GitHub中vite-plugin-mock中试例

请求

//fetch aixos 都可以
fetch("/api/getUsers")
     .then((res)=>res.json())
     .then((data)=>{
         console.log(data);
     })

还需要去package.json中配置变量....太过复杂,完全可以跳过啊。醉了。

"scripts":{  //启动项配置
    "dev":"cross-env NODE_ENV=development vite"
}

cross-env需要安装插件

npm i  cross-env -D //上面第一次安装已有安装 不需要安装 跳过 了解

样式组织

安装sass

npm i sass -D

src目录下新建一个styles文件夹

styles目录保存各种样式

image-20210302100622861.png

在main中导入即可

注意在vite.config.js添加styles别名

 alias: {
    '@': path.resolve(__dirname, "src"),
    "comps": path.resolve(__dirname, "src/components"),
    "apis": path.resolve(__dirname, "src/apis"),
    "views": path.resolve(__dirname, "src/view"),
    "styles": path.resolve(__dirname, "src/styles") //这里
  },

image-20210717125203500.png

ui库的导入

1.element3

个人题外话:了解国内开发人员为下一代开发人员的贡献。

此处以Github中社区开发者利用vue3新特性composition API重构了elementui组件库,提供vue3的支持。

element-ui也推出了支持vue3的组件库---element plus (element-plus.org/#/zh-CN/com…)

首先npm

npm i element3 -S

main引入样式组件

//全局引入element3
import element3 from 'element3'
import 'element3/lib/theme-chalk/index.css'createApp(App)
    .use(element3)
    .mount('#app')

直接上手即可。

组件按需加载

1.src目录下创建一个plugins文件夹,文件下创建一个element3.ts

2.main中导入

import element3 from 'plugins/element3';
//plugins 在vite.config.ts中配置的简易路径
createApp(App)
    .use(element3)
    .mount('#app')

配置一下简易路径vite.comfig.ts

alias: {
    '@': path.resolve(__dirname, "src"),
    "plugins": path.resolve(__dirname, "src/plugins")
  },

3.在element3.ts中引入

//按需引入,有时候用不着很多的element3样式组件,打包会产生大的内存,所以采用按需引入import { ElButton, ElInput } from 'element3'
import 'element3/lib/theme-chalk/button.css'
import 'element3/lib/theme-chalk/input.css'//插件需要导出一个函数,这里接受一个实例化
export default function (app) {
    //按需引入
    app.use(ElButton)
    app.use(ElInput)
}

4.文件中直接使用即可

2.ant-design-vue

1.安装

 npm install --save-dev cross-env

cross-env这是一款运行跨平台设置和使用环境变量的脚本。

我们为什么要使用cross-env呢?是因为当使用NODE_ENV =production,来设置环境变量时,大多数Windows命令提示将会阻塞(报错),简单的讲就是---windows不支持NODE_ENV=development的设置方式,会报错。

2.使用

在我们的项目根目录下创建:

image-20210717125203500.png

创建好文件夹后,输入以下内容

image-20210717125259823.png

image-20210717125347052.png

配置好请求域名后,在package.json文件中配置启动、打包命令:

image-20210717125518863.png 至于含义,咱一眼就能看出。

数据封装

  • 统一配置请求
  • 请求、想要统一处理

准备工作

  • 安装axios

    npm i axios -S
    
  • 添加配置文件:.env.development

    VITE_BASE_API=/api
    

请求封装,新建一个utils文件夹,创建一个request.js:

import axios from 'axios';
import { message } from 'ant-design-vue';
import router from  '../router/index';
import { createApp } from 'vue';
import App from '@/App.vue';
// 构建axios实例
const instance = axios.create({
    baseURL: import.meta.env.VITE_BASE_API+'?s=',
    headers: {
        'content-type': 'application/x-www-form-urlencoded'
      },
	timeout: 5000  // 设置请求超时连接时间
})
// 请求拦截
instance.interceptors.request.use(
    (config) => {
        // 指定请求令牌
           if(localStorage.getItem('token')){
               config.headers["Token"] = localStorage.getItem('token');
           }
        // // 自定义令牌的字段名为X-Token,根据咱们后台再做修改
        return config;
    },
    (error) => {
        // 请求错误的统一处理
        console.log(error); // for debug
        return Promise.reject(error);
    }
);
// 响应拦截器
instance.interceptors.response.use(
    /**
     * 通过判断状态码统一处理响应,根据情况修改
     * 同时也可以通过HTTP状态码判断请求结果
     */
    (response) => {
        const res = response.data;
        //  console.log(res.code==200)
        //异地登录
        if(res.code==-1){
            router.push("/login");
        }
        // 如果状态码不是200则认为有错误
        if (res.code != 200) {
            message.error({
                content: res.msg || "Error",
                duration: 5 * 1000,
            });
            return Promise.reject(new Error(res.message || "Error"));
        } else {
            return res;
        }
    },
    (error) => {
        message({
            content: error.message,
            type: "error",
            duration: 20 * 1000,
        });
        return Promise.reject(error);
    }
);
// * 网络请求
// * @param method 方法
// * @param url 接口地址
// * @param params 参数
// * @param showError 是否展示错误信息
// * @returns {Promise<any>}
async function getHttp(url, params, showError) {
    if (showError || showError == undefined) { // 是否展示错误信息
        showError = true;
    } else {
        showError = false;
    }
    return new Promise((resolve, reject) => {
        instance({
            url:url,
            method:'get',
            params:params
        }).then((res) => {
            if (res.code == 200) { // 200 是请求成功
                resolve(res);
            } else { // 其他情况返回错误信息,根据需要处理
                reject(res);
                if (showError) {
                    message.error(res.msg);
                }
            }
        }).catch(() => {
            if (showError) {
                message.error('请求失败,请稍后再试');
            }
        })
    })
}

async function postHttp(url, params, showError) {
    if (showError || showError == undefined) { // 是否展示错误信息
        showError = true;
    } else {
        showError = false;
    }
    return new Promise((resolve, reject) => {
        instance({
            url:url,
            method:'post',
            params:params
        }).then((res) => {
            console.log(res.code)
            if (res.code == 200) { // 200 是请求成功
                // console.log('picpipcpic')
                resolve(res);
            } else { // 其他情况返回错误信息,根据需要处理
                reject(res);
                if (showError) {
                    message.error(res.data.msg);
                }
            }
        }).catch(() => {
            if (showError) {
                message.error('请求失败,请稍后再试');
            }
        })
    })
}
const app = createApp(App);
function install(app) {
    app.config.globalProperties.$getHttp = getHttp;
    app.config.globalProperties.$postHttp = postHttp;
}
export default install;

在main.JS中引入

打包配置

import { createApp } from 'vue';
import App from './App.vue';
//引入封装aixos请求
import Request from "utils/request.js";
createApp(App).use(Request)
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
​
// https://vitejs.dev/config/
export default defineConfig({
  resolve:{
    alias:{
      '@': path.resolve(__dirname,"src"),
      'comps': path.resolve(__dirname, "src/components"),
      'styles':path.resolve(__dirname,'src/styles'),
      'layouts':path.resolve(__dirname,'src/layout'),
      'utils':path.resolve(__dirname,'src/utils'),
      'views':path.resolve(__dirname,"src/view")
    }
  },
  build: {
    // 打包路径
    outDir: "../static",
    rollupOptions: {
      input: {
        // 入口文件
        main: path.resolve(__dirname, "index.html"),
        // 其他入口
        // nested: path.resolve(__dirname, 'xxxx.html')
      },
    },
  },
  plugins: [vue()]
})

这样我们也就可以开始进行我们的业务开发了~~