使用vite构建vue3+ts项目及配置

vite创建vue3项目

(vue3+vue-router+ts+vite+element-plus+pinia+axios)

1. 初始化项目

  1. npm init vite@latest
    
  2. 输入项目名称

  3. 选择vue3 + ts

  4. 创建完毕cd到页面

  5. 安装默认依赖并运行

2. 初始配置

此处选用vscode进行编写代码,值得注意的是vue3中使用vscode的插件时需要禁用以前vue2常使用的插件Vetur,而安装Vue Language Features (Volar)插件。不然代码会提示报错。

  1. 配置所需依赖

    npm install @types/node --save-dev
    
  2. 修改vite.config.ts配置文件代码

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import { resolve } from 'path'
    
    export default defineConfig({
      plugins: [vue()],
      //解决“vite use `--host` to expose”
      base: './',
      server: {             
        host: '0.0.0.0',	
        // port: 8080,      
        open: true
      },
      resolve:{   
        //别名配置,引用src路径下的东西可以通过@如:import Layout from '@/layout/index.vue'
        alias:[   
          {
            find:'@',
            replacement:resolve(__dirname,'src') 
          }
        ]
      }
    })
    
  3. 安装路由

    npm install vue-router@4
    
  4. 在src目录下新建router文件夹,在router里创建index.ts

    import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
    // import Layout from '../components/HelloWorld.vue'
    
    const routes: Array<RouteRecordRaw> = [
      {
      //路由初始指向
        path: '/',
        name: 'HelloWorld',
        component:()=>import('../components/HelloWorld.vue'),
      }
    ]
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    })
    
    export default router
    
  5. main.ts中导入挂载路由

    import { createApp } from 'vue'
    import './style.css'
    import App from './App.vue'
    import router from './router'
    
    const app = createApp(App);
    app.use(router).mount('#app')
    
  6. 修改App.vue管理路由

    <script setup lang="ts">
    </script>
    <template>
      <router-view></router-view>
    </template>
    
    <style>
    
    </style>
    
  7. 运行看是否报错。如图打开了路由指向的HelloWorld.vue页面的内容就对了

  8. 配置ts文件采用@方式导入,在tsconfig.json文件中添加配置

    {
      "compilerOptions": {
        "target": "esnext",
        "useDefineForClassFields": true,
        "module": "esnext",
        "moduleResolution": "node",
        "strict": true,
        "jsx": "preserve",
        "sourceMap": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "esModuleInterop": true, 
        "lib": ["esnext", "dom"],
        "skipLibCheck": true,
    
        //添加---
        "suppressImplicitAnyIndexErrors": true,		//允许字符串用作下标
        "ignoreDeprecations":"5.0",		//高版本上句报错,此句解决。如此句报错可注释掉
         "baseUrl": ".",			
         "paths": {					
          "@/*":[					
            "src/*"					
          ]							
         }							
         //---------
      },
      "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
      "references": [{ "path": "./tsconfig.node.json" }],
      
      //添加
      "exclude":["node_modules"]		// // ts排除的文件
    
    }
    
  9. 安装代码检测工具

    npm install --save-dev eslint eslint-plugin-vue
    
  10. 在根目录创建.eslintrc.js文件

    module.exports = {
    	root: true,
    	parserOptions: {
    		sourceType: 'module'
    	},
    	parser: 'vue-eslint-parser',
    	extends: ['plugin:vue/vue3-essential', 'plugin:vue/vue3-strongly-recommended', 'plugin:vue/vue3-recommended'],
    	env: {
    		browser: true,
    		node: true,
    		es6: true
    	},
    	rules: {
    		'no-console': 'off',
    		'comma-dangle': [2, 'never'] //禁止使用拖尾逗号
    	}
    }
    

    在rules可以添加自己的验证规则

  11. 安装 css 预处理器 sass

    npm install -D sass sass-loader
    
  12. 引入element-plus

    npm install element-plus --save
    npm install @element-plus/icons-vue // 图标
    

    element-plus是vue3目前大流行组件库,用法基本和element ui一样

  13. main.ts中引入

    import { createApp } from 'vue'
    import './style.css'
    import App from './App.vue'
    import router from './router'
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    import * as ElementPlusIconsVue from '@element-plus/icons-vue'
    import zhCn from "element-plus/es/locale/lang/zh-cn";//国际化
    
    const app = createApp(App);
    
    app.use(ElementPlus, { locale: zhCn }).use(router).mount('#app')
    
    //全局注册图标组件
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
        app.component(key, component)
    }
    
  14. 国际化报错注意

> 国际化时如果安装了^2.3.8上的高版本或找不到包,解决方法:
> 需要在vite-env.d.ts加入
> declare module "element-plus/dist/locale/zh-cn.mjs"
> main.ts 中
> import zhCn from "element-plus/dist/locale/zh-cn.mjs"
> 若仍然有问题,修改为如下引用
> import zhCn from "element-plus/es/locale/lang/zh-cn"
  1. 使用element plus组件

    <template>
      <el-button type="primary" size="default" :icon='Plus'>新增</el-button>
    </template>
    <script setup lang="ts">
    import {Plus} from '@element-plus/icons-vue';
    
    </script>
    <style scoped lang="scss">
    
    </style>
    

    清除原有Helloworld.vue内容,添加element-plus按钮

  2. 安装pinia(状态管理,类似vue2中的vuex)

    npm install pinia
    
  3. 全局引入pinia

    import { createApp } from 'vue'
    import './style.css'
    import App from './App.vue'
    import router from './router'
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    import * as ElementPlusIconsVue from '@element-plus/icons-vue'
    import zhCn from "element-plus/es/locale/lang/zh-cn";//国际化
    import { createPinia } from 'pinia'
    
    const app = createApp(App);
    // 实例化 Pinia
    const pinia = createPinia()
    
    app.use(ElementPlus,{locale: zhCn}).use(router).use(pinia).mount('#app')
    
    //全局注册图标组件
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
        app.component(key, component)
    }
    
  4. 开发提示

    上面代码引用了默认的style.css文件(引用位置main.ts中),可能里面样式对我们开发有干扰,可自行处理修改style.css默认样式。建议:全删除,自己设置html,body,#app样式。以下参考可自行发挥:

*{
  margin: 0;
  padding: 0;
}
html,body,#app {
  width: 100%;
  height: 100%;
}

3. axios配置

  1. 下载依赖包

    npm install axios
    
  2. 在src文件夹下面创建utils文件夹,其下创建request.ts文件

    import axios from 'axios'
    // 创建axios实例
    const request = axios.create({
        baseURL: '',// 所有的请求地址前缀部分
        timeout: 80000, // 请求超时时间(毫秒)
        withCredentials: true,// 异步请求携带cookie
        // headers: {
        // 设置后端需要的传参类型
        // 'Content-Type': 'application/json',
        // 'token': x-auth-token',//一开始就要token
        // 'X-Requested-With': 'XMLHttpRequest',
        // },
    })
     
    // request拦截器
    request.interceptors.request.use(
        config => {
            // 如果你要去localStor获取token,(如果你有)
            // let token = localStorage.getItem("x-auth-token");
            // if (token) {
                    //添加请求头
                    //config.headers["Authorization"]="Bearer "+ token
            // }
            return config
        },
        error => {
            // 对请求错误做些什么
            Promise.reject(error)
        }
    )
     
    // response 拦截器
    request.interceptors.response.use(
        response => {
            // 对响应数据做点什么
            return response.data
        },
        error => {  
            // 对响应错误做点什么
            return Promise.reject(error)
        }
    )
    export default request
    
  3. 封装请求

    在src文件夹下面创建api文件夹,其下创建index.ts文件

    import instance from "@/utils/request";
    
    //一般情况下,接口类型会放到一个文件
    // 下面两个TS接口,表示要传的参数
    interface ReqLogin {
      name: string
      paw: string
    }
    interface ReqStatus {
      id: string
      navStatus: string
    }
    
    
    // Res是返回的参数,T是泛型,需要自己定义,返回对数统一管理***
    type Res<T> = Promise<ItypeAPI<T>>;
    // 一般情况下响应数据返回的这三个参数,
    // 但不排除后端返回其它的可能性,
    interface ItypeAPI<T> {
      data: T,//请求的数据,用泛型
      msg: string | null // 返回状态码的信息,如请求成功等
      code: number //返回后端自定义的200,404,500这种状态码
    }
    
    
    // post请求 ,没参数
    export const LogoutAPI = (): Res<null> =>
      instance.post("/admin/logout");
    
    // post请求,有参数,如传用户名和密码
    export const loginAPI = (data: ReqLogin): Res<string> =>
      instance.post("/admin/login", data);
    
    // post请求 ,没参数,但要路径传参
    export const StatusAPI = (data: ReqStatus): Res<null> =>
      instance.post(`/productCategory?ids=${data.id}&navStatus=${data.navStatus}`);
    
    
    //  get请求,没参数,
    export const FlashSessionListApi = (): Res<null> =>
      instance.get("/flashSession/list");
    
    // get请求,有参数,路径也要传参  (也可能直接在这写类型,不过不建议,大点的项目会维护一麻烦)
    export const ProductCategoryApi = (params: { parentId: number }): any =>
      instance.get(`/productCategory/list/${params.parentId}`, { params });
    
    // get请求,有参数,(如果你不会写类型也可以使用any,不过不建议,因为用了之后 和没写TS一样)
    export const AdminListAPI = (params: any): any =>
      instance.get("/admin/list", { params });
    
    
  4. 使用请求

    使用方式一:直接使用(和vue2在cretae上用一样,setup自带async,await在顶层可以直接使用)

    <script setup lang="ts">
    import { indexAPI} from "@/api/index.ts";
        //直接使用,一般用在进入页面入请求数据的接口
        let res = await indexAPI()
        console.log( "***" ,res);
    </script>
    

    使用方式二:使用 async / await,(setup虽然自带async,但单独用await只能在顶层使用,如果在函数下还是要async / await一起写)

    <script setup lang="ts">
    import { returnApplyListAPi } from "@/api/index.ts";
     
    const search = async(val: IUseTableParam) => {
        let res = await returnApplyListAPi({
            ...val,
        })
        console.log( "***" ,res);
        let { list, pageNum, pageSize, total } = res.data
        console.log(list, pageNum, pageSize, total);
    }
    </script>
    

    使用方式三:使用.then

    <script setup lang="ts">
    import { returnApplyListAPi} from "@/api/index.ts";
     
    const logout = () => {
        returnApplyListAPi({
            ...val,
        }).then((res) => {
             console.log('***',res );
            let { list, pageNum, pageSize, total } = res.data
        })
     
    };
    </script>
    
  5. 跨域代理

跨域需要代理才写

vite.config.ts文件中

export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': { // 匹配请求路径,
        target: '你要代理的地址', // 代理的目标地址
        changeOrigin: true,
        // secure: true, // 是否https接口
        // ws: true, // 是否代理websockets

        // 路径重写,**** 如果你的后端有统一前缀(如:/api),就不开启;没有就开启
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
})
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值