vue3项目搭建

1,384 阅读4分钟

设计技术点

  • vue3
  • 不适用ts
  • 配置vant3
  • 移动端适配

创建vue3项目

vue create vue3-project

部分步骤说明

选择一种创建方式

  • 默认 vue2版本
  • 默认 vue3版本
  • 手动配置 我们这里选第三种

选择项目所需要的特征属性

  • 选择vue版本
  • babel用于处理兼容
  • 这里不使用ts
  • PWA(Progressive Web App) 相关链接
  • 十分不建议勾选Linter/Formatter,这里的eslint十分不友好,后续需要可手动增加

添加vant3.0样式

vant3.0文档地址

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

移动端rem适配

Vant 官方也为我们提供了方案 Vant 中的样式默认使用 px 作为单位,如果需要使用 rem 单位,推荐使用以下两个工具: postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem lib-flexible 用于设置 rem 基准值

postcss配置

项目根目录新建postcss.config.js

module.exports = {
    "plugins": {
        "autoprefixer": {
            // 配置使用 autoprefixer
            overrideBrowserslist: ["last 15 versions"],
            browsers: ["Android >= 4.0", "iOS >= 7"]
        },
        "postcss-pxtorem": {
            rootValue: 100, // Vant 官方根字体大小是 37.5
            propList: ['*'],
            selectorBlackList: ['.norem'] // 过滤掉.norem-开头的class,不进行rem转换
        }
    }
}

注意:rootValue设置为100是为了方便将ui图中尺寸进行换算,这里1rem=100px

src文件夹下新建utils文件夹 utils文件夹下新加rem.js

// rem等比适配配置文件
// 基准大小
const baseSize = 100
// 注意此值要与 postcss.config.js 文件中的 rootValue保持一致
// 设置 rem 函数
function setRem() {
    // 当前页面宽度相对于 375宽的缩放比例,可根据自己需要修改,一般设计稿都是宽750(图方便可以拿到设计图后改过来)。
    const scale = document.documentElement.clientWidth / 375
    // 设置页面根节点字体大小(“Math.min(scale, 2)” 指最高放大比例为2,可根据实际业务需求调整)
    document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px'
}
// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = function () {
    console.log("我执行了")
    setRem()
}

main.js中使用rem.js

import './utils/rem'

注意rem.js中基准大小要与postcss.config.js中设置的rootValue值相同,rem.js主要用于等比适配配置文件

axio二次封装

utils中新建http.js

// src/utils/http.js

import axios from 'axios';

const getBaseUrl = (env) => {
    let base = {
        production: '/',
        development: 'https://www.baidu.com',
        test: 'http://localhost:3001',
    }[env];
    if (!base) {
        base = '/';
    }
    return base;
};

class NewAxios {
    constructor() {
        this.baseURL = getBaseUrl(process.env.NODE_ENV);
        this.timeout = 10000;
        this.withCredentials = true;
    }

    setInterceptors = (instance, url) => {
        instance.interceptors.request.use((config) => {
            // 在这里添加loading
            // 配置token
            config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || '';
            return config;
        }, err => Promise.reject(err));

        instance.interceptors.response.use((response) => {
            // 在这里移除loading
            // todo: 想根据业务需要,对响应结果预先处理的,都放在这里
            return response;
        }, (err) => {
            if (err.response) { // 响应错误码处理
                switch (err.response.status) {
                    case '403':
                        // todo: handler server forbidden error
                        break;
                    // todo: handler other status code
                    default:
                        break;
                }
                return Promise.reject(err.response);
            }
            if (!window.navigator.online) { // 断网处理
                // todo: jump to offline page
                return -1;
            }
            return Promise.reject(err);
        });
    }

    request(options) {
        // 每次请求都会创建新的axios实例。
        const instance = axios.create();
        const config = { // 将用户传过来的参数与公共配置合并。
            ...options,
            baseURL: this.baseURL,
            timeout: this.timeout,
            withCredentials: this.withCredentials,
        };
        // 配置拦截器,支持根据不同url配置不同的拦截器。
        this.setInterceptors(instance, options.url);
        return instance(config); // 返回axios实例的执行结果
    }
}

export default new NewAxios();

src文件夹下新建api,api下 1:index.js 2:home.js

//index.js
export * from './home';


//home.js
import axios from '@/utils/http';
export const fetchData = data => axios.request({
  method:'get',
  url: '/123/data',
  params:data
});
export default {};

注意:这种封装方式每次请求都会新建一个实例,过多实例是否会影响包体积或其他问题等这里有待讨论

这里用class的封装方式原因参考如下: 给这个类创建实例上的方法request 在 request 方法里,创建新的axios实例,接收请求配置参数,处理参数,添加配置,返回axios实例的请求结果(一个promise对象)。 你也可以不创建,直接使用默认导出的axios实例,然后把所有配置都放到它上面,不过这样一来整个项目就会共用一个axios实例。虽然大部分项目下这样够用没问题,但是有的项目中不同服务地址的请求和响应结构可能完全不同,这个时候共用一个实例就没办法支持了。所以为了封装可以更通用,更具灵活性,我会使用axios的create方法,使每次发请求都是新的axios实例。

参考文章