uniapp 新建用户端
新建uniapp项目
uniapp官网
链接: uniapp官网
点击新建项目
选择空项目
点击创建 ,新建默认模板
新建项目完成
代码结构
page 页面 类似于 vue 的 view
static 静态资源 类似于 vue 的 assert
App.vue 主启动类
main.js 主配置文件 ,适合导入全局的 js 和 挂在原型链
page.json 路由配置 vue的 router.js
点击运行
看见此页面 代码运行成功
其代码于 vue.js 高度相适,不在说明
配置请求拦截 接口
你需要的知识点 :
js 原型链
vue store
uview
导入uview
链接: 参考网站
注意我们导入的是 1.几 版本
配置 vue store
vue stroe 是全局状态管理的功能
全局的method 和 data
method 分成两种 一个是 mutations 同步执行,在 定时器 微任务执行的时候数值不准
actions 异步执行 ,
在下面我定义了 userinfo isLogin isRefresh token 三个数据
userinfo 用户登录数据
isLogin是否登录
isRefresh : 刷新用户数据
token : 与系统交互的 凭证
// vuex 状态管理
// vuex 状态管理
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
// 数据源
state: {
userinfo: uni.getStorageSync('USERINFO') || {},
historyLists: uni.getStorageSync("__history") || [],
islogin: uni.getStorageSync("islogin") || false,
isRefresh: uni.getStorageSync("isRefresh") || false,
socketTask: null,
message: {},
kuaiZhaoLists: uni.getStorageSync("kuaiZhaoLists") || [],
isSend: uni.getStorageSync("isSend") || false,
token: uni.getStorageSync('token') || {}
},
mutations: {
SET_USER_INFO(state, userInfo) {
state.userinfo = userInfo
},
SET_IS_SEND(state, isSend) {
state.isSend = isSend
},
SET_islogin(state, islogin) {
state.islogin = islogin
},
SET_isRefresh(state, isRefresh) {
state.isRefresh = isRefresh
},
SET_HISTORY_LISTS(state, history) {
state.historyLists = history
},
CLEAR_HISTORY(state) {
state.historyLists = []
},
CLEAR_ISLOGIN(state) {
state.islogin = false
},
CLEAR_USER_INFO(state) {
state.userinfo = {}
},
SET_kuaiZhao(state, kuaizhao) {
state.kuaiZhaoLists = kuaizhao
},
SET_token(state, token) {
state.token = token
},
},
actions: {
set_issend({
commit
}, issend) {
uni.setStorageSync('isSend', issend)
commit('SET_IS_SEND', issend)
},
set_userinfo({
commit
}, userinfo) {
uni.setStorageSync('USERINFO', userinfo)
commit('SET_USER_INFO', userinfo)
},
set_kuaizhao({
commit
}, kuaihzao) {
uni.setStorageSync('kuaiZhaoLists', kuaihzao)
commit('SET_kuaiZhao', kuaihzao)
},
set_islogin({
commit
}, islogin) {
uni.setStorageSync('islogin', islogin)
commit('SET_islogin', islogin)
},
set_isRefresh({
commit
}, isRefresh) {
uni.setStorageSync('isRefresh', isRefresh)
commit('SET_isRefresh', isRefresh)
},
set_token({
commit
}, token) {
uni.setStorageSync('token', token)
commit('SET_token', token)
},
set_history({
commit,
state
}, history) {
let list = state.historyLists
list.unshift(history)
uni.setStorageSync('__history', list)
commit('SET_HISTORY_LISTS', list)
},
clearHistory({
commit
}) {
uni.removeStorageSync('__history')
commit('CLEAR_HISTORY')
},
clearislogin({
commit
}) {
uni.removeStorageSync('islogin')
commit('CLEAR_ISLOGIN')
},
clearHistory({
commit
}) {
uni.removeStorageSync('USERINFO')
commit('CLEAR_USER_INFO')
}
}
})
export default store
我把·我之前写的都导入进来了
在 main.js 导入 token 用来 全局保存用户信息
导入 uview
链接: uview
官网在线导入 文档 ,不在说明
配置代码请求统一管理入口
我在代码新建了 utils 公共请求 和 拦截的 js
在下面实现了 请求 和 拦截 ,我从 uni.getStorageSync(‘token’) 得到 token 拼接到 请求头上面
拦截为 请求 接口 返回的 code 为 401 表面 未登录或者 token 过期 ,就进入 登录页面
// An highlighted block
// common/http.interceptor.js
// 这里的Vue为Vue对象(非创建出来的实例),vm为main.js中“Vue.use(httpInterceptor, app)”这一句的第二个参数,
// 为一个Vue的实例,也即每个页面的"this"
// 如果需要了解这个install方法是什么,请移步:https://uviewui.com/components/vueUse.html
const install = (Vue, vm) => {
//Vue.prototype.$u 这个是 在 main.js1 uview 挂载在 vue 原型上
// 此为自定义配置参数,具体参数见上方说明
Vue.prototype.$u.http.setConfig({
baseUrl: Vue.prototype.baseUrl, // 请求的本域名
method: 'POST',
// 设置为json,返回后会对数据进行一次JSON.parse()
dataType: 'json',
showLoading: true, // 是否显示请求中的loading
loadingText: '请求中...', // 请求loading中的文字提示
loadingTime: 500, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
originalData: false, // 是否在拦截器中返回服务端的原始数据
loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
// // 配置请求头信息
header: {
'content-type': 'application/json;charset=UTF-8'
},
});
// 请求拦截部分,如配置,每次请求前都会执行
Vue.prototype.$u.http.interceptor.request = (config) => {
// if(config.url.search(`/wx/user/${Vue.prototype.appid}/login`)===-1 && config.url.search(`/citylife/nocheck`)===-1){
// config.header.Authorization='wx '+uni.getStorageSync('token');
// }else{
// //访问登录等接口
// config.header.Authorization='';
// }
if (uni.getStorageSync('token')) {
config.header.Authorization = 'Bearer '+uni.getStorageSync('token');
}
// 引用token
// 方式一,存放在vuex的token,假设使用了uView封装的vuex方式
// 见:https://uviewui.com/components/globalVariable.html
// config.header.token = vm.token;
// 方式二,如果没有使用uView封装的vuex方法,那么需要使用$store.state获取
// config.header.token = vm.$store.state.token;
// 方式三,如果token放在了globalData,通过getApp().globalData获取
// config.header.token = getApp().globalData.username;
// 方式四,如果token放在了Storage本地存储中,拦截是每次请求都执行的
// 所以哪怕您重新登录修改了Storage,下一次的请求将会是最新值
// const token = uni.getStorageSync('token');
// config.header.token = token;
// config.header.Token = 'xxxxxx';
// 可以对某个url进行特别处理,此url参数为this.$u.get(url)中的url值
// if (config.url == '/user/login') config.header.noToken = true;
// 最后需要将config进行return
return config;
// 如果return一个false值,则会取消本次请求
// if(config.url == '/user/rest') return false; // 取消某次请求
}
// 响应拦截,如配置,每次请求结束都会执行本方法
Vue.prototype.$u.http.interceptor.response = (res) => {
if (res.code == 200) {
// res为服务端返回值,可能有code,result等字段
// 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到
// 如果配置了originalData为true,请留意这里的返回值
return res;
} else if (res.code == 500) {
// res为服务端返回值,可能有code,result等字段
// 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到
uni.showToast({
title: res.msg,
icon: 'error'
})
return false;
} else if (res.code == 401) {
vm.$u.toast('身份验证失败,请重新登录');
setTimeout(() => {
vm.$u.route('/pages/Login/Login')
}, 1500)
return false;
} else {
console.log(res);
return res;
}
}
}
export default {
install
}
接口管理
const install = (Vue, vm) => {
// 登录
let login = (params = {}) => vm.$u.post(`/core/userindex/login`, params);
//得到用户数据
let getUserDetail = () => vm.$u.get(`/core/userindex/hello`);
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
vm.$u.api = {
login,
getUserDetail
};
}
export default {
install
}
// 这里我定义了 登录 和 得到用户消息接口 通过 uview 的 模板统一进行管理
测试接口
接口分析
需要知识点 asyc await 解决回调地狱
async onClick_1() {
if (this.username == '') {
uni.showToast({
icon: 'error',
title: '账号不能为空'
})
return
}
if (this.password == '') {
uni.showToast({
icon: 'error',
title: '密码登录不能为空'
})
return
}
let res = await this.$u.api.login({
"username": this.username,
"password": this.password,
})
if (res.code == 200) {
// uni.setStorageSync('token', res.data.token)
uni.setStorageSync('token', res.data.token)
this.$store.dispatch('set_islogin', true)
this.$store.dispatch('set_isRefresh', true)
uni.showToast({
title: '登录成功',
icon: 'none'
});
if (this.options != '') {
console.log('准备跳转回去的页面:', this.options.delta);
let delat = this.options.delta || '';
delat = decodeURIComponent(delat);
if (delat.indexOf("/pages/my/my") != -1) {
uni.reLaunch({
url: delat
});
return;
}
uni.navigateBack({
delta: 1
});
}
}
},
通过接口 得到 token返回用户首页
getUserInfo(){
let that = this;
this.$store.dispatch('set_isRefresh', false)
that.$u.api.getUserDetail().then(res => {
console.log('userInfo接口返回值:',res);
// 保存userinfo
this.$store.dispatch('set_userinfo', res.data);
});
},
成功完成了 前后端 接口 代码对接
结尾
我等下会提供模板代码和 公共接口 在评论区 希望大家共同进步 。