После почти двух месяцев возни, обхода и различных оптимизаций (одна ставка на 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 сопряжено с большими трудностями, но это действительно заставляет людей сильно расти, а также дает мне чувство удовлетворения. Поскольку апплет является коммерческим проектом компании, а не моим личным проектом, код проекта не может быть открытым исходным кодом.Если у вас есть какие-либо вопросы, вы можете связаться со мной.Во избежание подозрений в рекламе название апплета будет здесь нет объяснений.Если вы хотите испытать это, вы можете написать мне личное сообщение, все могут исправить меня!
Ко мне за вторым номером пришел начальник, Входящий!