- Quick application introduction
- Problems encountered and solutions
- Several development practices
- a little insight
Quick application introduction
introduce
Web page : The web page does not need to be installed, and the experience is not very good;
Native apps : Native apps have a smooth experience, but they need to be downloaded and installed from the app store, which is difficult to reach users in one step, and the installation package consumes a lot of data;
Quick application : It is deeply integrated in the mobile phone operating system, and users can directly run it on the mobile phone without downloading and installing, and can experience the application content smoothly.
Similar to the WeChat applet, the WeChat applet is nested in the WeChat app, and the quick application is nested in the mobile phone system.
The entrance is relatively complete, including: URL link, global search, application store, browser, negative screen, system desktop, PUSH, voice assistant, security center, garbage cleaning, information assistant, weather, SMS template, calendar, personalized theme, files manage...
Development Technology
The quick application adopts the front-end technology stack, which consists of basic tags, styles, js scripts, etc., and is similar to the development method of Vue.
The quick application is developed using the MVVM design pattern. The developer does not need to directly operate the addition and deletion of DOM nodes, and uses the data-driven method to complete the node update.
Develop real-time compilation and rendering, and package and generate rpk package upload platform after completion.
quick start
- Install Quick App Development Tools: https://www.quickapp.cn/docCenter/IDEPublicity
- New quick application project
- code structure
- Development and debugging
- Compile, package and submit for testing
- Upload to the developer center of the official website, submit for review and release
Problems encountered and solutions
shortcoming
Problems felt by real development experience:
- The development tool belongs to the simplified version of VS Code, which is easy to freeze and occasionally has strange problems.
- APIs are not all unified, each manufacturer has some private APIs and functions
- Official documentation is incomplete and not detailed enough
- The update iteration is slow, the basic functions are available, and the more detailed functions are not complete
- The community is not prosperous and less updated and maintained
- Due to the lack of applications and developers, there are few documents and related materials, and it is difficult to find solutions that can be used for reference when encountering problems.
Problems encountered and solutions
1. Development tools run stuck
Phenomenon: The quick application development tool will become stuck when running for a long time.
Solution: You can exit and kill the quick application development tool, and then reopen it.
2. The development tool runs an error
Phenomenon: An error is reported in the first installation, an error is reported in the development process, and an error is reported in the occasional compilation.
Solution: View the preview error message on the right => View the error message output at the bottom => onError monitoring => Code dichotomy troubleshooting => Restart the development tool => Restart the computer
illustrate:
- Regular obvious errors will be prompted by the preview on the right
- If an error is reported inside the component, the entire component will fail to render. You can view the debugger output to find the problem.
-
onError
Global monitoring, useprompt.showDialog
to pop up a global error - The exception page finds the error by half-hiding the code in turn by dichotomy
- No exception was found or
$app
,$def
, custom$config
there is no error, clear the cache and recompile, and then restart the development tool, and then restart the computer
3. Lifecycle function execution problem
Page execution order onInit => onReady => onShow
The custom component is only onInit => onReady
Phenomenon: The page that has been loaded once will only execute onShow
after returning to the page. At this time, the custom component life cycle function in the page will not be executed.
Solution: Add if
and change it to false in the page onShow
, and change it to true after 100ms, forcing the subcomponent to refresh.
4. Positioning is not supported z-index
Control level
Phenomenon: z-index
Invalid, multiple position
When positioning elements overlap each other, whoever renders later will be on the upper layer.
Solution: Use stack
component instead, stack
container sub-components are arranged in a stacked arrangement, each direct sub-component is stacked in sequence, covering the previous sub-component; controlled by code logic To be displayed at the end of the top layer to render.
5. The private auto-login api makes the preview unavailable
Phenomenon: Oppo's private automatic login api is used, and there is no error in the module, which causes the preview on the right side of the developer tool to fail, and cannot be developed and debugged in real time.
Solution: Encapsulate the login method, introduce parameters to control the debugging phase with a hard-coded login token, and do not use private login APIs.
6. Too much data in the page stack is destroyed
Phenomenon: The reading page and the detail page will generate a new page stack every time because the id is different. The number of page stacks exceeds 5, and the earliest page data cached in the memory will be destroyed. The general manifestation is that the home page will become blank, because the most Advanced is the home page.
Solution: replace router.push
with router.replace
for pages with id such as reading page and detail page; record if the number of monitoring page stacks exceeds 5, and reload the data when returning to the home page.
7. Timer Issues
Phenomenon: The execution of the function in the timer reports an error this
cannot be found, page A jumps to B, the background continues to monitor the timer of page A, and the timer is executed at the point. At this time, page A has been destroyed and an error is reported.
Solution: Add the Function
bindPage
method to bindPage
, and all timers use the following methods:
const bindPageLC = () => {
Function.prototype.bindPage = function (vmInst) {
const fn = this
return function () {
if (!vmInst) {
throw new Error('使用错误:请传递VM对象')
}
if (vmInst.$valid) {
return fn.apply(vmInst, arguments)
} else {
console.error('页面销毁时,不执行回调函数')
}
}
}
}
bindPageLC()
setTimeout(function() {
}.bindPage(this), 500)
8. Changes in system font settings cause content to be misplaced
Phenomenon: Manually modify the system font size, and the page is misplaced without adaptation. Currently, there is no relevant API to monitor the change of the system font size.
Solution: manifest.json
Turn off font size response "textSizeAdjust": "none"
.
9. The content is misplaced due to the change of the system display settings
Phenomenon: Manually modify the display size of the system, and the html elements embedded in the rich text container will become larger and dislocated. "textSizeAdjust": "none"
can only be turned off and does not respond to system font changes.
Solution: Instead of using the rich text container to embed html, use components such as --- div
and text
instead.
10. Screen adaptation
The default size of the quick application and the negative one-screen card is "designWidth": 750
, and the 750 design drawing can be used to write the style in 1:1;
If "designWidth": 1080
, the 375 graph needs to be multiplied by 3, you can define a variable in the public style, @3:3px;
;
The specific usage is: height: 156*@3;padding: 16*@3 16*@3 0;
.
11. Night adaptation
Phenomenon: Monitor the night mode and then change the outermost style to change the color. It is found that it does not work. It is necessary to change the style of each element separately to be effective.
Solution: Quick app can adapt to media query at night @media (prefers-color-scheme: dark) {}
.
manifest.json
Medium "themeMode": -1,
Follow the theme color, "forceDark": true,
Enable reverse color
Picture dark night src replacement: monitor the theme mode switch onConfigurationChanged
, get the current theme mode configuration.getThemeMode()
Component turns off inverse color individually: forcedark="false"
Custom style: adapt with media query @media (prefers-color-scheme: dark) {}
12. Reading page vertical flip mode 1.0 advertising problem
Phenomenon: Multiple advertising components for
onLoad
, binding appear
trigger loading, each component will trigger multiple times appear
event; onLoad
The callback will fire multiple times.
Solution: Add the index cache to filter out the loaded components; extract the advertisement object to the external common reference, pass the data to the advertisement component to render the data, and do the data cache filtering.
13. 2.0 Notes on Native Advertising
Loading: The outermost layer loads a new ad via if
re-rendering
Success: The returned data no longer has an ad id
Click: The advertisement exposure and click will only be triggered once, and the second click will not trigger the advertisement click report, no profit; the jump area of the trigger advertisement cannot be controlled by if
, otherwise there is no response to the click, use show
Control
Close: Use show
to close the advertisement element, not if
, so that it will not jump to the advertisement link
14. Security Audit Issues
loglevel
needs to be set to off
;
There is online behavior before agreeing to the privacy agreement: all requests are sent after agreeing to the agreement;
http
链接:对接口下发的链接全部转换成https
,接口链接支持http
https
,部分下It is still http
;
Hard coding is not allowed in the code IP
: it can be used for splicing;
storage
not allowed to store sensitive information in plain text, such as nickname, mobile phone number, etc.: available cipher.aes()
encrypted storage.
Several development practices
Platform version
Quick application coverage update, platform version can be upgraded to the latest version 1100
error handling
- JSON.parse parsing error handling
const parseJSON = () => {
const rawParse = JSON.parse
JSON.parse = (str, defaults) => {
try {
return rawParse(str)
} catch (err) {
console.error(`JSON 解析失败:${str}, ${err.stack}`)
return defaults
}
}
}
- Judge the page status by $valid, and solve the error of referencing this data in the callback function
const bindPageLC = () => {
Function.prototype.bindPage = function (vmInst) {
const fn = this
return function () {
if (!vmInst) {
throw new Error('使用错误:请传递VM对象')
}
if (vmInst.$valid) {
return fn.apply(vmInst, arguments)
} else {
console.error('页面销毁时,不执行回调函数')
}
}
}
}
- error page
Monitor onPageNotFound
, when the page jumps abnormally, jump to the custom error page, and add a buried point to report
- Global error monitoring
Monitor onError
application reports an error, it is called when the application catches an exception, and the buried point is added to report
- Back-end server interface request failure report
performance optimization
1. Mount public functions globally
global.$config
Mount public static configuration data: $config.bpImg
global.$utils
Mount pure functions and encapsulation of some system APIs: $utils.formatDate()
app.ux
The quick application method function of the mount package: this.$app.$def.login
2. Reasonable nesting of html
The html level should not exceed 28 layers, otherwise a warning will be issued; the label must be closed, otherwise no error will be reported, but the rendering judgment logic will not work, and strange bugs will appear
3. Use CSS selectors wisely
The deeper the nesting level of CSS styles, the longer a single match will take.
Avoid using the name of a component (such as text) as the last matching rule, otherwise each text component will be traversed and matched once when rendering
Match from right to left, the last style name is as unique as possible, and the number of matches is less
4. Simplify ViewModel data
The quick application will recursively define each attribute in the assigned responsive data. The fewer the number of attributes, the better.
Therefore, for array type data, you can filter out the object properties that are not needed when assigning
5. Use lazy loading
list
in the component, not in the screen list-item
can load more while sliding, complete the rendering
tabs
the component, the tab content that is not currently displayed can be rendered when the user clicks the tab (control the child nodes of the tab-content component with the if instruction)
data transfer
1. Data transfer between parent and child components
Parent component: props
<==> Child component: $emit()
Trigger bound custom event
Child component: $dispatch()
Trigger custom event <==> Parent component: $on()
Monitor custom event and pass it out
Parent component: $broadcast()
Trigger custom event <==> Child component: $on()
Monitor custom event and pass it in
2. Brother components transmit data
Write a JS that provides the ability to publish and subscribe, and then each ViewModel
introduce this JS file
Or mount it at the page level ViewModel
, and the subcomponent is referenced to the page level through $root
ViewModel
parent component
<script>
import {
createOrRetrieveInst
} from './pubsub.js'
export default {
onReady () {
// 1. 实例化:并绑定在VM上
this.pubsubModel = createOrRetrieveInst()
// 2. 订阅:其它VM也可以调用
this.pubsubModel.subscribe('count-add', function (vArg0, vArg1){ ... })
// 3. 发布:其它VM也可以调用
this.pubsubModel.publish('count-add', ['arg0', 'arg1'])
}
}
</script>
Subassembly
<script>
export default {
onReady () {
// 1. 订阅
this.$root.pubsubModel.subscribe('count-add', function (vArg0, vArg1){ ... })
// 2. 发布
this.$root.pubsubModel.publish('count-add', ['arg0', 'arg1'])
}
}
</script>
3. Data transfer across layers
app.ux
In:
onCreate() {
this.dataCache = {} // 初始化 app 缓存的数据
},
getAppData(key) { // 获取 app 缓存的数据
return this.dataCache[key]
},
setAppData(key, val) { // 设置 app 缓存的数据
this.dataCache[key] = val
},
use:
// 任意页面设置
this.$app.setAppData('adbooks', JSON.parse(JSON.stringify(adBook)))
// 任意页面获取
this.$app.getAppData('adbooks')
Quickly generate multiple quick apps
Requirement: One quick app is the main one, and multiple quick apps for skinning, image changing, and problem changing are derived.
Solution: use the command line to copy the new configuration to overwrite the existing configuration and repackage, the configuration item files manifest.json
, variables.less
, public config.js
Negative one screen card development
- The overall space of the new version of the negative one-screen card is completely customized, including logo, title, refresh rate, and it will be triggered once every time you slide to the negative one screen
onShow
- The card is loaded with system loading, you do not need to add loading, otherwise the two loadings will conflict, and the skeleton screen is used to load the intermediate state
- cache read problem
The negative one-screen card needs to read the quick application storage
cache, the package name must be the same, and the package cannot be created independently. The card should be embedded in the quick application, and then create a smart service on the management platform.
-
console
View
- Computer installation
adb
-
brew cask install android-platform-tools
-
adb logcat -c
Clear log cache information -
adb logcat -v time >./log.log
Write the log, and then find the information in the log file
- night adaptation
- Must be adapted to night mode
- Media queries are not supported
@media (prefers-color-scheme: dark) {}
- Dynamically modify the style of each component according to the obtained current question mode value
a little insight
After completing a cycle of fast application projects, compare static pages, jq, vue, react, applet, uni-app, electron and various derived component libraries
The core is still three things, html page structure, css style, js logic:
- The writing, optimization, and precautions of the html page structure are similar
- The same is true for css writing (except for react css in js writing), mastering a complete set of style writing can basically handle regular business
- js core logic is written the same way
Then you will find that the scaffolding, project structure, and usage methods of various projects are similar, and the business logic is always the most written at the end.
Here you can sort out a set of your own project development methods and then reuse them continuously: including project structure, file naming, html structure, css naming and writing, js conventional methods, api calling methods, documentation, eslint rules and other configuration items, etc. .
Take one of the points:
Frequently used message prompt pop-ups
element:
this.$message({
message: '这是一条消息提示',
type: 'info',
duration: 3000,
...
})
vant:
this.$notify({
message: '这是一条消息提示',
type: 'danger',
duration: 3000
...
})
antd:
message.success({
content: '这是一条消息提示',
duration: 3,
...
})
message.loading({
content: '这是一条消息提示',
duration: 3,
...
})
WeChat applet:
wx.showToast({
title: '成功',
icon: 'success',
duration: 1500
})
uni-app:
uni.showToast({
title: '这是一条消息提示',
icon: 'success',
duration: 1500
})
Quick application:
prompt.showToast({
message: 'message',
duration: 0
})
The basic usage and principles of these frameworks and component libraries are similar. The biggest difference lies in the naming of the api and the difference in parameters. It takes effort and memory to remember each.
This api can be repackaged here, for example, unified into $utils.showToast()
, so it is enough to always remember this one.
The functions that can be encapsulated include: various feedback pop-ups, login and logout, payment, cache storage, buried point functions, system call methods provided by each framework, etc.
Re-sealing the commonly used ones for reuse can further smooth out the differences and reduce the memory burden.
This is the end of my sharing, thank you for reading, thank you~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。