The original

This is a very urgent matter (it takes two days to write a single page with video playback, picture browsing, text and text mixed arrangement list, pull up refresh, scroll refresh, etc.). At the beginning, my colleague used the traditional H5+JS+CSS method, I was worried about the progress, so I stuck to vuejs. The reason is that this is the second time vuejs has been used in a project, and the first experience was not so good, mainly because vuejs adaptation on the lower versions of Android was a real headache.

UI Component selection

Back to the first time I used Vuejs, I chose Element-UI with rich elements, but I didn’t look for other components because the elements were quite consistent with the product design. But at last, because Element-UI was mainly based on PCWeb, UI adaptation problems on mobile terminals were prominent and there were many difficulties. This time, I was more rational and chose The main mobile terminal mint-UI of Ele. me team. So far, the experience is very good.

Mint-ui usage process

Mint-ui is well maintained and easy enough to use. My basic usage flow is as follows:

  • First try out the demo on your phone and scan the link:

Check out the Mint UI one by one to see if it meets your needs and has a good idea of what it supports.

  • When used, refer to the specified demo code. The official documentation is a little lacking, but combined with the demo code, it’s more than enough. Mint-ui/Example /pages at master · ElemeFE/mint-ui · GitHub

  • If the features in Demo are not enough to support your requirements, continue to refer to the documentation, because the documentation will list all the attribute values. mint-ui documentation

  • If it is not supported, customize it.

Record several potholes during development

Rem adaptation on mobile (with Mint-UI included)

This was the first problem I encountered when building the framework. According to my previous experience, I first tried to use Px2REM-Loader to uniformly convert PX to REM. However, the problem was that using Px2REM would convert all CSS files in the project into REM, while the CSS in Mint-UI could not be converted. Since it has already been adapted, but not in REM mode, forcing a conversion of its internal CSS files will generally result in the size of all its internal elements being reduced.

So the purpose should be to write their style content to do REM conversion, so use PostCSS, the reason is postCSS with PX2REM plug-in.

Stick the vue – loader. Conf. Js:

'use strict'
const utils = require('./utils')
const config = require('.. /config')
const precss = require('precss')
const pxtorem = require('postcss-px2rem')
const autoprefixer = require('autoprefixer')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
  ? config.build.productionSourceMap
  : config.dev.cssSourceMap

module.exports = {
  loaders: utils.cssLoaders({
    sourceMap: sourceMapEnabled,
    extract: isProduction
  }),
  postcss:[
      precss(),
      autoprefixer({
          browsers: [
              'last 10 Chrome versions'.'last 5 Firefox versions'.'Safari >= 6'.'ie > 8'
          ]
      }),
      pxtorem({
          remUnit: 75 // 1/10 of the design size})].cssSourceMap: sourceMapEnabled,
  cacheBusting: config.dev.cacheBusting,
  transformToRequire: {
    video: ['src'.'poster'].source: 'src'.img: 'src'.image: 'xlink:href'}}Copy the code

Js dynamically set the fontsize of the root node to match rem adaptation response:

// px2rem
window.onresize = setHtmlFontSize
function setHtmlFontSize () {
  const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
  const htmlDom = document.getElementsByTagName('html')[0]
  htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setHtmlFontSize()
Copy the code

Horizontal scrolling requirements for picture lists

Horizontal scrolling required in requirements is something like this:

* The principle of vertical scrollability is that when the height of the webview is smaller than the height of the content, the scroll bar will appear, such as the normal infinite vertical list. Horizontal scrollability works similarly when the horizontal viewable width of a container is smaller than the width of its contents.

This is achieved by using a better Vue scroll component, better Scroll.

The template hierarchy has requirements: itemContainer -> imageWrapper -> imageItem, where itemContainer needs a fixed width and hidden scrollbar.

<div class="itemImage" ref="itemContainer">
      <! Need to support horizontal scrolling -->
      <ul ref="imageWrapper">
        <li class="image_item" :key="image.id" v-for="(image, index) in item.images" ref="imageItem">
          <img class="image" :src="image.big"/>
        </li>
      </ul>
    </div>
Copy the code
.itemImage {
  overflow: hidden;
  width: 750px;
}
Copy the code

Vue is used in the methodNextTick can be specifiedThe next timeA method that executes after DOM updates.

mounted () {
      this.$nextTick((a)= > {
        this.initImageScroll()
      })
  },
methods: {
   initImageScroll: function () {
      let width = 0
      for (let i = 0; i < this.item.images.length; i++) {
        width += this.$refs.imageItem[0].getBoundingClientRect().width
      }
      this.$refs.imageWrapper.style.width = width + 'px'
      this.$nextTick((a)= > {
        if (!this.scroll) {
          this.scroll = new BScroll(this.$refs.itemContainer, {
            startX: 0.click: true.scrollX: true.scrollY: false.eventPassthrough: 'vertical'})}else {
          this.scroll.refresh()
        }
      })
    },
}
Copy the code

Automatic rolling reset problem after route jump return

The problem is stated in the official vue – the router problem: scroll behavior | vue router only post here in vue – when the router instantiation to join the appearance of the implementation:

export default new Router({
  routes: [{path: '/'.name: 'Main'.component: Main,
      meta: {
        keepAlive: true}}, {path: '/ImagePlayer'.name: 'ImagePlayer'.component: ImagePlayer,
      meta: {
      }
    }
  ],
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      if (from.meta.keepAlive) {
        from.meta.savedPosition = document.body.scrollTop
      }
      return { x: 0.y: to.meta.savedPosition || 0}}}})Copy the code

Prevents the parent element from following when the child element floats

This requirement is actually quite common. When there is a floating layer, display content on the floating layer, and when there is a scrolling operation on the floating layer, prevent the bottom element from scrolling at the same time. My solution here is to fix it by position=fixed. * When the float appears, dynamically set the root element of the bottom element to fixed and record the current scrollY value. * When the float disappears, dynamically set the root element of the bottom element to its original value and roll back to the scrollY position.

The implementation method is as follows:

   /** * prevents bottom sliding from following when the floating layer is aroused * @param isFixed */
    stopBodyScroll: function (isFixed) {
      let bodyEl = document.getElementById('main')
      if (isFixed) {
        this.saveMainTop = window.scrollY
        bodyEl.style.position = 'fixed'
        bodyEl.style.top = -this.saveMainTop + 'px'
      } else {
        bodyEl.style.position = ' '
        bodyEl.style.top = ' '
        window.scrollTo(0.this.saveMainTop)
      }
    }
Copy the code

Loading does not disappear with mt-loadMore

This problem is caused by the document not being clear enough to call its internal child component’s onTopLoaded method at the right time. Here is how MT-LoadMore does the pull-down refresh: There are two loadMore refs in the loadtop method. The reason for this is that in my application there are two tabs, both of which have the drop-down refresh function. Note that if you use multiple MT-loadMore components within the same component, You need to mark different ref values, such as loadMore1 and loadmore2. Otherwise, when the onTopLoaded method is called, various exceptions will occur, including that the loading cannot be stopped

<! -- Drop down refresh list --><template>
<div>
 <mt-loadmore 
		:top-method="loadTop" 
		:top-loading-text="null" 
		:top-drop-text="null"
		:top-pull-text="null"
     ref="loadmore1" 
		@top-status-change="handleTopChange">
</div>
</template>
<script>
export default {
   methods: {
    /** * drop down refresh */
    loadTop: function () {
      if (this.selected === '1') {
        this.getYourData01((a)= > {
          this.$refs.loadmore1.onTopLoaded()
        })
      } else {
        this.getYourData02((a)= > {
          this.$refs.loadmore2.onTopLoaded()
        })
      }
    },
  }
}
</script>
Copy the code

At the end

Mint-ui is very handy and really highly recommended. Go to sleep, beep beep beep.