предисловие
Тост или компонент сообщения в основном используется в каждом проекте.
Во Vue и React они все компоненты, и мы привыкли обрабатывать этот тип компонентов в глобальном API, чтобы не писать шаблон и данные для каждой страницы, что более удобно для использования.
В апплете пользовательский компонент Toast также имеет ту же проблему [wx.showToast() этот API имеет только два метода успеха/загрузки, которые не могут удовлетворить наши потребности]
Оригинал похож на это ...
<td-toast is-show="{{$toast.show}}" icon="{{$toast.icon}}" text="{{$toast.text}}"></td-toast>
{
//data
data:{
$toast: {
show: false,
text: '',
icon: ''
}
},
//methods
toast(text, icon = '', times = 2000, cb) {
//...省略其他逻辑
this.setData({
$toast: {
show: true,
text: text,
icon: icon
}
});
//...省略其他逻辑
},
clearToast() {
//...省略其他逻辑
this.setData({
$toast: {
show: false,
text: '',
icon: ''
}
});
//...省略其他逻辑
}
}
вопрос
Практически на каждой странице нашего бизнеса есть тост. Это означает, что каждая страница должна определять wxml, data, toast(), clearToast()?
Нам нужно вызвать его так же, как wx.showToast()
строить планы
Сначала мы разобрались с проблемой wxml и обнаружили, что эту проблему решить непросто, у нас нет возможности динамически создавать теги.
Тогда я должен сначала использовать высокомерную схему: создать plugin.wxml (используемый для хранения всех глобальных общедоступных шаблонов)
Каждая страница будет включать этот plugin.wxml
//plugin.wxml
<!-- 目前只有toast -->
<td-toast is-show="{{$toast.show}}" icon="{{$toast.icon}}" text="{{$toast.text}}"></td-toast>
Затем разберитесь с проблемой js и используйте plugin.js для выполнения логики данных, соответствующей plugin.wxml.
//plugin.js
export default {
$data: {
$toast: {
show: false,
text: '',
icon: ''
}
},
//methods
toast(text, icon = '', times = 2000, cb) {
//...省略其他逻辑
this.setData({
$toast: {
show: true,
text: text,
icon: icon
}
});
//...省略其他逻辑
},
clearToast() {
//...省略其他逻辑
this.setData({
$toast: {
show: false,
text: '',
icon: ''
}
});
//...省略其他逻辑
}
};
Видно, что plugin.js — это содержимое страницы, поэтому следующим шагом будет внедрение содержимого plugin.js на каждую страницу.
В это время попробуйте определить inject.js
import plugin from './plugin';
function inject(page) {
for (let key in plugin.$data) {
if (Object.prototype.hasOwnProperty.call(plugin.$data, key)) { //过滤
page.data[key] = plugin.$data[key];
}
}
const obj = Object.assign({}, plugin, page);
return obj;
}
export default (page) => {
return inject(page)
}
В настоящее время существует метод внедрения, который может объединять plugin.js со страницей.
Просто добавьте метод инъекции на страницу
// pages/demo/index.js
import inject from './../plugin/inject';
Page(
// 注入 plugin
inject({
data: {},
onLoad: function(options) {},
onReady: function() {},
onShareAppMessage: function() {
// plugin.js中定义的 toast()
this.toast('分享')
}
})
);
На данный момент он почти завершен, конечно, есть еще некоторые проблемы, такие как поле usingComponents в конфигурации json
Хорошего решения этих проблем пока нет.
В настоящее время пишу инструмент сборки для автоматической обработки конфигурации json, конечно, в основном он используется для однофайловой разработки, решения проблем, которые нельзя использовать с npm, и дополнительно поддерживает postcss
Это отступление, мы также можем использовать вышеприведенную инъекцию для некоторых других вещей, таких как перехват страницы
Например: добавить обратный вызов onLogin
//plugin.js
export default {
$data: {
$toast: {
show: false,
text: '',
icon: ''
}
},
/**
* 生命周期函数--监听onLoad
*/
loadHooker: function(onLoad, onLogin) {
return function(option) {
// 不管三七二十一 先调了onLoad再说
onLoad.call(this, option);
const app = getApp();
if (app.globalData.userInfo) { // 已经登录
setTimeout(()=>{
this.globalData = app.globalData;
if (onLogin) {
onLogin.call(this, option, app.globalData.userInfo);
}
},0)
} else { //没有登录 异步=》onLogin
app.userInfoReadyCallback = json => {
this.globalData = app.globalData;
if (onLogin) {
onLogin.call(this, option, app.globalData.userInfo);
}
};
}
};
},
toast(text, icon = '', times = 2000, cb) {
//...省略其他逻辑
},
clearToast() {
//...省略其他逻辑
}
};
//inject.js
import plugin from './plugin';
function inject(page) {
for (let key in plugin.$data) {
if (Object.prototype.hasOwnProperty.call(plugin.$data, key)) { //过滤
page.data[key] = plugin.$data[key];
}
}
//新回调
const onLoadHooker = plugin.loadHooker(page.onLoad, page.onLogin);
const obj = Object.assign({}, plugin, page);
obj.onLoad = onLoadHooker;// hookonLoad
return obj;
}
export default (page) => {
return inject(page)
}
Если интерфейс выборки зависит от информации о пользователе
Page(
inject({
data: {},
onLoad: function() {},
onLogin: function(options, userInfo) {
this.toast('拿到用户信息')
this.fetch(userInfo.openid);
}
})
)
Что ж, впервые пишу такую статью, очень незнакомая, надеюсь, смогу указать на какие-то ошибки или идеи получше.