Краткое изложение навыков разработки мини-программ

внешний интерфейс JavaScript Ресурсы изображений Icon

предисловие

Недавно компания собиралась разработать апплет электронной коммерции, и он начал работать после прочтения документа в спешке. Общий опыт разработки лично для меня не очень хорош, особенно если вы привыкли к разработке Vue раньше и вдруг разрабатываете небольшие программы, это кажется очень безвкусным. Ниже приводится сводка некоторых проблем и решений, с которыми я столкнулся при разработке, только для справки.

Внедрить иконочный шрифт

Вводить значки шрифтов в апплет сложнее, чем в веб, короче говоря, это занимает три шага:

  1. Загрузите iconfont, скопируйте iconfont.css в iconfont.wxss и импортируйте его в app.wxss.

  2. Просмотрите онлайн-ссылку на iconfont в режиме юникода, замените ссылку в iconfont.wxss на удаленную ссылку

  1. Введите соответствующий класс значков в файл wxml.
<icon class="iconfont icon-pay"></icon>

бесполезный

VSCode имеет легкий менее плагин, который является самым простым способом для меня использовать меньше

  1. vscode установить проще без плагина

  2. Создайте каталог less для хранения меньшего количества файлов

  3. Добавить комментарии компиляции в заголовок файла// out: ../pages/index/index.wxss, compress: true, sourceMap: false

  4. ctrl+s автоматически компилируется после сохранения

скомпилированный результат

кнопка сброса

Кнопки в апплете мощные, и кнопки должны использоваться для многих функций, таких как всплывающее окно авторизации пользователя и вызов функций обслуживания клиентов. Стиль по умолчанию, как правило, не может удовлетворить потребности, вы можете сбросить стиль кнопки единообразно, а затем написать свой собственный стиль.

button {
  padding: 0;
  background: #fff;
  line-height: 0;
  &::after {
    border-color: transparent;
  }
}
.button-hover {
  background: #fff;
}

Поддержка асинхронного ожидания

async-await — это синтаксис ECMA2017 (ES8), на момент написания этой статьи апплет все еще не поддерживает синтаксис async-await, поэтому необходимо использовать библиотеку регенератора.

  1. Загрузите regenerator и поместите regenerator-runtime в каталог utils.

2. Представлено в util.jsimport regeneratorRuntime from './regenerator-runtime/runtime-module'

  1. Инкапсулировать wxRequest для поддержки async-await
const wxRequest = async (url, params = {}) => {
  Object.assign(params, {
    token: wx.getStorageSync('token')
  })
  // 所有的请求,header默认携带token
  let header = params.header || {
    'Content-Type': 'application/json',
    'token': params.token || ''
  }
  let data = params.data || {}
  let method = params.method || 'GET'
  // hideLoading可以控制是否显示加载状态
  if (!params.hideLoading) {
   wx.showLoading({
     title: '加载中...',
   })
  }
  let res = await new Promise((resolve, reject) => {
    wx.request({
      url: url,
      method: method,
      data: data,
      header: header,
      success: (res) => {
        if (res && res.statusCode == 200) {
          resolve(res.data)
        } else {
          reject(res)
        }
      },
      fail: (err) => {
        reject(err)
      },
      complete: (e) => {
        wx.hideLoading()
      }
    })
  })
  return res
}

export {
  wxRequest
}

Инструкции:

import regeneratorRuntime from '../../utils/regenerator-runtime/runtime-module.js'
import {
  wxRequest
} from '../../utils/util.js'

Page({
  data: {
   list:[],
   count: 0,
   page: 1,
   limit: 10
  },
  onLoad: function() {
    this.getList()
    // 请求已经结束 做其他事
  },
  getList: async function() {
    await wxRequest(app.globalData.baseUrl + '/test',{
      hideLoading: true,
      data: {
        limit: this.data.limit,
        page: this.data.page
      }
    }).then((ret) => {
      this.setData({
        list: ret.data.data,
        count: ret.data.num
      })
    })
  }
})

После инкапсуляции все равно очень интересно, еще и расширение удобное

Динамически установить значение в данных

Сценарий приложения: циклический список должен динамически изменять данные, соответствующие идентификатору в списке, в соответствии с выбранным элементом.

// 动态传递id
<block wx:for="{{list}}" wx:key="{{index}}">
  <view catch:tap="onChangeName" data-id="{{item.id}}"></view>
</block>

Page({
  data: {
    list:[{
      id: 0,
      name: 'wang'
    },{
      id: 1,
      name: 'li'
    }]
  },
  onChangeName: function(event){
    // 拿到id
   let id = event.target.dataset.id
   let key = `list[${id}].name`, val = 'zhang'
   // 设置值
   this.setData({
    [key]: val
   })
  }
})

гибкий макет, многоточие переполнения не работает

Список заказов обычно представляет собой изображение слева и название или описание справа. В это время ширина изображения фиксирована, а длина заголовка является адаптивной.

.wrap {
  display: flex;
}
.sub {
  flex: 1;
  width: 0; // 宽度设为0
}
.sub text {
  display: block; // 一定要设置成block
}

<view calss="wrap">
  <image src="i.png"/>
  <view class="sub">
    <text>一段文本一段文本一段文本一段文本一段文本一段文本</text>
    <view>其他</view>
  </view>
</view>

доставка событий компонента

Задача: Родительский компонент передает исходные данные дочернему компоненту.Когда дочерний компонент щелкает, triggerEvent может настроить событие.Родительский компонент выполняет пользовательское событие, повторно запрашивает данные и передает их дочернему компоненту.

/* 子组件 */
<view>
  <view bind:tap="setId" data-id="1"></view>
</view>

properties: {
  list: {
    type: Array,
    default: []
  }
},

methods: {
  setId(e) {
    let id = e.currentTarget.dataset.id
    this.triggerEvent('deleteFav', id)
  }
}

/* 父页面 */
<child bind:customEvent="deleteFav"></child>

data: {
  list: []
},
deleteFav(e) {
  let id = e.detail // 获取传递过来的数据
  // 根据id请求数据,然后重新setData
  let newData = [1,2,3]
  this.setData({
    list: newData
  })
}

Парсинг HTML с помощью wxParse

  1. скачатьwxParse, поместите его в каталог utils
  2. Представьте на странице JS:import WxParse from '../../utils/wxParse/wxParse'
Page({
  data:{
    contentHTML:'' // 解析后的HTML
  },
  onLoad: function() {
    // 请求到的HTML数据
    let content = '<div>我是HTML代码</div>', that = this;
    WxParse.wxParse('contentHTML', 'html', content, that, 0);
  }
})

  1. Показать проанализированный контент
<import src="../../utils/wxParse/wxParse.wxml"/>
<view>
  <!-- 显示内容 -->
  <template is="wxParse" data="{{wxParseData:contentHTML.nodes}}" />
</view>

Изображение в равных пропорциях

Тег изображения имеет атрибут режима, который может установить способ отображения изображения.Если документ не внимательно прочитан, его действительно легко найти.

<image src="test.png" mode="widthFix"/>

Подтяните, чтобы загрузить и потянуть вниз, чтобы обновить

{
  "onReachBottomDistance": 0,
  "enablePullDownRefresh": true
}
data: {
  limit: 30,
  page: 1,
  list:[],
  count:0
},
// 下拉
onPullDownRefresh: function () {
  this.setData({
    page: 1,
    list:[]
  })
  this.getData()
  wx.stopPullDownRefresh()
},
// 上拉
onReachBottom: function () {
  if(this.data.list.length >= this.data.count) {
    return false
  }
  this.setData({
    page: this.data.page + 1
  })
  this.getData()
},
getData: async function () {
  await wxRequest(app.globalData.baseUrl + '/test', {
    data: {
      page: this.data.page,
      limit: this.data.limit,
    }
  }).then((ret) => {
    let list = this.data.list.concat(ret.data.list)
    this.setData({
      list: list,
      count: ret.data.count
    })
  })
}

загрузить изображение

Задача: Апплет загружает изображения на сервер, до трех изображений, а интерфейс может удалять изображения.

Схема эффекта выглядит следующим образом

Используются два API: wx.uploadFile wx.chooseImage

Пример WXML:

<view class="sale after-pic">
  <block wx:for="{{imgList}}" wx:key="{{index}}">
    <view class="pic">
      <image src="{{item}}" />
      <icon type="clear" size="20" catchtap="clearImg" data-id="{{index}}"/>
    </view>
  </block>
  <image src="../../images/upload.png" catchtap="chooseImage" />
</view>
<button catchtap="onSub">提交</button>

imgList — это временный адрес изображения, возвращаемый после успешного выполнения wx.chooseImage.

Пример JS

Page({
  data: {
    imgList:[]
  },
  // 使用async await是因为图片上传是异步的
  onSub: async function() {
    // 点击提交后,开始上传图片
     let imgUrls = []
     for (let index = 0; index < this.data.imgList.length; index++) {
       await this.uploadFile(this.data.imgList[index]).then((res) => {
         // 这里要注意把res.data parse一下,默认是字符串
         let parseData = JSON.parse(res.data)
         imgUrls.push(parseData.data) // 图片地址
       })
     }
     console.log(imgUrls) // 3张图片上传成功后,执行其他操作
  },
  // 删除某张图片
  clearImg: function (params) {
    let imgList = this.data.imgList
    let id = params.currentTarget.dataset.id // 图片索引
    imgList.splice(id, 1) // 删除
    this.setData({
      imgList: imgList
    })
  },
  chooseImage: function (params) {
    wx.chooseImage({
      count: 3, // 做多3张
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: (res) => {
        // 存储临时地址
        this.setData({
          imgList: res.tempFilePaths
        })
      }
    })
  },
  uploadFile: function (filePath) {
    // 返回Promise是为了解决图片上传的异步问题
    return new Promise( (resolve, reject) => {
      wx.uploadFile({
        url: app.globalData.baseUrl + '/file/upload', // 上传地址
        filePath: filePath,
        name: 'file', // 这里的具体值,问后端人员
        formData: {},
        header: {
          "Content-Type": "multipart/form-data"
        },
        success: (res) =>{
          resolve(res.data)
        },
        fail:(err) => {
          reject(err)
        }
      })
    })
  }
})

динамический заголовок

Динамически установить заголовок при загрузке

wx.setNavigationBarTitle({
  title: '新标题'
})

Эпилог

Выше перечислены лишь некоторые проблемы, с которыми я столкнулся в процессе разработки.Если есть какие-либо ошибки, прошу покритиковать и исправить их.Спасибо за прочтение.

Blog

GitHub