Первый Mpvue Mell Program Development закончится, чтобы обобщить его

внешний интерфейс Ресурсы изображений Vue.js mpvue

     После почти двух месяцев возни, обхода и различных оптимизаций (одна ставка на X3) наконец-то будет запущен первый разработанный мной апплет (SKR SKR!)! Конечно, в первую очередь, я должен поблагодарить босса за то, что он меня не убил - потому что в начале июня, когда я впервые получил PRD мини-программы, босс спросил меня, сколько времени мне потребуется, чтобы это сделать. на это и сказали "две недели", кхм, а потом. . . До сих пор я все еще жив Удивительно, правда? ? ? Конечно, есть и время, потраченное на погоню за «бутиковыми мини-программами». Что ж, не будем нести чушь, а начнём подводить итоги~

1. Выбор рамы

Я никогда не изучал нативный апплет, не говоря уже о том, чтобы использовать его для разработки коммерческого апплета.Когда я еще работал в прежней компании, фронтенд-команда в то время поделилась mpvue, когда они упомянули решение апплета.После новой компании , технический начальник тоже упомянул mpvue, да и сам я пишу Vue больше года, и знаком с написанием Vue, и команда новой компании давно ждет апплет, и надеется чтобы как можно быстрее разложить его по полочкам, поэтому выбор mpvue для разработки еще и самый быстрый и разумный!

2. Строительство проекта

смотрелиОфициальная документация mpvue, при строительстве проекта естественно выбрали официально рекомендованныйvue-cli, смотря наПятиминутный инструктаж по запускуПосле этого используйте команду
vue init mpvue/mpvue-quickstart my-project
Был сгенерирован базовый проект, при последующей разработке конфигурация проекта практически не менялась, но добавлялся менее загрузчик.

3. Структура каталогов

В основном структура каталогов, созданная vue-cli, с добавлением некоторых папок, в основном фреймворка, используемого для взаимодействия данных с фоном.flyioПапки конфигурации файлов (папка API), а также все управление проектными даннымиvuex(папка хранения), общая структура каталогов выглядит следующим образом:

project 
└───build 
└───config 
└───dist 
└───node_modules 
└───src 
    └───api
        |    ajax.js // flyio请求与响应拦截器的配置文件
        |    config.js // 请求的配置文件
        |    index.js // 生成请求api实例文件
        |    Server.js // 项目的数据请求统一管理文件
    └───components
    └───pages
    └───store
        └───modules // vuex模块文件夹
        |    index.js // vuex处理文件
    |   App.vue
    |   config.js
    |   main.js
└───static    
    └───images
    └───lib
    └───weui
│   README.md
│   package.json  
│   package-lock.json  

4. Яма, на которую вы наступили

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

4-1. Проблема со значком tabBar

существуетНастройте собственный нижний tabBar апплетаКогда столкнулся с первой проблемой: в случае с моими значками конструктора значков указать правильный путь,Иконка tabBar в инструментах разработчика всегда будет большой и займет почти всю высоту, совсем некрасиво, перерыл кучу блогов так и не нашел решения.Пытался и сам реализовать tabBar, но увидев отвратительный эффект, сдался, вернулся к родному tabBar, а потом тихонько подумав об этом, наконец, после сравнения некоторых проектов mpvue на github, я обнаружил, что это проблема значка значка, и, наконец, успешно решил ее:То есть размер значка остается прежним, а затем вокруг остается подходящая прозрачная (?) заготовка....очень простой? Это тратит много клеток моего мозга, простите мою глупость (умственно отсталое лицо). . . Конечно, у нативной панели tabBar есть еще одна проблема:Текст заголовка tabBar будет очень близко к низу на реальной машине.,这个我没找到解决办法,除了自己实现tabBar。 . .

4-2. Проблема сохранения старых данных перед данными страницы сведений

Я думаю, что многие студенты столкнулись с этой проблемой, в основном из-за того, что экземпляр страницы не уничтожается после перехода страницы в mpvue, а заталкивается в стек страниц, поэтому старые данные будут сохранены, и я вижу, что в вопросах много людей на mpvue github, которые столкнулись с этой проблемой и продолжают обращать внимание, чего достаточно, чтобы показать, что это проблема болевой точки, которая заставит ее повлиять на пользовательский опыт апплета. . . Относительно унифицированное решение, которое я видел до сих пор, таково: когда страница (подробности) находится в режиме загрузки, инициализируйте данные, которые будут отображаться на этой странице, и сделайте новые назначения следующим образом:

<template>
    <html-text :text="htmltext"></html-text>
</template>
<script>
    import htmlText from xxxxx
    export default {
        components: {
            htmlText
        },
        data () {
            return {
                htmltext: ''
            }
        },
        onLoad () {
            this.htmltext = ''
            this.$http.get('xxxxxxxx').then((res) => {
                this.htmltext = res.htmltext
            })
        }
    }
</script>

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

4-3 Проблема в том, что созданная функция ловушки выполняется при инициализации проекта.

     Я думаю, это должен быть баг mpvue, верно? Лучше не использовать эту функцию хука случайно на странице. . .

4-4. В настоящее время поддержка mpvue для сложного форматированного текста в настоящее время имеет низкую производительность.

    这个问题不能甩锅给mpvue,对于展示“相当复杂”的富文本(内容较长,且由多张图片甚至多张动图)的需求,一般不会有很多用户会遇到,但是很不巧的是,我遇到了。 . .谁让我们致力于做一个有逼格的品牌呢?有需求了就要解决,光能展示远远不够,还得展示的优雅,目前的mpvue-wxParse На самом деле большая часть проблем решена.Также есть несколько проектов на гитхабе, которые получили сотни звезд на основе этого проекта, но эффект, который я произвел с этим проектом, довольно недоволен боссом и техническим боссом, и изображения не могут быть загружены изящно.И поскольку htmlтекст слишком длинный, перед тем, как все изображения будут проанализированы и отображены, есть долгое время пустого экрана, поэтому я, наконец, отказался от этого решения.
     затем нашел еще один на github по адресуmpvue-wxParse Улучшенный проект для сложного форматированного текста на основеmpvue-htmlParse, я попробовал немного лучше, но это было все еще далеко от требований босса.Наконец, мне пришлось форкнуть код на основе этого проекта, чтобы самому изменить его для удовлетворения потребностей босса.Наконец-то я смог пройти тест. Адрес проектаmpvue-htmlParse, этот проект в основном направлен назагрузка изображенияВнесены улучшения.После загрузки первой картинки на главную страницу может быть отправлено уведомление о том, что эффект предзагрузки можно отключить, а затем к каждой картинке добавляется эффект загрузки хризантемы.Картинка хризантемы будет отображаться до полной загрузки картинки загружается, а затем ширина экрана устройства и информация об изображении соответствующим образом увеличиваются или уменьшаются, так что общий эффект может в основном достигать эффекта твита общедоступной учетной записи WeChat «обанкротившейся версии», Сфера применения этого проекта ограничена, и студенты, которые нуждаются в этом, могут улучшить на этой основе.

4-5. Встроенные в WeChat переходы маршрутизации navigationTo(), redirectTo(), navigationBack(), switchTab(), reLaunch() и т. д. ведут себя странно на реальных машинах

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

4-6 Обратите внимание на использование onShow()

     Помните, что код js в функции хука будет выполняться не только при первом входе на страницу, но и после того, как экран выключится и снова загорится.

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

5. Использование Flyio

     При разработке апплета мы не использовали родной wx.request() апплета для взаимодействия с данными, а выбралиmpvueРекомендовано в документацииFlyio,введение Флайо много не введут,можете сами прочитать документ во время боя,здесь я в основном рассказываю оПостроение перехватчиков запросов и ответов:
На самом деле в документе есть очень подробное введение и код, но после того, как я записал его по коду, столкнувшись с проблемой неудачного входа в систему, я не решил ее так, как ожидалось: сначала заблокировать запрос, затем повторно запросить чтобы получить новый файл cookie, а затем начать снова. После обсуждения с другими я использовал обещание решить эту проблему. Конкретный код можно увидеть:
src/api/ajax.js:

/**
 * http请求拦截器
 */
const Fly = require('flyio/dist/npm/wx')
const config = require('./config')

const ajaxUrl =
  process.env.NODE_ENV === 'development'
    ? config.Host.development
    : process.env.NODE_ENV === 'production'
      ? config.Host.production
      : config.Host.test
      
let fly = new Fly()
let loginFly = new Fly()
// 定义公共headers
const headers = {
  ...
}
Object.assign(fly.config, {
  headers: headers,
  baseURL: ajaxUrl,
  timeout: 10000,
  withCredentials: true
})
loginFly.config = fly.config
// session失效后本地重新登录
const login = () => {
  return new Promise((resolve, reject) => {
    wx.login({
      success: res => {
        let loginParams = {
          ...
        }
        loginFly.post('/api/locallogin/url', loginParams).then(d => {
          if (d.headers && typeof d.headers['set-cookie'] !== 'undefined') {
            // 更新session
            wx.setStorageSync('sessionid', d.headers['set-cookie'])
          }
          resolve()
        }).catch(error => {
          log(error)
          reject(res.data)
        })
      },
      fail: res => {
        console.error(res.errMsg)
      },
      complete: res => {}
    })
  })
}
// 请求拦截器
fly.interceptors.request.use(request => {
  if (wx.getStorageSync('sessionid')) {
    request.headers.cookie = wx.getStorageSync('sessionid')
  }
  return request
})
// 响应拦截器
fly.interceptors.response.use(
  response => {
    // session已经失效,需要重新登录小程序
    if (response.data.errCode === 100009) {
      // log('session失效,根据之前存储在本地的用户信息重新请求session...')
      // 锁定响应拦截器
      fly.lock()
      return login().then(() => {
        fly.unlock()
        // log(`重新请求:path:${response.request.url},baseURL:${response.request.baseURL}`)
        return fly.request(response.request)
      }).catch(err => {
        log(err)
      })
    } else {
      return response.data.data
    }
  },
  err => {
    log('error-interceptor', err)
    if (err.status) {
      wx.showToast({
        title: '出现未知错误',
        icon: 'none',
        duration: 3000
      })
    }
  }
)
export default fly

// создать экземпляр API
src/api/index.js:

import Server from './Server.js'

class Api {
  constructor () {
    Object.assign(this, ...Array.from(arguments))
  }
}

export default new Api(Server)

6. Использование vuex

     Поскольку это мини-программа покупок в жизни, она включает в себякорзина+Выбор адресаДля более сложной логики требуется совместное использование данных во многих местах.В этом проекте vuex играет большую роль.Поскольку модулей много,если все данные записать в один файл,то это несомненно принесет огромные трудности в последующем сопровождении.Поэтому, данные каждого модуля разделены и записаны в свои файлы, так что общий процесс намного понятнее.Ниже приведен код основного файла разделенных модулей
src/api/Server.js:

/**
 * 本模块主要用于与服务端进行交互
 */
import ajax from './ajax.js'
async function requestFunction ({params}) {
    let res = await ajax.get('/request/url/', {params})
    ...
    return res.data
}
export default {
    requestFunction
}

src/store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'

import modules1 from './modules/modules1'
import modules2 from './modules/modules2'
import modules3 from './modules/modules3'
...

Vue.use(Vuex)

export default new Vuex.Store({
  // 做模块化处理,每个功能一个store.js文件,然后统一在这边引入
  modules: {
    modules1,
    modules2,
    modules3,
    ...
  }
})

src/store/modules/modules1.js:

import api from '@/api' // actions里请求用到
const state = {
    aaaa,
    ...
}
const getters = {
    aaaa (state) {
        return state.aaaa
    },
    bbbb (state, getters, rootState) {
        return getters.aaaa
    },
    ...
}
// actions里可进行异步操作
const actions = {
    async anExample ({state, getters, dispatch, commit}, {params}) {
        let res = await api.requestFunction({params})
        ...
        return res
    },
    ...
}
const mutations = {
    setStateX (state, Y) {
        state.X = Y
    },
    ...
}
export default {
  namespaced: true, // 很重要
  state,
  getters,
  actions,
  mutations
}

вызвать файл .vue
src/pages/xxx.vue

<script>
import { mapState, mapGetters } from 'vuex'
export default {
   computed: {
        // 调用getters
        ...mapGetters('modules', [
            'aaaa',
            'bbbb'
        ]) 
    },
    methods: {
        // 调用action
        funcA () {
            this.$store.dispatch('modules1/anExample', {params}).then(res => {
                ...
            })
        },
        // 调用mutation
        funcB () {
            this.$store.commit('modules1/setStateX', Y)
        }
    }
}
</script>

7. Резюме

     Давайте так много напишем для этого резюме, в основном знакомимСтруктура проекта,яма столкнулась(В проекте встречается много проблем, но когда я его писал, я вдруг почувствовал, что это не проблемы?), использование Flyio(акцент на конфигурации перехватчика), а такжеКраткое введение в vuex. На самом деле, после того, как разработка проекта была закончена, я особо об этом не думал, но много ходил в обход и делал много «бесполезной работы». Создание проекта от 0 до 1 сопряжено с большими трудностями, но это действительно заставляет людей сильно расти, а также дает мне чувство удовлетворения. Поскольку апплет является коммерческим проектом компании, а не моим личным проектом, код проекта не может быть открытым исходным кодом.Если у вас есть какие-либо вопросы, вы можете связаться со мной.Во избежание подозрений в рекламе название апплета будет здесь нет объяснений.Если вы хотите испытать это, вы можете написать мне личное сообщение, все могут исправить меня!

     Ко мне за вторым номером пришел начальник, Входящий!