Weex practice based on vue2.0 (front-end perspective)

Time:2020-1-18

Premise: during this period, several weex pages written by we in the company were reconstructed with vue2.0, and the client’s weexsdk was also updated to0.10.0Edition. This article will write about some differences between the old and new versions in the front-end perspective. Practical articles of the old version of we

weex-vue-render v 0.10.0

ios weexSDK 0.10.0

android weexSDK 0.10.0

Compiling Vue files

In the age of we, for business codetext.weWe useweex-loaderAnd web pack can be compiled easily to get the final JS needed. But in the age of Vue, we need two loaders,weex-loaderandvue-loader, for company access, we are not likely to use the official scaffolding tools, which are generally implemented by ourselves. What’s confusing here is that there’s another loader calledweex-vue-loaderIn general, this loader does not need to be called manually for developers.

In the build phase or in the dev phase, we will use theweex-loaderandvue-loaderTwo loaders.

//JS used by native side

weexWebpackConfig.module.loaders.push({
  test: /\.vue(\?[^?]+)?$/,
  loader: require.resolve('weex-loader')
})
weexWebpackConfig.output.filename = '[name].weex.min.js'
//JS used in H5

vueWebpackConfig.module.loaders.push({
  test: /\.vue(\?[^?]+)?$/,
  loader: require.resolve('vue-loader')
})
vueWebpackConfig.output.filename = '[name].min.js'

For the native side, we use the weex loader to compile the Vue file. If we detect that the file is a Vue in the weex loader, we callweex-vue-loader。 For H5, we use the official Vue loader provided by Vue to compile Vue. At the same time, we distinguish the compiled file names for easy identification.

One of the things that makes it easy for us to implement scaffolding ourselves is that we need to add a comment to let the web SDK recognize that this is Vue.

var bannerPlugin = new webpackG.BannerPlugin(
    '// { "framework": "Vue" }\n',
    { raw: true }
  )
webpackConfig.plugins.push(bannerPlugin);

Weex practice based on vue2.0 (front-end perspective)

Source: Official Documents

Source dependency management

Our business is multi page, so it is very convenient to access weex. The JS file is compiled by Vue after each page is imported.vueandweex-vue-renderAs a public resource, we introduce it uniformly. Because we need to customize some modules such as error collection in combination with the native party, we choose Vue, weex Vue render and customized modules and components as the source management, and package them into a public file for reference at H5 end.

We did the same in the era of we. See details. In the age of Vue, the general direction remains the same, and minor adjustments have been made at the entry file.

import Vue from 'vue'
window.Vue = Vue

/**
 *Register component
 * 
 */

// import TestComponent from './components/test/test.vue'
// Vue.component('test-component', TestComponent)


/**
 *Register module
 * 
 */
require('weex-vue-render')

// shopBase
import shopBase from './modules/shop-base'
window.weex.registerModule('shopBase', shopBase)

// shopModal
import shopModal from './modules/shop-modal'
window.weex.registerModule('shopModal', shopModal)

We can see that compared with the previous component and module are registered by weex, but in the age of Vue, our component will be registered by Vue. Note that here I mount Vue towindowObject, because in the business code of each page, we need to instantiate Vue in our entry JS, and we need to use Vue object.

And when registering the module, our weex is also taken from the window object,require('weex-vue-render')In this step, you will mount the weex under the window.

The specific component writing has now been completed into the writing of Vue files, and students with Vue experience can start in one second.

The specific module writing is much simpler than before. Export an object containing the module method, and then callweex.registerModuleJust register.It is worth noting that the extension of HTML5 in the new official document does not mention how to write callbacks. The rules of callbacks are the same as those of the old version. The following code snippet is an example

const shopBase = {
  isOnline: function (callbackId) {
    const sender = this.sender;
    let hostname = window.location.hostname;
    let result = false;
    if (hostname.indexOf('showjoy.com') !== -1) {
      result = true;
    }
    sender.performCallback(callbackId, {
      data: result
    })
  }

}
export default shopBase


// another js

window.weex.registerModule('shopBase', shopBase)

The transformation of viewport

This part of the content and principle are explained in a way. For those who don’t know about viewport adaptation, please read my previous article, viewport and flexible JS

Students who have developed web pages should understand thatweex-hmtl5There should be no handling of multi screen viewport adaptation in the version of weex. The framework has handed over the work of viewport adaptation to Taotaoflexible.jsREM based viewport adaptation. We need to introduce a paragraph when writing the page on H5flexible.jsScript.

Weex based on vue2.0 has abandonedflexible.jsREM adaptation, changed to750pxThe scheme for docking the viewport. We’ll see that no matter what the size of the screen,layout viewportThe values of are all 750px, so when I write CSS code, it’s the same. I write code with 750 as the full screen width. The difference is that I want to write measurement units nowpx, which is not needed in the era of we.

I went through it when I refactored the web pageweex-vue-renderTwo versions of iteration, one isv-0.2.0The other one isv-0.10.0

These two versions are rightviewportWe have also made changes to the processing of, and we are also affected by some version iterations when writing business code.

stayweex-vue-render v-0.2.0Version andWeex-html5 old weexIn the version, we don’t need to writemeta[name=viewport]Yes, the framework will automatically help us calculate the page needsviewportInformation.

weex-html5With flexible, you can adapt to multiple screens, which is needless to say.

weex-vue-render v-0.2.0The adaptation mode of is as follows:

//Author's note
//Here, the default value is 750, injected by build
const DEFAULT_VIEWPORT_WIDTH = process.env.VIEWPORT_WIDTH

function parseViewportWidth (config) {
  let width = DEFAULT_VIEWPORT_WIDTH
  if (config && config.width) {
    width = Number(config.width) || config.width
  }
  return width
}

export function setViewport (config = {}) {
  const doc = window.document

  if (doc) {
    const viewportWidth = parseViewportWidth(config)

    // set root font-size
    doc.documentElement.style.fontSize = viewportWidth / 10 + 'px'
  
  //Author's note 
  //Get the width of the current mobile screen by key sentences
    const screenWidth = window.screen.width 
    const scale = screenWidth / viewportWidth
    const contents = [
      `width=${viewportWidth}`,
      `initial-scale=${scale}`,
      `maximum-scale=${scale}`,
      `minimum-scale=${scale}`,
      `user-scalable=no`
    ]

    let meta = doc.querySelector('meta[name="viewport"]')
    if (!meta) {
      meta = doc.createElement('meta')
      meta.setAttribute('name', 'viewport')
      document.querySelector('head').appendChild(meta)
    }

    meta.setAttribute('content', contents.join(','))
  }
}
    const screenWidth = window.screen.width 

This statement is one of the key points of the adaptation script, which is intended to get the current mobile screenideal viewportIdeal viewport, most of the timewindow.screen.widthYou can get the screenideal viewportYes, but a small number of Android native browsers are getting problematic values. Under normal iPhone 6, the value of this script is:

`width=750`,
`initial-scale=0.5`,
`maximum-scale=0.5`,
`minimum-scale=0.5`,
`user-scalable=no`

But in some Android phones, the browser will get the wrong screenwidth to get the wrong initial scale, so there will be problems with the screen display. thereforeweex-vue-render v-0.10.0Version 2 modifies the implementation of this script, but the cost is that we have to add a paragraph to the HTML filemeta[name=viewport]Label.

The form of the label is:<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

This tag needs to be added, which is not reflected in the update log, but only on the official websiteexampleThe implementation of demo has been modified in, and it is tripped by this pit…

Now let’s seeweex-vue-render v-0.10.0How to get the device inideal viewportThis also explains why this tag should be added to HTML.

Weex practice based on vue2.0 (front-end perspective)

Let’s take a look at the source code modification section. Here we willwindow.screen.widthModified to becomedocument.documentElement.getBoundingClientRect().width

In plain English, the width of HTML on the current screen is obtained by<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">Labellingwidth=device-widthIt is decided that, in combination, this tag sets the width of HTML to device width, which is the width of the deviceideal viewportWidth. And that value is always right. Calculated in this wayviewportIt will be displayed in 750px width on various devices.

In addition, if we rely on source code instead ofscriptMode managementweex-vue-renderThere will be a bug in version 0.10.0 that causes us to get the value of the viewport as undefined.

Weex practice based on vue2.0 (front-end perspective)

The reason lies inweex-vue-renderOf package.json in NPM packagemainField points to"main": "src/render/vue/index.js",Source code, and the viewport related code in the source code containslet viewportWidth = process.env.VIEWPORT_WIDTHEnvironment variables, no documentation that we rely on in source codeweex-vue-renderWhen compiling, you need to give environment variablesprocess.env.VIEWPORT_WIDTH Set the value of 750. So the value of the compiled viewportwidth variable must be undefined.

You cannpm i [email protected]Check it out.

Solution one willmainThe entry points to the compiled file of weex Vue render. Method 2 can add this environment variable when we manage the source code ourselves.

0.10.0 SDK supports relative address and automatic completion

stay0.4.0The version of SDK does not support automatic completion of relative address, while our front-end students write jump route or API interface in the way of relative address when writing business logic.

For example, an API request

stream.fetch({
    method: 'GET',
    url: "/api/shop,
    type: 'json'
  }, function (response) {})

The H5 browser will automatically splice the host of the current domain name, and the native side only gets the relative address request. The native side of our company manually splices the required host domain name before the network request to complete the network request.

However, the native web SDK supports incomplete relative addresses since version 0.9.4.

Support relative URL, which will resolve real URL by bundle’s URL.

But what’s worse is that it doesn’t match our business scenario. Because the host of SDK auto completion is based on the URL of JS bundle.

For example, our JS bundle address iscdn1.xxx.com/js/weex.js, but the address of the interface that needs to be requested in the business isshop.m.xxx.com/api/getContent

The problem is that we are.vueThe interfaces written in the page are relative addresses/api/getContentIn this way, the weexsdk will convert the relative address according to the host of the bundle, which becomescdn1.xxx.com/api/getContent, causing interface request 404.

So at this time, native needs to write its own handler and adapter, rewrite their own network requests, and then register in the web SDK. This means that native needs to complete the URL before the SDK is incomplete, and does not leave the opportunity to the SDK for processing.

Issue of this problem

Summary

This is just a preliminary attempt to migrate to the Vue era, but the foundation has been laid and more services can be accessed. There are many things to consider in H5 in the future that need to be reconsidered from the perspective of weex.

This article is from Nanyang, the front-end team of Shangzhuang. If you need to discuss anything, please come to me, especially the content related to viewport.

Recommended Today

[Redis5 source code learning] analysis of the randomkey part of redis command

baiyan Command syntax Command meaning: randomly return a key from the currently selected databaseCommand format: RANDOMKEY Command actual combat: 127.0.0.1:6379> keys * 1) “kkk” 2) “key1” 127.0.0.1:6379> randomkey “key1” 127.0.0.1:6379> randomkey “kkk” Return value: random key; nil if database is empty Source code analysis Main process The processing function corresponding to the keys command is […]