Recently picked up a project, using UNIApp nvUE to develop Android and ios end + small program end, the first time to develop NVUE, for the CSS layout, or stepped on a lot of pits. Some UNIApp apis are also unavailable in NVUE. The article also includes some methods I used in the project, such as rich text parsing and App binding to wechat, for your reference.

1. Precautions

1. Nvue supports only flex

// The default layout isdisplay: flex;
flex-direction: column; // Change the horizontal part toflex-direction: row;
Copy the code

2. Class binding only supports array syntax.

<template>
  // Array writing is supported
  <text :class="[isError ? 'isError' : 'isRight']"></text>

  Object notation is not supported
  <text :class="{isError}"></text>
</template>
Copy the code

3. Only labels can set font size and color

<template>
  // You can change the font size and color
  <text class='text'>The text content</text>

  // Font size and color cannot be changed
  <view class='text'>The text content</view>
</template>

<style>
.text {
  color: red;
  font-size: 28rpx;
}
</style>
Copy the code

The box model

  • Box-sizing defaults to border-box for nvUE box models.
  • On Android, Overflow only supports Hidden;
  • On ios, Overflow supports hidden and Visible, and the default is Visible.

2. Restrictions on CSS

// Unsupported CSSmargin: auto;
display: ...;
content: ...;
animation: ...;
width: vw, %;height: the vh, %;background-image:... ; // Unsupported CSS propertiesborder-radius: percentage is invalid;Copy the code

3, multi-terminal single line/multi-line text overflow

// Text overflow@mixin line($lineNum, $width: 100%) {
  /* line */
  @if $lineNum == 1{/ / App/* #ifdef APP-PLUS */
    lines: 1; // 1Or ntext-overflow: ellipsis;
    /* #endif *// / the other side/* #ifndef APP-PLUS */
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
    width: $width;
    /* #endif */
  } @else {
    /* Multiple lines *// / App/* #ifdef APP-PLUS */
    lines: $lineNum; // 1Or ntext-overflow: ellipsis;
    /* #endif *// / the other side/* #ifndef APP-PLUS */
    overflow: hidden;
    -webkit-line-clamp: $lineNum;
    display: -webkit-box;
    text-overflow: ellipsis;
    word-wrap: break-word;
    white-space: normal ! important;
    -webkit-box-orient: vertical;
    /* #endif */}}Copy the code
/ / use
@include line(1, 400rpx); / / a single
@include line(2); / / line
Copy the code

4. Obtain the navigation bar height

// App navigation bar height
uni.getSystemInfoSync().safeArea.top + 'px'

// Applet navigation bar height
uni.getMenuButtonBoundingClientRect().top + 10 + 'px'
Copy the code

5. Bottom safety area

const safeArea = uni.getSystemInfoSync().safeArea
const paddingBottom = safeArea.bottom - safeArea.height + 'rpx'
Copy the code

6, modify the navigation bar battery, time color

// Only dark and light are supported
// #ifdef APP-PLUS
plus.navigator.setStatusBarStyle('dark')
// #endif
Copy the code

7. Transition animation

// Use the animation's CSS properties, animation time, animation transition effects, animation delay timetransition-property: transform;
transition-duration: 0.2 s;
transition-timing-function: ease;
transition-delay:0.1 s;
Copy the code

8. Border styles

border-top: 1px;
border-style: solid;
border-top-color: #eee;

// HBuilderX 3.1.0+ started to support abbreviated stylesborder-top: 1px solid #eee;
Copy the code

Uni-app API not supported in NVUE

// 1
uni.createAnimation()

// 2
uni.pageScrollTo()

// 3. Node layout interaction (cross viewer)
uni.createIntersectionObserver()
Copy the code

10. Security zone at the bottom of wechat

/* #ifndef APP-PLUS */
padding-bottom: calc(env(safe-area-inset-bottom));
/* #endif */
Copy the code

11, NVUE parsing rich text (support applets)

App-nvue and Alipay applet do not support HTML String. They only support the list of nodes, that is, Array type. HTML String should be converted to Nodes Array, which can be converted using HTML-Parser.

<template>
  <rich-text :nodes='htmlNodes'/>  
</template>

<script>
  // NvUE only supports node rendering, so convert HTML to node
  import parseHtml from './html-parse.js'
  export default {
    data () {
      return {
        htmlStr: '< H1 > My diary 
         

It's a beautiful day

for playing outside

'
.htmlNodes: [] } }, onLoad () { this.getContent() }, methods: { getContent () { // Convert HTML text to node this.htmlNodes = parseHtml(this.htmlStr) } } }
</script>
Copy the code

12. Calculate and clear the cache on the App side

cacheSetting.js

// Compute cache
export const computedCache = () = > {
  return new Promise(resolve= > {
    plus.cache.calculate((size) = > {
      let cachSize = ' '
      size = parseInt(size)
      if (size === 0) {
        cachSize = ' '
      } else if (size < 1024) {
        cachSize = size + 'B'
      } else if (size < 1048576) {
        cachSize = (size / 1024).toFixed(2) + 'KB'
      } else if (size < 1073741824) {
        cachSize = (size / 1048576).toFixed(2) + 'MB'
      } else {
        cachSize = (size / 1073741824).toFixed(2) + 'GB'
      }
      resolve(cachSize)
    })
  })
}

// Clear the cache
export const clearCache = (cb) = > {
  uni.showLoading({
    title: 'Cleaning up... '
  })
  const os = plus.os.name
  if (os === 'Android') {
    const main = plus.android.runtimeMainActivity()
    const sdRoot = main.getCacheDir()
    const files = plus.android.invoke(sdRoot, 'listFiles')
    const len = files.length
    for (let i = 0; i < len; i++) {
      const filePath = ' ' + files[i] // Did not find a proper way to get the path, so write can be converted to file path
      plus.io.resolveLocalFileSystemURL(filePath, (entry) = > {
        if (entry.isDirectory) {
          entry.removeRecursively(() = > { // Recursively delete all files and subdirectories under it
            uni.showToast({
              title: 'Cache cleanup completed'.duration: 2000
            })
            cb()
          }, (e) = > {
            console.log(e.message)
          })
        } else {
          entry.remove()
        }
      }, () = > {
        console.log('File path reading failed')}}}else { // ios
    plus.cache.clear(() = > {
      uni.showToast({
        title: 'Cache cleanup completed'.duration: 2000
      })
      cb()
    })
  }
}
Copy the code

13, multi-end 1px border

1. The new border. SCSS

// Default border color $border: #e4e7ed; / / nvue side/* add! *. Nvue page compiled to H5, app. vue style will be overwritten by uni-app view element's own border attribute, so it will be invalid. Important App side compatibility is good, directly use 0.5px to achieve thin border, do not use pseudo-element form implementation */
/* #ifdef APP-NVUE */
.border {
  border-width: 0.5 px.! important;
  border-color: $border! important; 
  border-style: solid;
}
.border-t {
  border-top-width: 0.5 px.! important; 
  border-color: $border! important; 
  border-top-style: solid;
}
.border-l {
  border-left-width: 0.5 px.! important; 
  border-color: $border! important; 
  border-left-style: solid;
}
.border-r {
  border-right-width: 0.5 px.! important; 
  border-color: $border! important; 
  border-right-style: solid;
}
.border-b {
  border-bottom-width: 0.5 px.! important; 
  border-color: $border! important; 
  border-bottom-style: solid;
}
.border-tb {
  border-top-width: 0.5 px.! important; 
  border-bottom-width: 0.5 px.! important; 
  border-color: $border! important; 
  border-top-style: solid;
  border-bottom-style: solid;
}
/* #endif *// / not nvue end/* #ifndef APP-NVUE */
.border..border-b..border-l..border-r..border-t..border-tb {
  position: relative;
}
.border-b:after,
.border-l:after,
.border-r:after,
.border-tb:after,
.border-t:after,
.border:after {
  content: ' ';
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
  box-sizing: border-box;
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
  width: 200%;
  height: 200%;
  transform: scale(0.5.0.5);
  border: 0 solid $border;
  z-index: 1;
}
.border-t:after {
  border-top-width: 1px;
}
.border-l:after {
  border-left-width: 1px;
}
.border-r:after {
  border-right-width: 1px;
}
.border-b:after {
  border-bottom-width: 1px;
}
.border-tb:after {
  border-width: 1px 0;
}
.border:after {
  border-width: 1px;
}
/* #endif */
Copy the code

2. Uni. SCSS introduction

@import './assets/style/border.scss';
Copy the code

3. Use within components

// 1. Use <template> <view class=' as the class nameborder-tb'></view>
</template>
Copy the code
// 2. Inheritance as a selector
<template>
  <view class='cell'></view>
</template>

<style lang='scss' scoped>
  .cell {
    @extend .border-tb;
  }
</style>
Copy the code

14. App users bind wechat /App wechat login

1. The manifest. Json configuration

Code 2.

appBindWx () {
  const that = this
  uni.getProvider({
    service: 'oauth'.success: (res) = > {
      // Support wechat, QQ, Weibo, etc
      if (~res.provider.indexOf('weixin')) {
        uni.login({
          provider: 'weixin'.success: ({authResult}) = > {
            // The data returned by wechat is shown in the picture below
            // Request that the interface complete the binding
          },
          fail: (res) = > {
            console.log('App wechat failed to obtain user information ', res)
          }
        })
      }
    }
  })
}
Copy the code

3. Data returned by wechat