阅读 950

vue3+ts+vant的个人搭建方式(学习中)

最近vite更新频繁,现版本最高vite2,确实更高更快更强,可惜,run build报错,尝试了一下vue3框架的各种搭建模式,现总结以下适合移动端的vue3+ts+vant搭建方式,避免后续走弯路

创建vue3+ts项目

基础node环境搭建这里不做详述

vue脚手架搭建(这里不选择用vite,因为不稳定,等待尤大后续更新出稳定版本)

npm install -g @vue/cli
复制代码

创建vue3+ts项目

vue create vue3-project
复制代码

创建项目时注意勾选自己需要的各种选项

引入ui样式框架,这里选择vant

vant3.0文档链接

安装vant

# Vue 3 项目,安装 Vant 3:
npm i vant@next -S
复制代码

vant 官网:在 Vite 中如何按需引入组件?

在 Vite 中无须考虑按需引入的问题。Vite 在构建代码时,会自动通过 Tree Shaking 移除未使用的 ESM 模块。而 Vant 3.0 内部所有模块都是基于 ESM 编写的,天然具备按需引入的能力。 现阶段遗留的问题是,未使用的组件样式无法被 Tree Shaking 识别并移除,后续我们会考虑通过 Vite 插件的方式进行支持

main.ts使用

import { createApp } from 'vue'
import App from './App.vue'
import Vant from 'vant'
import 'vant/lib/index.css';

createApp(App).use(Vant).mount('#app')
复制代码

项目运行

npm run dev
复制代码

测试vant是否引入成功(查看组件样式是否正确显示即可)

创建TestDemo.vue组件并引用

使用van-cell-group组件

<van-cell-group>
  <van-cell title="单元格" value="内容"></van-cell>
  <van-cell title="单元格" value="内容"></van-cell>
</van-cell-group>
复制代码

注释掉App.vue中的基础样式

项目编译

run build

测试项目打包结果

使用nodejs的http-server模块直接在dist文件中启用建议服务检测 进入dist根目录

http-server
复制代码

简易封装axios

src文件加下新建services文件夹 新建两个子文件url.ts和request.ts

url.ts

export default{
    
    baseUrl:'http://www.test.com',
    login:'/login/normal'
}

复制代码

request.ts


import axios, { AxiosInstance, AxiosResponse } from "axios";
import url from "@/services/url";

axios.defaults.timeout = 60000; // 设置全局请求超时时间

axios.defaults.baseURL = url.baseUrl // 设置全局请求基地址

export default class Request {
    private spinningAxios = axios.create(); // 建立请求时会产生全局Loading的axios实例

    private noSpinningAxios = axios.create(); // 建立请求时不会产生全局Loading的axios实例

    constructor() {
        this.addInterceptors(this.spinningAxios, true);
        this.addInterceptors(this.noSpinningAxios, false);
    }

    private addInterceptors(requestMain: AxiosInstance, loading: boolean): void {
        requestMain.interceptors.request.use(options => {
            // 对全局请求的options进行更改,例如增加动态头部信息等
            if (loading) {
                // 自定义全局Loading的产生方式,在项目开发中建议在全局写一个工具类 例如 xxxx.showLoading()
            }
            return options;
        }, error => {
            // 错误捕捉 此时的错误为最外层status的错误
            return Request.outError(error, loading)
        })
        requestMain.interceptors.response.use(response => {
            // 处理全局请求的返回response,例如对返回值进行判断
            return Request.disposeResponse(response, loading)
        }, error => {
            // 错误捕捉 此时的错误为最外层status的错误
            return Request.outError(error, loading)
        })
    }

    private static outError(error: any, loading: boolean): Promise<string> {
        if (loading) {
            // 自定义全局Loading的关闭方式,在项目开发中建议在全局写一个工具类 例如 xxxx.hideLoading()
        }
        const { response = {} } = error;
        return Promise.reject(response.statusText || (error && error.toString()) || "未知错误");
    }

    private static disposeResponse(response: AxiosResponse, loading: boolean): AxiosResponse | Promise<any> {
        if (loading) {
            // 自定义全局Loading的关闭方式,在项目开发中建议在全局写一个工具类 例如 xxxx.hideLoading()
        }
        // 对接口返回的数据进行判断,例如接口中 code 的值 200为成功,500为失败,401为未登录时进行各个操作,此处可以使用枚举
        const { data } = response;
        switch (data.code) {
            // case insideStatus.success:  // 200
            //     return response;
            // case insideStatus.error: // 500
            //     return Promise.reject(data.msg);
            // case insideStatus.noLogin: // 401
            //     this.utils.toLogin();
            //     return Promise.reject(data.msg);
            // default:
            //     return Promise.reject(data.msg);
            default: return response; //示例数据,请自行剔除
        }
    }

    public async post<T, S>(url: string, data: T): Promise<S | string> {
        return this.spinningAxios.post(url, data, {
            // 添加例如 headers 之类的属性
        }).then(res => Promise.resolve(res.data)).catch(err => Promise.reject(err.toString()))
    }

    public async get<T, S>(url: string, data: T): Promise<S | string> {
        return this.spinningAxios.get(url, {
            params: data,
            // 添加例如 headers 之类的属性
        }).then(res => Promise.resolve(res.data)).catch(err => Promise.reject(err.toString()))
    }

    public async postNoLoading<T, S>(url: string, data: T): Promise<S | string> {
        return this.noSpinningAxios.post(url, data, {
            // 添加例如 headers 之类的属性
        }).then(res => Promise.resolve(res.data)).catch(err => Promise.reject(err.toString()))
    }

    public async getNoLoading<T, S>(url: string, data: T): Promise<S | string> {
        return this.noSpinningAxios.get(url, {
            params: data,
            // 添加例如 headers 之类的属性
        }).then(res => Promise.resolve(res.data)).catch(err => Promise.reject(err.toString()))
    }
}
复制代码

request使用

src文件夹下新建api文件夹 新建text.ts文件

import Request from '@/services/request';
export default class Methods {
    private request = new Request();
    public async login<T, S>(data: T): Promise<S | string> {
        return this.request.post('12312321', data)
    }

}
复制代码

页面中使用

import Methods from '@/api/test'
复制代码
  setup: () => {
    onMounted(() => {
      const http = new Methods()
      http
        .login({
          userPhone: '123456789',
          userPassword: '123456789',
        })
        .then((res) => {
          //成功回调
          console.log(res)
        })
        .catch((err) => {
          //失败回调
          console.log(err)
        })
    })
  },
复制代码

vuex的使用

这里有两种不推荐vue3使用vuex的说法可借鉴:

链接1 链接2

vue3新建项目时代码中自带store文件

这里模块化处理 store文件夹下新建module文件夹 module下新建test.ts

const test = {
    state: {
        total: 10
    },
    mutations: {
        totleFun(state: any, value: number): void {
            state.total = value
        }
    },
    actions: {
        totleFunAdd(context: any, value: number) {
            context.commit('totleFun', value + 1)
        },
        totleFunDel(context: any, value: number) {
            context.commit('totleFun', value - 1)
        }
    }
}

export default test
复制代码

相应的index.js中引用

import { createStore } from 'vuex'
import  test  from './module/test'
export default createStore({
  state: {
   
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    test
  }
})
复制代码

页面中访问

//引入
import {useStore } from 'vuex'

//使用
useStore().state.test.total
复制代码
文章分类
前端
文章标签