支持vue3的uni-app项目框架实战

1,405 阅读3分钟

开发环境:HBuilderX

一、创建项目

1、使用命令行创建项目

创建以 javascript 开发的工程  
npx degit dcloudio/uni-preset-vue#vite my-vue3-project

创建以 typescript 开发的工程  
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project  

2、进入工程目录

复制代码cd my-vue3-project  

3、安装依赖

复制代码npm i  或  yarn  

4、 运行

  • 运行到 h5: npm run dev:h5
  • 运行到 app: npm run dev:app
  • 运行到 微信小程序: npm run dev:mp-weixin
    注意⚠️: 微信开发者工具需与hbuildx绑定,且微信开发者工具需打开服务端口(设置-安全设置-服务端口)

5、打包

  • 打包到 h5: npm run build:h5
  • 打包到 app :npm run build:app
  • 打包到 微信小程序: npm run build:mp-weixin

二、使用css预处理

安装less或sass出现的问题

一般都是版本的问题,2020年以后安装的less版本均为6.0以上,安装后可能会出现报错

建议使用cmpn:  npm install -g cnpm --registry=https://registry.npm.taobao.org

如果已有版本,则需卸载后再进行安装

如卸载less-loader : cnpm uninstall less-loader

  • 安装less
cnpm install less --save
cnpm install less-loader@4.1.0 --save
  • 安装sass
cnpm install sass --save
cnpm install sass-loader@7.0.0 --save
  • node-sass要安装最新版
cnpm install node-sass@latest

三、使用vuex

创建并引入store

  1. 首先在根目录下新建一个store文件夹,并在其中创建index.js,内容简单如下
import { createStore } from 'vuex'
const store = createStore({
    state:{//存放状态
        "username":"狐狸",
        "age":18
    }
})
 
export default store
  1. 在main.js中引入,并使用
import App from './App'
import store from './store'
 
import { createSSRApp } from 'vue'
export function createApp() {
  const app = createSSRApp(App)
	app.use(store)
  return {
        app
  } 
}
  1. 在页面中测试是否可以调用
<script>
    import store from '@/store/index.js'; //需要引入store
    console.log('使用vuex',store)
</script>

store模块化

当项目复杂时,可以奖store分割成模块 页面目录:

image.png

moduleA.js部分内容如下

const moduleB = {
	namespaced: true,
	//组件调用时:store.state.moduleA.userName
	state: {
		userName: '用户名'
	},
	mutations: {
		changeName(state, name) {
			state.userName = name
			//组件调用时:store.commit('moduleA/changeName','修改后我的名字')
		}
	}
}
export default moduleB

index中修改:

import moduleA from './modules/moduleA.js'
modules: {
		moduleA
	}

四、封装请求

新建目录如下:

image.png

utils下request.js内容如下:

// const baseUrl = 'http://8.140.136.xxx:8981' //接口请求地址(测试)
const baseUrl = "https://vue.xxx.com.cn"; //接口请求地址(正式)
const socketUrl = "wss://vue.xxx.com.cn"; //socket请求地址
import $store from "../store/index.js";
let commonParams = {
  token: $store.state.token
};
const httpRequest = ({ method, url = '', params = {}, header = {}, isLoading = true }) => {
  return new Promise((resolve, reject) => {
    // FN.Loading(1);
    if (isLoading) {
      wx.showLoading();
    }
    wx.request({
      url: baseUrl + url,
      data: params,
      method: method || 'POST',
      header: Object.assign({}, header, commonParams),
      timeout: 15000,
      success(res) {
        if (isLoading) {
          wx.hideLoading();
        }
        console.log('接口请求结束,返回的数据为', res);
        // FN.LoadingOff();
        if (res.statusCode === 200) {
          //与服务端链接成功
          switch (res.data.error_code) {
            case 0:
              //成功
              resolve(res?.data)
              break;
            case 10000:
              //未登录,请重新登录
              break;
            case 122:
              //参数不对,等其他情况
              break;
            default:
              uni.showToast({
                title: `请求失败:${res.data.message}`,
                icon: 'none',
              });
              reject(res);
          }
        } else {
          reject(res);
        };
      },
      fail(res) {
        // FN.Toast("网络开小差了");
        console.log('网络开小差了...');
        reject(res);
      }
    })
  })
};
export default {
  baseUrl,
  httpRequest,
  socketUrl,
};

utils下method.js内容如下:

import request from './request'
const get = ({
    url,
    params,
    header = {
        'content-type': 'application/json',
    },
    isLoading = true
}) => {
    return request.httpRequest({
        method: 'GET', url, params, header, isLoading
    });
}
const post = ({
    url,
    params,
    header = {
        'content-type': 'application/json',
    },
    isLoading = true
}) => {
    return request.httpRequest({
        method: 'POST', url, params, header, isLoading
    });
}
const getForm = ({
    url,
    params,
    header = {
        'content-type': 'application/x-www-form-urlencoded',
    },
    isLoading = true
}) => {
    return request.httpRequest({
        method: 'GET', url, params, header, isLoading
    });
}
const postForm = ({
    url,
    params,
    header = {
        'content-type': 'application/x-www-form-urlencoded',
    },
    isLoading = true
}) => {
    return request.httpRequest({
        method: 'POST', url, params, header, isLoading
    });
}
export default {
    get,
    post,
    getForm,
    postForm
}

api可以根据业务逻辑分类

import http from '../utils/method.js'
// get,post对应的请求头是{'content-type': 'application/json'},
// getForm,postForm对应的请求头是{'content-type': 'application/x-www-form-urlencoded'},
// 根据接口需求选用合适的请求方式
export function  postLogin (datas){
    return http.post({
        url:'/mp/user/check-login',
        datas,
        isLoading: true,
    })
}
//登录---------------
export function loginForm(datas){ 
    return http.getForm({
        url:'v1/shop/index_new.html',
        datas,
        isLoading: true,
    })
}

在页面中使用(pages/index/index.vue):

import {loginForm,postLogin} from "../../api/user.js"
postLogin({name:1}).then(res=>{}).catch(err=>{})//也可以用async await

源码地址:gitee.com/hmm18834406…