1
  • 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

  1. Install Quick App Development Tools: https://www.quickapp.cn/docCenter/IDEPublicity
  2. New quick application project

  1. code structure

  1. Development and debugging

  1. Compile, package and submit for testing

  1. 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, use prompt.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

  1. 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
    }
  }
}
  1. 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('页面销毁时,不执行回调函数')
      }
    }
  }
}
  1. error page

Monitor onPageNotFound , when the page jumps abnormally, jump to the custom error page, and add a buried point to report

  1. 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

  1. 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

  1. 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
  2. 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
  3. 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.

  1. 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
  1. 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~


前端一锅煮
852 声望31 粉丝

积极阳光前端一枚,爱学习,爱分享,全栈进行中~


« 上一篇
我的前端一天