Всем привет друзья. Я МилФан. 👻👻👻
Я должен сказать, что этот проект был сделан в течение длительного времени. Во время процесса развития я столкнулся с некоторыми ямами, и я решил его и поделился всем.
При всестороннем рассмотрении всех аспектов я отказался от основных многоквартирных рамок развития и использовал原生
Каркас апплета для разработки.
Предки копают ямы, а страдают будущие поколения.Желаю вам всем поскорее стать большими коровами! ! 👻👻👻
👻Настроить динамическую панель навигации Tabbar
В разработке апплета по умолчанию определитеtabbar
, должен быть вapp.json
Конфигурация json следующая:
"tabBar": {
...
"list": [
{
"text": "首页",
"iconPath": "/public/images/index.png",
"selectedIconPath": "/public/images/index-act.png",
"pagePath": "pages/job/index"
}
...
]
}
После настройки его нельзя изменить. вы можете позвонитьsetTabBarItem
Установите текст кнопки и путь к изображению; невозможно динамически установить адрес перехода и количество вкладок.
решение
Нам нужно создать новый中间页面
, используется для управления всеми панелями вкладок и использования страниц, которые будут связаны с панелями вкладок.组件
Таким образом, нам нужно только написать стиль панели вкладок с исправлением внизу этой страницы и щелкать разные вкладки, чтобы отображать разные компоненты.
JSON-файл
{
"usingComponents": {
"home" : "/pages/job/index", // 首页
"company" : "/pages/company/company", // 公司
"message" : "/pages/chat/index", // 消息
"mine" : "/pages/mine/index", // 我的
"tabbar" : "/milfun/widget/custom-tab-bar", //自定义tabbar组件
}
}
wxml-файл
<!-- wxml中,把页面设置成组件 -->
<home wx:if="{{activeTab == 'home'}}">首页</home>
<company wx:if="{{activeTab == 'company'}}">公司</company>
<message wx:if="{{activeTab == 'message'}}">消息</message>
<mine wx:if="{{activeTab == 'mine'}}">我的</mine>
<!-- wxml中,自定义tabbar组件 -->
<tabbar list="{{tabList}}" bindmytab="tabChange"></tabbar>
js-файл
Page({
data: {
activeTab:'home' // company 、message、mine
},
onLoad: function (options) {
let tmp = 1; // 用来控制显示不同方案的tabbar
if( tmp === 1 ){ // 显示第一套tabbar
this.setData({
tabList:[
{
"name": "...",
"text": "...",
"iconPath": "...",
"selectedIconPath": "...",
"pagePath": "..."
},
...
]
})
}else{ // 显示第二套tabbar
this.setData({
tabList:[{},...]
})
}
}
})
Выше показан метод написания промежуточной страницы Как изменить обычную страницу на страницу компонента?
Измените страницу на компонентную запись
Разница в основном из-за разного написания в js-файле, поэтому мы смотрим только на js-часть:
нормальное письмо
Page({
data: {
},
onLoad: function (options) {
},
onShow: function (options) {
},
func1:function(e){
console.log(e)
},
func2:function(e){
console.log(e)
},
})
написание компонентов
Component({
options: { // 为了使用全局css样式
addGlobalClass: true,
},
data: {},
/*
* 组件被创建时调用,等同于上方的 onLoad
*/
attached: function (options) {
},
/*
* 组件内部方法,等同于上方的自定义方法
*/
methods: {
func1:function(e){
console.log(e)
},
func2:function(e){
console.log(e)
},
}
})
Таким образом, мы реализовали функцию динамической панели вкладок, мы можем изменить данные списка таблиц в любое время, как прыгать, последнее слово за нами!
👻Всплывает окно ввода, и страница скользит вверх
Удовлетворите вышеуказанную проблему, наше решение: вручную установить положение поля ввода.
js-файл
// 输入框获取焦点
foucus:function (e) {
this.setData({typerHeight: e.detail.height})
},
// 输入框失去焦点
blur:function () {
this.setData({typerHeight: 0})
},
wxml-файл
<view class="tc-board" style="bottom:{{typerHeight}}px" >
......
</view>
Таким образом, когда поле ввода получает фокус, он будет получен на высоту клавиатуры, а затем входное поле - это нижний стиль, установите его на свой рост, что идеально подходит на поле ввода. Когда поле ввода потеряла фокус, высота устанавливается на 0, а входной вид ввода возвращается в нижнюю часть страницы.
👻Обратный вызов асинхронного запроса + проверка токена
Чтобы избежать написания сложного вложенного оператора if else в бизнес или функции обратного вызова
// 方法一
onLoad:function (e) {
// if嵌套
if(){
if(){
if(){ // do something }
}
}
// 回调陷阱
func1(data,func(){
func2(data,func(){
func3(data,func(){
// do something
})
})
})
},
Мой подход заключается в добавлении обещания к методу, например, 🥗:
js-файл публичной функции
/**
* 统一post请求接口
* @param {*} e “url,data,contentType,noOuth”
*/
function post(e){
// token 保存在缓存中,有需要时调取
let header = { 'Content-Type': contentType, 'Authorization':'Bearer ' + getCache('accessToken') }
// 封装在promise中
return new Promise(function (resolve, reject) {
wx.request({
url: config.domain + e.url , // domain统一放在config中
data:e.data,
method: 'POST',
header: header,
success: res => {
// console.log(res)
if(res.data.code == 200 ){
resolve(res.data) // 请求成功,返回数据
}
else{
wx.showToast({
title: res.msg,
icon: 'none',
duration: 1500,
});
reject(res.data.msg) // 请求出错,显示错误
}
},
fail: res => { // 请求失败
wx.showToast({
title: '请求发送失败',
icon: 'none',
duration: 1500,
});
}
})
})
}
JS-файл страницы
// 方法一
onLoad:function (e) {
fun.post({ url:'...',data:{...} })
.then( res => console.log(res) ) // 步骤一
.then( res => console.log(res) ) // 步骤二
.then( res => console.log(res) ) // 步骤三
.catch( res => console.log(res) ) // 捕捉异常
},
Это делает письмо четким, элегантным и приятным!
👻 Интерфейс единого управления
С вышеприведенным почтовым интерфейсом у нас будет много интерфейсов запросов в разработке.Если они все написаны на странице, ими сложно управлять.Если есть какая-то модификация, будет проблематично найти их один за другим.Мой подход:
Создайте новый js в каталоге модуля, чтобы сохранить всю информацию об интерфейсе. Почему под модулем? Потому что учитывая, что могут быть разные субподряды, если их все вместе прописать, то это будет слишком много, и подразделение будет доставлять неудобства руководству.Подробности, пожалуйста, работайте по конкретным проектам.
унифицированный файл управления интерфейсом API
/**
* 该模块下所有接口
* 接口参数:
* url: just url
* contentType: default:false( use urlencoded ) or true( use json )
* noOuth: default:false( hase Authorization ) or true( no Authorization )
*/
const constApi = {
// 获取用户信息
getUserInfo : { // 定义接口调用的名字
url: 'api/v1/userinfo'
},
// 获取用户设置
getUserSetting: {
url: 'api/v1/usersetting',
outh:true // 需要鉴权
}
}
/**
* 对外接口统一调用
* @param {*} name 在api文件中的key
* @param {*} data 要post的数据
*/
const http = async function(key,data){
let api = constApi[key];
let response = await fun.post({
url:api.url,
data:data,
contentType:api.contentType,
outh:api.noOuth
})
return response
}
export default http
инструкции
// 导入api文件
import Api from './api-index.js'
onLoad:async function (e) {
// 用法一
Api('getUserInfo ',{
userId:1,
userPwd:123456,
...
})
.then( res => console.log(res) )
...
// 用法二
let tmp = await Api('getUserInfo',{...})
this.setData({ list: tmp })
},
В то время, если интерфейс изменен или изменен адрес, нет необходимости ходить по всей улице, чтобы найти те страницы, которые используют интерфейс, и изменять их одну за другой. Его нужно только изменить и управлять им единообразно в api-index.js.
В этот раз я поделюсь с вами ими первыми, и продолжу делиться с вами полезным опытом разработки в будущем.Не лезьте в ямы, которые уже пройдены.
Спасибо вам всем! 👻👻👻