"Это второй день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г."
статус-кво
В апплете WeChat есть домашние страницы, личные страницы и некоторые страницы списков, страницы сведений и т. д. Большинством этих страниц можно поделиться. Когда общая страница открывается другим пользователем, как страница гарантирует, что пользователь вошел в систему?
В интернете много решений, добавляющих перехват в пакет запроса.Если токена нет, сначала вызвать запрос на вход для получения токена, а потом продолжить. В этой схеме нет ничего плохого, только обратите внимание на один момент, когда несколько запросов срабатывают на странице одновременно, когда все запросы перехватываются, они помещаются в массив, после успешного получения токена он достаточно для обхода массива по одному запросу.
Но этот запрос немного сложнее.Например, апплет сетевого магазина, на большинстве страниц должен быть магазин (поскольку необходимо получить инвентарь, цену и т. Д. Текущих продуктов магазина в соответствии с магазином), это хранилище основано на текущем местоположении Вызовите фоновый интерфейс, чтобы получить Да, было бы слишком сложно инкапсулировать его в запросе в это время.
решение
Прежде всего, мы заметили, что вход в систему и получение позиционирования асинхронны с нашим запросом страницы.Нам нужно убедиться, что запрос страницы выполняется после входа в систему и получения позиционирования, но если мы напишем каждую страницу один раз, ремонтопригодность будет слишком плохой. Таким образом, мы можем абстрагироваться от способа сделать это. Итак, код выглядит следующим образом:
const app = getApp()
Page({
data: {
logs: []
},
onLoad() {
app.commonLogin(()=>{
// 处理页页面请求
})
}
})
Кажется, это решает нашу проблему, но подумайте об этом еще раз, если вы хотите сделать больше вещей, таких как унифицированная обработка onShareAppMessage для каждой страницы, но я не хочу писать это снова на каждой странице, кроме того, я Я хочу реализовать часы для каждой страницы самостоятельно, как мне это сделать?
дальнейшие решения
Мы видим апплет WeChat, каждая страница — это Page(), затем мы можем добавить слой снаружи страницы, и у нас может быть MyPage для замены страницы, без дальнейших церемоний, код:
Код, связанный с tool.js
/**
* 处理合并参数
*/
handlePageParamMerge(arg) {
let numargs = arg.length; // 获取被传递参数的数值。
let data = {}
let page = {}
for (let ix in arg) {
let item = arg[ix]
if (item.data && typeof (item.data) === 'object') {
data = Object.assign(data, item.data)
}
if (item.methods && typeof (item.methods) === 'object') {
page = Object.assign(page, item.methods)
} else {
page = Object.assign(page, item)
}
}
page.data = data
return page
}
/***
* 合并页面方法以及数据, 兼容 {data:{}, methods: {}} 或 {data:{}, a:{}, b:{}}
*/
mergePage() {
return this.handlePageParamMerge(arguments)
}
/**
* 处理组件参数合并
*/
handleCompParamMerge(arg) {
let numargs = arg.length; // 获取被传递参数的数值。
let data = {}
let options = {}
let properties = {}
let methods = {}
let comp = {}
for (let ix in arg) {
let item = arg[ix]
// 合并组件的初始数据
if (item.data && typeof (item.data) === 'object') {
data = Object.assign(data, item.data)
}
// 合并组件的属性列表
if (item.properties && typeof (item.properties) === 'object') {
properties = Object.assign(properties, item.properties)
}
// 合组件的方法列表
if (item.methods && typeof (item.methods) === 'object') {
methods = Object.assign(methods, item.methods)
}
if (item.options && typeof (item.options) === 'object') {
options = Object.assign(options, item.options)
}
comp = Object.assign(comp, item)
}
comp.data = data
comp.options = options
comp.properties = properties
comp.methods = methods
return comp
}
/**
* 组件混合 {properties: {}, options: {}, data:{}, methods: {}}
*/
mergeComponent() {
return this.handleCompParamMerge(arguments)
}
/***
* 合成带watch的页面
*/
newPage() {
let options = this.handlePageParamMerge(arguments)
let that = this
let app = getApp()
//增加全局点击登录判断
if (!options.publicCheckLogin){
options.publicCheckLogin = function (e) {
let pages = getCurrentPages()
let page = pages[pages.length - 1]
let dataset = e.currentTarget.dataset
let callback = null
//获取回调方法
if (dataset.callback && typeof (page[dataset.callback]) === "function"){
callback = page[dataset.callback]
}
// console.log('callback>>', callback, app.isRegister())
//判断是否登录
if (callback && app.isRegister()){
callback(e)
}
else{
wx.navigateTo({
url: '/pages/login/login'
})
}
}
}
const { onLoad } = options
options.onLoad = function (arg) {
options.watch && that.setWatcher(this)
onLoad && onLoad.call(this, arg)
}
const { onShow } = options
options.onShow = function (arg) {
if (options.data.noAutoLogin || app.isRegister()) {
onShow && onShow.call(this, arg)
//页面埋点
app.ga({})
}
else {
wx.navigateTo({
url: '/pages/login/login'
})
}
}
return Page(options)
}
/**
* 合成带watch等的组件
*/
newComponent() {
let options = this.handleCompParamMerge(arguments)
let that = this
const { ready } = options
options.ready = function (arg) {
options.watch && that.setWatcher(this)
ready && ready.call(this, arg)
}
return Component(options)
}
/**
* 设置监听器
*/
setWatcher(page) {
let data = page.data;
let watch = page.watch;
Object.keys(watch).forEach(v => {
let key = v.split('.'); // 将watch中的属性以'.'切分成数组
let nowData = data; // 将data赋值给nowData
for (let i = 0; i < key.length - 1; i++) { // 遍历key数组的元素,除了最后一个!
nowData = nowData[key[i]]; // 将nowData指向它的key属性对象
}
let lastKey = key[key.length - 1];
// 假设key==='my.name',此时nowData===data['my']===data.my,lastKey==='name'
let watchFun = watch[v].handler || watch[v]; // 兼容带handler和不带handler的两种写法
let deep = watch[v].deep; // 若未设置deep,则为undefine
this.observe(nowData, lastKey, watchFun, deep, page); // 监听nowData对象的lastKey
})
}
/**
* 监听属性 并执行监听函数
*/
observe(obj, key, watchFun, deep, page) {
var val = obj[key];
// 判断deep是true 且 val不能为空 且 typeof val==='object'(数组内数值变化也需要深度监听)
if (deep && val != null && typeof val === 'object') {
Object.keys(val).forEach(childKey => { // 遍历val对象下的每一个key
this.observe(val, childKey, watchFun, deep, page); // 递归调用监听函数
})
}
var that = this;
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
set: function (value) {
if (val === value) {
return
}
// 用page对象调用,改变函数内this指向,以便this.data访问data内的属性值
watchFun.call(page, value, val); // value是新值,val是旧值
val = value;
if (deep) { // 若是深度监听,重新监听该对象,以便监听其属性。
that.observe(obj, key, watchFun, deep, page);
}
},
get: function () {
return val;
}
})
}
Код страницы:
app.tool.newPage({
data: {
// noAutoLogin: false
},
onShow: function () {
// 在这里写页面请求逻辑
}
}
наконец
Код уже давно работает в сети, пакет newPage в инструменте можно добавить в соответствии с вашими потребностями. Короче говоря, я здесь, чтобы предложить идею, если есть лучшая, поделитесь ею.