Яма, которую приходится преодолевать при разработке небольших программ, я пролезла за вас!

Апплет WeChat

Всем привет друзья. Я МилФан. 👻👻👻

Я должен сказать, что этот проект был сделан в течение длительного времени. Во время процесса развития я столкнулся с некоторыми ямами, и я решил его и поделился всем. При всестороннем рассмотрении всех аспектов я отказался от основных многоквартирных рамок развития и использовал原生Каркас апплета для разработки.

Предки копают ямы, а страдают будущие поколения.Желаю вам всем поскорее стать большими коровами! ! 👻👻👻

👻Настроить динамическую панель навигации 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)
	},
  }
})

tabbar1 tabbar2Таким образом, мы реализовали функцию динамической панели вкладок, мы можем изменить данные списка таблиц в любое время, как прыгать, последнее слово за нами!

👻Всплывает окно ввода, и страница скользит вверх

Удовлетворите вышеуказанную проблему, наше решение: вручную установить положение поля ввода.

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.

В этот раз я поделюсь с вами ими первыми, и продолжу делиться с вами полезным опытом разработки в будущем.Не лезьте в ямы, которые уже пройдены.

Спасибо вам всем! 👻👻👻