Section A Mobile adaptation scheme

Vue mobile H5 adapter solution (Lib-flexible + Px2REM-loader)

  1. Px2rem-loader: Transforms CSS px into REM units, so you don’t need to calculate rem values yourself
  2. Lib-flexible: Modify the font size of the root HTML element according to the width of the device to adapt to different terminals

configuration

  • Install 1: NPM I px2REm-loader — save-dev
  • Install 2: NPM I lib-flexible –save
  • Configuration 1: import ‘lib-flexible/flexible.js’ to main.js
  • In configuration 2: vue.config.js
css: {
    loaderOptions: {
        css: {
            // options here will be passed to css-loader
        },
        postcss: {
            // options here will be passed to postcss-loader
            plugins: [require('postcss-px2rem') ({remUnit: 37.5 // 1rem is 37.5px, usually 750 according to the design. This is 375}}})]Copy the code

Note: In-line styles do not translate rem

Problems encountered during the section B project

UI library using Vant, although not used to feel the BASIC UI library is the same, very easy to use

One A drop down refresh + Load more

Take a look at the renderings firstThe whole page list of the mobile terminal is relatively simple, and the local list is a bit troublesome. The drop-down refresh + load more combination still needs to be combined with the scene to make corresponding changes, and it is not feasible to copy mechanically. (The full code is presented at the end of the article)

For example, if 20 pieces of data are used on a page, pull down to load more. Because a page swappable list has the function of loading more and pulling down to refresh, the same component is used many times on the same page, so it may affect each other

const detailGold = () = > import('./components/detail');
const detailMoney = () = > import('./components/detail');
Copy the code

(Parent component) dynamically gives the outer box height suitable for various phones

<div
class="list-content"
ref="listbox"
:style="'height:' + listheight + 'px'"
>
<detail-gold
@childMsg="childMsg"
:list="listGold"
v-if="gold"
:finishList="finishList"
></detail-gold>
<detail-money
@childMsg="childMsg"
:list="listMoney"
v-if="money"
:finishList="finishList"
></detail-money>
</div>
Copy the code
data() {
    return {
      // Dynamically fetch the page
      clientHeight: window.screen.height,
      listheight: ' '.// Subcomponents pass parameters
      listGold: [].listMoney: []./ / the next page
      lastindicateGold: ' '.lastindicateCash: ' '.// Determine the TAB switch
      gold: true.money: false./ / timer
      timer: null.// There is no data in the next request, so avoid loading all the time
      finishList: true}},created() {
    let id = this.$route.query.id;
    if (id == 1) {
      this.isactive = true;
      this.subtitle = 'Gold yield';
      this.company = '(个)';
      this.gold = true;
      this.money = false;
    } else if (id == 2) {
      this.isactive = false;
      this.subtitle = 'Cash proceeds';
      this.company = '(yuan);
      this.gold = false;
      this.money = true;
    }
    this.getData(id);
    // Dynamically get the height
    this.$nextTick(() = > {
      let top = this.$refs.listbox.offsetTop;
      this.listheight = this.clientHeight - top; })},Copy the code

Write the list as a child component

<template>
  <div class="detail" ref="detail">
    <van-pull-refresh
      ref="detailpull"
      class="pull"
      :style="'height:' + pullH + 'px'"
      v-model="refreshing"
      @refresh="onRefresh"
    >
      <van-list
        v-model="loading"
        :offset="10"
        :finished="finished"
        finished-text="There is no more."
        :error.sync="error"
        error-text="Request failed, click reload"
        @load="onLoad"
      >
        <div class="detail-box" v-for="(item, index) in list" :key="index">
          <div class="left">
            <div class="title">{{ item.title }}</div>
            <div class="time">
              {{ item.transFullTime | timeFormat("YYYY-MM-DD HH:mm:ss") }}
            </div>
          </div>
          <div class="right">
            <div class="sybol">+</div>
            <div class="number">{{ item.number }}</div>
          </div>
        </div>
      </van-list>
    </van-pull-refresh>
  </div>
</template>
Copy the code

1. The onLoad event will be triggered when you enter the page. If the onload event is triggered in the child component for the first time, it will be very slow and there will be a partial blank situation

props: {
    friendsList: Array.finishList:Boolean
},
data() {
    return {
        loading: false.finished: false.more: 0}},mounted() {
// Switch to zero
this.more = 0
},
methods: {// Load more
onLoad(refresh) {
    if (this.finishList == false && this.refreshing == false) {
    this.loading = false
    this.finished = true
    return
    }
    this.more++
    if (this.more > 1) {
    if (refresh) {
        this.$emit('childMsg', refresh)
    } else {
        this.$emit('childMsg')}},// Drop refresh
onRefresh() {
      // Clear the list data
      this.finished = false;
      // Reload the data
      // If loading is set to true, it is loaded
      this.loading = true;
      this.onLoad('refresh'); }},Copy the code

2. Slide will trigger onload event for many times, which needs to be handled in the parent component

Tip: Use timer to notice this pointing problem

childMsg(msg) {
    let that = this;
    console.log(msg)
    if(! that.timer) { that.timer =setTimeout(() = > {
        if (msg) {
        that.finishList = true
        if (that.subtitle == 'Gold yield') {
            that.listGold = []
            that.lastindicateGold = ' '
            that.getData(1)
            that.timer = null;
            return
        } else {
            that.listMoney = []
            that.lastindicateCash = ' '
            that.getData(2)
            that.timer = null;
            return}}else {
        if (that.subtitle == 'Gold yield') {
            if (that.lastindicateGold == ' ') {
            that.getData(1)}else {
            that.getData(1, that.lastindicateGold)
            }
        } else {
            if (that.lastindicateCash == ' ') {
            that.getData(2)}else {
            that.getData(2, that.lastindicateCash)
            }
        }
        }
        that.timer = null;
    }, 1000)}},Copy the code

3. If there is no data in the child component, the drop-down can only pull the local problem and obtain the height of the list. If the height of the list is smaller than that of the parent component, it can directly equal the height of the parent component to pull the full-screen dynamic list height

props: {
    friendsList: Array.finishList:Boolean
},
data() {
    return {
        loading: false.finished: false.more: 0}},methods: {onLoad(refresh) {
    this.more++
    if (this.more > 1) {
    this.$emit('childMsg')}},watch: {
    list: function (val) {
      console.log(val)
      if (this.refreshing) {
        this.refreshing = false;
        return
      }
      if (val.length < 20 || val.length % 20 > 0) {
        this.finished = true;
      }else{
        this.finished = false
      }
      this.loading = false;

    },
    // There is no data in the next request, so avoid loading all the time
    finishList: function (val) {
      if (val == false) {
        this.loading = false
        this.finished = true
      } else {
        this.loading = true
        this.finished = false
      }
      // Dynamically give the pull-down height to prevent the pull-down problem when there is no data
      this.$nextTick(() = > {
        let detailHeight = this.$refs.detail.offsetHeight;
        let pullHeight = this.$refs.detailpull.$el.offsetHeight
        console.log(detailHeight, pullHeight)
        if (pullHeight < detailHeight) {
          this.pullH = detailHeight
        }
      })
    }
  },
Copy the code

4. At this time, I feel OK. After a careful look at the effect, you will find that there are two loading effects in the pull-down

onLoad(refresh) {
      if (this.finishList == false && this.refreshing == false) {
        this.loading = false
        this.finished = true
        return
      }
      this.more++
      if (this.more > 1) {     
          this.$emit('childMsg')}},onRefresh() {
      this.$emit('childMsg'.'refresh')},Copy the code

Two B Long press to save

Use TouchStart, TouchMove, TouchEnd to achieve mobile end long press save directly with the code to speak it

<template>
  <div
    class="qrcode"
    :style="'height:' + qrheight + 'px'"
    @touchstart="gotouchstart"
    @touchmove="gotouchmove"
    @touchend="gotouchend"
  >
  </div>
</template>

<script>
export default {
  data() {
    return {
      timeOutEvent: null,}},methods: {
    gotouchstart() {
      let that = this;
      clearTimeout(that.timeOutEvent);// Clear the timer
      that.timeOutEvent = null;
      that.timeOutEvent = setTimeout(function () {
        // The chief executive decides what to do,
        
      }, 800);// Set timer here
    },
    // Release by hand, if released within 500 ms, cancel the long press event and execute the event that onclick should execute
    gotouchend() {
      let that = this;
      clearTimeout(that.timeOutEvent);
      that.timeOutEvent = null
      if(that.timeOutEvent ! =0) {
        // Write what to execute here (e.g. onclick event)}},// If the finger moves, cancel all events, indicating that the user is only moving instead of pressing
    gotouchmove(e) {
      e.preventDefault()
      let that = this;
      clearTimeout(that.timeOutEvent);// Clear the timer
      that.timeOutEvent = null}}},</script>
Copy the code

Three C save the QR code to the phone album

I really tried a lot of ways to do this. It works in the browser but not in the APP with a WebView. Why? Since webView opens pages that block all events by default, this requires android /IOS native collaboration to do the following two things

  • A WebView listens for download links to web pages.
  • Use your system’s DownloadManager to download it.

I can think of two solutions

1. Convert the image into a binary file stream and upload it to Android /IOS

data() {
    return {
        saveImgpath: require('.. /.. /.. /public/img/qrcode.png')}},image2Base64(img) {
      var canvas = document.createElement("canvas");
      let w = window.screen.width;
      let h = window.screen.height;
      canvas.width = w;
      canvas.height = h;
      var ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0.0, w, h);
      var dataURL = canvas.toDataURL("image/png");
      return dataURL;
    },
    getImgBase64(url) {/ / url is saveImgpath
      let that = this
      var base64 = "";
      var img = new Image();
      img.src = url;
      img.onload = function () {
        base64 = that.image2Base64(img);
        console.log(base64);
        // Pass to native
        that.$bridge.signalCommunication('saveImg',base64)
      }
    }
Copy the code

2. Let Android /IOS monitor the download behavior of web pages and give “access”

data() {
    return {
        saveImgpath: require('.. /.. /.. /public/img/qrcode.png')}},saveImg(Url) { / / Url is saveImgpath
    var blob = new Blob([' '] and {type: 'application/octet-stream' });
    var url = URL.createObjectURL(blob);
    var a = document.createElement('a');
    a.href = Url;
    a.download = Url.replace(/(.*\/)*([^.]+.*)/ig."$2").split("?") [0];
    var e = document.createEvent('MouseEvents');
    e.initMouseEvent('click'.true.false.window.0.0.0.0.0.false.false.false.false.0.null);
    a.dispatchEvent(e);
    URL.revokeObjectURL(url);
},
Copy the code

Section C Practical tips

1. The value to be passed to the child component in data must be typed; otherwise, the child component will report an error if it cannot accept the value

2. The lock-scroll property is enabled by default and cannot scroll any elements in the background. To scroll elements in the background, assign false to it

3. The mobile terminal prevents double-clicking the phone to enlarge the screen

* {
      margin: 0;
      padding: 0;
      -webkit-touch-callout: none;
      /** The system default menu is disabled */
      -webkit-user-select: none;
      /** WebKit browser */
      -khtml-user-select: none;
      /** Early browser */
      -moz-user-select: none;
      / * * * / firefox
      -ms-user-select: none;
      /**IE10*/
      user-select: none;
    }
input.textarea {
      -webkit-user-select: auto;
    }

Copy the code

4. Prevent the IOS double click page from sliding/sliding

<script type="text/javascript">
    var agent = navigator.userAgent.toLowerCase();
    var iLastTouch = null;
    if (agent.indexOf("iphone") > =0 || agent.indexOf("ipad") > =0) {
      document.body.addEventListener("touchend".function (event) {
        var a = new Date().getTime();
        iLastTouch = iLastTouch || a + 1;
        var c = a - iLastTouch;
        if (c < 500 && c > 0) {
          event.preventDefault();
          return false;
        }
        iLastTouch = a
      }, false);
    };
    document.documentElement.addEventListener('touchmove'.function (event) {
      if (event.touches.length > 1) { event.preventDefault(); }},false);
  </script>
Copy the code

5. Install/uninstall dependencies

NPM install module

When installed locally, dependency package information is written to package.json

Note that a common scenario in teamwork is for someone to clone your project from Github and then install the necessary dependencies via NPM install. These are dependencies and devDepencies in your package.json. Therefore, it is important to write dependent package information (required name and version) to package.json while installing locally!

NPM install module: do not write to package.json after installation

NPM install –save install to package.json

NPM install –save-dev — devDepencies in package.json (dev environment dependent)

NPM uninstall modules

What you should think about when removing a local module: Will the dependency information on package.json also be removed?

NPM uninstall module: Deletes the module, but does not delete the corresponding information left in package.json

NPM uninstall module –save Deletes the module and deletes the information left under Dependencies in package.json

NPM uninstall module –save-dev deletes the module and removes the information left in devDependencies in package.json

6. On PC and mobile terminals, only numbers are allowed

<! -- Disallow Chinese character Spaces, only numbers are allowed -->
<input
class="inp"
type="text"
v-model.trim="info.account"
placeholder="Please enter a number"
onkeyup="value=value.replace(/^(0+)|[^\d]+/g,'')"
/>
<! -- Disallow space -->
<input
class="inp"
type="text"
v-model.trim="info.name"
placeholder=""
onkeyup="this.value=this.value.replace(/\s+/g,'')"
/>
Copy the code

7. Nice scrollbar styles

.block-tips::-webkit-scrollbar {
  width: 5px;

  height: 13px;

  -webkit-border-radius: 5px;

  -moz-border-radius: 5px;

  border-radius: 5px;
}

.block-tips::-webkit-scrollbar-thumb {
  background-color: #DEDEE4;

  background-clip: padding-box;

  -webkit-border-radius: 5px;

  -moz-border-radius: 5px;

  border-radius: 5px;

  min-height: 28px;
}
Copy the code

The appendix

Section B one A drop down refresh + load more complete code

The parent component

<template>
  <div class="profit">
    <div class="profit-box">
      <div class="pro-box">
        <headers :header="headData"></headers>
        <div class="subtitle">
          <div class="sub">
            <span>{{ subtitle }}</span>
            <span class="company">{{ company }}</span>
          </div>
          <div class="number">{{ balance }}</div>
        </div>
      </div>
      <div class="content">
        <div class="list-header">
          <div class="pro" :class="{ active: gold }" @click="proClick(1)">Gold income</div>
          <div class="pro" :class="{ active: money }" @click="proClick(2)">cash</div>
        </div>
        <div
          class="list-content"
          ref="listbox"
          :style="'height:' + listheight + 'px'"
        >
          <detail-gold
            @childMsg="childMsg"
            :list="listGold"
            v-if="gold"
            :finishList="finishList"
          ></detail-gold>
          <detail-money
            @childMsg="childMsg"
            :list="listMoney"
            v-if="money"
            :finishList="finishList"
          ></detail-money>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import headers from '.. /.. /components/headers'
const detailGold = () = > import('./components/detail');
const detailMoney = () = > import('./components/detail');
import { incomeRecord } from '@/api/index.js'
export default {
  name: 'money'.components: {
    headers,
    detailGold,
    detailMoney
  },
  data() {
    return {
      headData: {
        title: 'My revenue'.other: false
      },
      isGold: false.isMoney: false.isactive: true.subtitle: 'Gold yield'.company: '(个)'.balance: ' '.clientHeight: window.screen.height,
      listheight: ' '.listGold: [].listMoney: []./ / the next page
      lastindicateGold: ' '.lastindicateCash: ' '.gold: true.money: false.timer: null.// There is no data in the next request, so avoid loading all the time
      finishList: true}},created() {
    let id = this.$route.query.id;
    if (id == 1) {
      this.isactive = true;
      this.subtitle = 'Gold yield';
      this.company = '(个)';
      this.gold = true;
      this.money = false;
    } else if (id == 2) {
      this.isactive = false;
      this.subtitle = 'Cash proceeds';
      this.company = '(yuan);
      this.gold = false;
      this.money = true;
    }
    this.getData(id);
    // Dynamically get the height
    this.$nextTick(() = > {
      let top = this.$refs.listbox.offsetTop;
      this.listheight = this.clientHeight - top; })},methods: {
    back() {
      this.$router.go(-1);// return to the previous layer
    },
    // Gold/cash switch
    proClick(id) {
      // this.getData (id);
      if (id == 1) {
        if (this.gold == true) {
          return
        }
        this.finishList = true
        this.subtitle = 'Gold yield'
        this.company = '(个)'
        this.listGold = []
        this.getData(1)
        this.gold = true
        this.money = false
      } else {
        if (this.money == true) {
          return
        }
        this.finishList = true
        this.subtitle = 'Cash proceeds'
        this.company = '(yuan)
        this.listMoney = []
        this.getData(2)
        this.gold = false
        this.money = true}},// Get data
    getData(type, lastindicate) {
      let data = {};
      data.userId = this.$global.userId;
      data.type = type;
      data.limit = 20;
      if (lastindicate) {
        data.lastindicate = lastindicate;
      }
      incomeRecord(data).then(res= > {
        if (type == 1) {
          this.balance = res.data.gold.toFixed(2);
        } else if (type == 2) {
          this.balance = res.data.balance.toFixed(2);
        }
        if (res.data.info.length == 0) {
          this.finishList = false
          return
        }
        // Gold revenue
        if (type == 1) {
          if (this.listGold.length == 0) {
            // this.balance = res.data.gold.toFixed(2);
            this.listGold = res.data.info;
            this.listGold.map((item, i) = > {
              this.listGold[i].title = this.goldType(this.listGold[i].goldType)
              this.listGold[i].number = this.listGold[i].gold
            })
          } else {
            let newArr = res.data.info
            newArr.map((item, i) = > {
              newArr[i].title = this.goldType(newArr[i].goldType)
              newArr[i].number = newArr[i].gold
            })
            for (let i = 0; i < newArr.length; i++) {
              this.listGold.push(newArr[i])
            }
          }
          this.lastindicateGold = res.data.lastindicate
        } else {
          // Cash earnings
          if (this.listMoney.length == 0) {
            this.balance = res.data.balance.toFixed(2);
            this.listMoney = res.data.info;
            this.listMoney.map((item, i) = > {
              this.listMoney[i].title = this.cashType(this.listMoney[i].cashType)
              this.listMoney[i].number = this.listMoney[i].cash
            })
          } else {
            let newArr = res.data.info
            newArr.map((item, i) = > {
              newArr[i].title = this.goldType(newArr[i].cashType)
              newArr[i].number = newArr[i].cash
            })
            for (let i = 0; i < newArr.length; i++) {
              this.listMoney.push(newArr[i])
            }
          }
          this.lastindicateCash = res.data.lastindicate
        }
      })
    },
    // Gold revenue type
    goldType(type) {
      switch (type) {
        case 1:
          return 'Gold coins for cash';

        case 2:
          return 'Friends reading Contribution';

        case 3:
          return 'Fill in the invitation code';

        case 4:
          return 'Reading content';

        case 5:
          return 'Quality content';

        case 6:
          return 'Daily Login';

        case 7:
          return 'Moments invite';

        case 8:
          return 'wechat Group Invitation';

        case 9:
          return 'Rising Star';

        case 10:
          return 'Reading Rewards';

        case 11:
          return 'Friend Contribution';

        case 12:
          return 'Friend Contribution (name of friend)'; }},// Cash income type
    cashType(type) {
      switch (type) {
        case 1:
          return 'Gold coins for cash'
        case 2:
          return 'withdrawal'
        case 3:
          return 'Invite a friend to complete a mission for the first time'
        case 4:
          return 'Inviting friends for the first time (1 yuan to your account immediately)'
        case 5:
          return 'New User Rewards'}},childMsg(msg) {
      let that = this;
      console.log(msg)
      if(! that.timer) { that.timer =setTimeout(() = > {
          if (msg) {
            that.finishList = true
            if (that.subtitle == 'Gold yield') {
              that.listGold = []
              that.lastindicateGold = ' '
              that.getData(1)
              that.timer = null;
              return
            } else {
              that.listMoney = []
              that.lastindicateCash = ' '
              that.getData(2)
              that.timer = null;
              return}}else {
            if (that.subtitle == 'Gold yield') {
              if (that.lastindicateGold == ' ') {
                that.getData(1)}else {
                that.getData(1, that.lastindicateGold)
              }
            } else {
              if (that.lastindicateCash == ' ') {
                that.getData(2)}else {
                that.getData(2, that.lastindicateCash)
              }
            }
          }
          that.timer = null;
        }, 1000)}},}}</script><! -- Add"scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.profit {
  .profit-box {
    background: #efeff5 100%;
    .pro-box {
      background-color: rgba(255.255.255.1);
      border-radius: 0px 0px 10px 10px;
      .header {
        margin-top: 52px;
        display: flex;
        position: relative;
        padding-bottom: 12px;
        color: rgba(255.255.255.0);
        font-size: 20px;
        text-align: center;
        box-shadow: 0px -1px 20px 0px rgba(245.245.245.1);
        font-family: Arial;
        .return {
          margin-left: 15px;
        }
        .text {
          width: 65px;
          height: 16px;
          color: rgba(0.0.0.1);
          font-size: 16px;
          text-align: center;
          font-family: Arial;
          font-weight: bold;
          position: absolute;
          left: 50%;
          top: -3px;
          transform: translateX(-50%);
          vertical-align: top; }}.subtitle {
        // padding-top: 12px;
        height: 90px;
        border-radius: 0px 0px 10px 10px;
        text-align: center;
        .sub {
          margin-top: 20px;
          height: 13px;
          color: rgba(0.0.0.1);
          font-size: 13px;
          text-align: center;
          font-family: Arial;
          .company {
            margin-left: 3px; }}.number {
          margin-top: 20px;
          height: 30px;
          color: rgba(255.0.0.1);
          font-size: 30px;
          text-align: center;
          font-family: Arial; }}}.content {
      background: #ffffff;
      margin-top: 10px;
      border-radius: 10px 10px 0px 0px;
      .list-header {
        border-radius: 10px 10px 0px 0px;
        height: 46px;
        border: 1px solid rgba(239.239.245.1);
        box-sizing: border-box;
        display: flex;
        align-items: center;
        .pro {
          height: 16px;
          color: rgba(144.143.143.1);
          font-size: 16px;
          text-align: center;
          font-family: Arial;
          width: 50%;
        }
        .active {
          height: 16px;
          color: rgba(255.0.0.1);
          font-size: 16px;
          text-align: center;
          font-family: Arial; }}.list-content {
        // padding: 15px 15px 30px 15px;
        // height: 566px;
        overflow: auto; }}}}</style>

Copy the code

Child components

<template>
  <div class="detail" ref="detail">
    <van-pull-refresh
      ref="detailpull"
      class="pull"
      :style="'height:' + pullH + 'px'"
      v-model="refreshing"
      @refresh="onRefresh"
    >
      <van-list
        v-model="loading"
        :offset="10"
        :finished="finished"
        finished-text="There is no more."
        :error.sync="error"
        error-text="Request failed, click reload"
        @load="onLoad"
      >
        <div class="detail-box" v-for="(item, index) in list" :key="index">
          <div class="left">
            <div class="title">{{ item.title }}</div>
            <div class="time">
              {{ item.transFullTime | timeFormat("YYYY-MM-DD HH:mm:ss") }}
            </div>
          </div>
          <div class="right">
            <div class="sybol">+</div>
            <div class="number">{{ item.number }}</div>
          </div>
        </div>
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
export default {
  props: ['list'.'finishList'].data() {
    return {
      loading: false.finished: false.error: false.more: 0.timer: null.refreshing: false.pullH: ' '}},mounted() {
    // this.listData = this.list
    this.more = 0
  },
  watch: {
    list: function (val) {
      console.log(val)
      if (this.refreshing) {
        this.refreshing = false;
        return
      }
      if (val.length < 20 || val.length % 20 > 0) {
        this.finished = true;
      }else{
        this.finished = false
      }
      this.loading = false;

    },
    // There is no data in the next request, so avoid loading all the time
    finishList: function (val) {
      if (val == false) {
        this.loading = false
        this.finished = true
      } else {
        this.loading = true
        this.finished = false
      }
      // Dynamically give the pull-down height to prevent the pull-down problem when there is no data
      this.$nextTick(() = > {
        let detailHeight = this.$refs.detail.offsetHeight;
        let pullHeight = this.$refs.detailpull.$el.offsetHeight
        console.log(detailHeight, pullHeight)
        if (pullHeight < detailHeight) {
          this.pullH = detailHeight
        }
      })
    }
  },
  methods: {
    onLoad(refresh) {
      if (this.finishList == false && this.refreshing == false) {
        this.loading = false
        this.finished = true
        return
      }
      this.more++
      if (this.more > 1) {
        this.$emit('childMsg')}},onRefresh() {
      this.$emit('childMsg'.'refresh')}}}</script>

<style  scoped lang='scss'>
.detail {
  height: 100%;
  .detail-box {
    padding: 0px 15px 0px 15px;
    display: flex;
    margin-top: 30px;
    .left {
      width: 50%;
      text-align: left;
      .title {
        height: 14px;
        color: rgba(0.0.0.1);
        font-size: 14px;
        font-family: Arial;
      }
      .time {
        margin-top: 10px;
        height: 10px;
        line-height: 17px;
        color: rgba(144.143.143.1);
        font-size: 12px;
        font-family: Arial; }}.right {
      width: 50%;
      color: rgba(255.0.0.1);
      align-items: center;
      justify-content: flex-end;
      display: flex;
      .sybol {
        width: 13px;
        height: 28px;
        font-size: 20px;
        font-family: PingFangSC-regular;
      }
      .number {
        margin-left: 5px;
        height: 28px;
        font-size: 20px;
        text-align: left;
        font-family: PingFangSC-regular; }}.active {
      color: rgba(68.139.242.1); }}.detail-box:nth-child(1) {
    margin-top: 0px;
    padding-top: 15px; }}.pull {
  background: #efeff5 ! important;
}
</style>

Copy the code

Write in the last

I am Liangcheng A, a front-end, love technology and love life.

I’m very happy to meet you.

If you want to learn more, please click here and look forward to your little ⭐⭐

  • If there are any errors in this article, please correct them in the comments section. If this article helped you, please like it and follow 😊

  • This article was first published in nuggets. Reprint is prohibited without permission 💌