使用uniapp&Vue系开发小程序
创建项目
sh
// js
npx degit dcloudio/uni-preset-vue#vite uni-preset-vue
// ts
npx degit dcloudio/uni-preset-vue#vite-ts uni-preset-vue也可直接clone模板
sh
// git clone -b 分支名 --single-branch <repository URL>
// js
git clone -b vite --single-branch https://github.com/dcloudio/uni-preset-vue.git
//ts
git clone -b vite-ts --single-branch https://github.com/dcloudio/uni-preset-vue.git安装依赖
sh
cd uni-preset-vue
npm i
// yarn运行项目
sh
npm run dev:mp-weixin
// yarn dev:mp-weixin状态管理
使用pinia进行状态管理,安装pinia
sh
npm i pinia
// 如遇到安装依赖冲突时忽视冲突 npm i pinia --legacy-peer-deps
// yarn add pinia使用pinia
js
// main.js
import App from './App'
import { createSSRApp } from 'vue';
import * as Pinia from 'pinia';
import util from './utils/util.js';
export function createApp() {
const app = createSSRApp(App);
const store = Pinia.createPinia();
app.use(store);
// app.config.globalProperties.$util = util;
uni.$util = util;
return {
app,
Pinia
}
}在src目录下创建store文件夹,创建相应的仓库,如user.js
js
// src/store/user.js
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
export const useUserStore = defineStore('user', {
// state
const token = ref('');
// getters
const logged = computed( () => {
return true
})
// actions
const setToken = (token) => {
token.value = token
}
retrun {
token,
logged,
setToken
}
})pinia数据持久化
sh
npm i pinia-plugin-unistorage
// yarn add pinia-plugin-unistorage修改main.js,增加以下代码
js
import { createUnistorage } from 'pinia-plugin-unistorage';
store.use(createUnistorage());在页面中使用
vue
<script setup>
import { useUserStore } from '@/store/user.js'
const user = useUserStore()
// 设置token
const token = 'jwt-token';
user.setToken(token)
// 打印token
console.log(user.token)
</script>网络请求
axios或uni-request任选一种方式
使用axios进行网络请求
安装axios、小程序适配器插件axios-miniprogram-adapter
sh
npm i axios
// yarn add axios
npm i axios-miniprogram-adapter
// yarn add axios-miniprogram-adapter在src目录下创建config目录,创建配置文件net.config.js
js
export const netConfig = {
// axios 基础url地址
baseURL: 'https://xxx.xx/api',
// 为开发服务器配置 CORS。默认启用并允许任何源,传递一个 选项对象 来调整行为或设为 false 表示禁用
cors: true,
// 根据后端定义配置
contentType: 'application/json;charset=UTF-8',
// 回话密钥名称
tokenName: 'Authorization',
//消息框消失时间
messageDuration: 3000,
//最长请求时间
requestTimeout: 60000,
//操作正常code,支持String、Array、int多种类型
successCode: [200, 0],
//登录失效code
invalidCode: -1,
//无权限code
noPermissionCode: -1,
};使用axios
js
// src/utils/request.js
import axios from 'axios';
import mpAdapter from "axios-miniprogram-adapter";
axios.defaults.adapter = mpAdapter;
import { netConfig } from '@/config/net.config';
const { baseURL, contentType, requestTimeout, successCode } = netConfig;
let tokenLose = true;
const instance = axios.create({
baseURL,
timeout: requestTimeout,
headers: {
'Content-Type': contentType,
},
});
// request interceptor
instance.interceptors.request.use(
(config) => {
// do something before request is sent
return config;
},
(error) => {
// do something with request error
return Promise.reject(error);
}
);
// response interceptor
instance.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
(response) => {
const res = response.data;
// 请求出错处理
// -1 超时、token过期或者没有获得授权
if (res.status === -1 && tokenLose) {
tokenLose = false;
uni.showToast({
title: '服务器异常',
duration: 2000
});
return Promise.reject(res);
}
if (successCode.indexOf(res.status) !== -1) {
return Promise.reject(res);
}
return res;
},
(error) => {
return Promise.reject(error);
}
);
export default instance;封装api,在src目录下创建api目录,创建不同模块请求集,如user.js
js
import request from '@/utils/request'
/**
* @description 授权登录
* @param {*} data
*/
export function wxLogin(data) {
return request({
url: '/wx/code2Session',
method: 'post',
params: {},
data
})
}
/**
* @description 获取手机号
* @param {*} data
*/
export function getPhoneNumber(data) {
return request({
url: '/wx/getPhoneNumber',
method: 'post',
params: {},
data
})
}在页面中使用
vue
<script setup>
import { wxLogin, getPhoneNumber } from '@/api/user.js'
/**
* @description 微信登录
*/
const onWxLogin = async () => {
uni.login({
provider: 'weixin',
success: loginRes => {
state.wxInfo = loginRes
const jsCode = loginRes.code
wxLogin({jsCode}).then((res) => {
const { openId } = res.data
user.setUserInfo({ openId })
})
}
})
}
</script>使用uni-request封装网络请求
js
// src/utils/request.js
import { baseURL, HEADER, TOKENNAME } from '@/config/app';
import { useUserStore } from '../store/user.js';
//发送请求
function baseRequest(url, method, data, auth = false) {
let header = {
};
const userStore = useUserStore();
if (!auth) {
//登录过期自动登录
if (!userStore.logged && !uni.$util.checkLogin()) {
return uni.$util.toast('token过期,请重新登录', 'error', 800, () => {
setTimeout(() => {
uni.reLaunch({
url: '/pages/login/index'
})
}, 800)
})
}
}
if (userStore.userToken.accessToken) header[TOKENNAME] = `Bearer ${userStore.userToken.accessToken}`;
return new Promise((reslove, reject) => {
uni.showLoading({
title: '加载中'
})
uni.request({
url: baseURL + url,
method: method || 'GET',
header: header,
data: data || {},
success: (res) => {
// console.log('-----请求url-----', url)
// console.log('-----请求res-----', res)
if (res.statusCode == 200 && res.data.code == 200) {
reslove(res.data);
} else if (res.statusCode == 200 && res.data.code == 401) {
uni.showModal({
title: '错误提示',
content: res.data.message || '登录过期,请重新登录',
showCancel: false,
confirmText: '重新登录',
success(op) {
if (op.confirm) {
userStore.logout()
uni.reLaunch({
url: '/pages/login/index'
})
}
}
})
} else {
uni.showModal({
title: '错误说明',
content: res.data.message || '未知错误',
showCancel: false,
confirmText: '知道了'
})
reject(res.data.message || '系统错误');
}
},
fail: (err) => {
console.log(err);
uni.showModal({
title: '错误说明',
content: JSON.stringify(err) || '未知错误',
showCancel: false,
confirmText: '知道了'
})
reject(JSON.stringify(err))
},
complete() {
uni.hideLoading()
}
})
})
}
const request = {};
['options', 'get', 'post', 'put', 'head', 'delete', 'trace', 'connect'].forEach((method) => {
request[method] = (api, data, auth) => baseRequest(api, method, data, auth)
})
export default request;在src/api目录下创建模块请求集,如user.js
import request from "@/utils/request.js";
/**
* 获取用户信息
*/
export function getUserInfo() {
return request.get('sysUser/baseInfo', {}, true);
}相关配置
安装vue自动导入插件
sh
npm i unplugin-auto-import
// yarn add unplugin-auto-import修改vite.config.js
js
import AutoImport from 'unplugin-auto-import/vite'
plugins: [
AutoImport({
imports: ["vue"]
})
]使用组件
使用vant UI组件,在src目录下创建wxcomponents,拷贝vant文件夹(npm i vant后拷贝dist目录下vant)
json
// pages.json
// 全局引入
"globalStyle": {
"usingComponents": {
"van-button": "/wxcomponents/vant/button/index"
}
}
// 局部引入
{
"path": "pages/index/index",
"usingComponents": {
"van-button": "/wxcomponents/vant/button/index"
}
}在页面中直接使用
vue
<template>
<view>
<van-button type="default">默认按钮</van-button>
</view>
</template>