Vue.js转mpvue过程中遇到的问题及注意事项原创
金蝶云社区-honey缘木鱼
honey缘木鱼
5人赞赏了该文章 1127次浏览 未经作者许可,禁止转载编辑于2019年03月26日 14:40:08

之前用vue.js开发过一个商城项目,当初领导说只放在APP中,现在又说做个商城小程序,也不知道当初怎么想的,当初就提醒过,直接做个小程序,也可以集成在App中,也可以单独拿出来用,非不同意,现在又准备做小程序,简直了!!!没办法,作为基层员工,只能同意。


一.vue.js对比mpvue

1.网络请求

 vue.js:通常在Web开发中使用axios等ajax库来实现。


export function postHttp (url, data = {}) {

  Indicator.open({

    text: '加载中...',

    spinnerType: 'fading-circle'

  })

  return new Promise((resolve, reject) => {

    axios.post(url, data)

      .then(response => {

        if (response.data.status == 1) {

          resolve(response.data)

        } else {

          Toast(response.data.msg)

        }

        Indicator.close() // // 关闭动画

      }, (err) => {

        reject(err)

        Indicator.close()

      })

  })

}


mpvue:使用小程序的原生API wx.request等来封装请求的。


// 封装微信小程序请求

export function request (url, method, data) {

    return new Promise((resolve, reject) => {

        wx.request({

            data:data,

            method:method,

            url: url,

            success: function (res) {

                if (res.data.status === 1) {

                    resolve(res.data)

                } else {

                    reject(res.data)

                }

            },

            fail:function (err) {

                reject(err)

            }

        })

    })

}


2.页面跳转及传参方式

vue.js:官方提供了vue-router进行路由跳转及传参。

跳转及传参:

```

 this.$router.push({

        path: 'HomePages/productDetails',

        query: {

          id: id//参数

        }

   })

```

接收参数:在mounted ()方法中用this.$route.query.id即可。


mpvue:使用<a>标签和小程序原生API wx.navigateTo等来做路由。

跳转及传参:

```

 const url = '../goodsDetails/main?id='+id

  wx.navigateTo({ url })

```

导航 tabBar跳转

```

methods: {

    bindViewTap () {

      const url = '../logs/main'

      wx.switchTab({ url })

    },

}

```

接收参数: 

 通过this.$root.$mp.query 进行获取小程序在 this.$root.$mp.query.id

          console.log(this.$root.$mp)

      }


FF925632-0710-4659-8BCF-C5F7A484C30B.png


3.模板<template>中使用methods

vue.js:vue可以在模板中直接使用methods


<template>

   <div class="contain">

      <div class="price">¥{{toDecimal2(item.price)}}</div>

  </div>

</template>

methods: {


//价钱保留2位小数

toDecimal2 (x) {

  var f = parseFloat(x)

  if (isNaN(f)) {

    return false

  }

  var f = Math.round(x * 100) / 100

  var s = f.toString()

  var rs = s.indexOf('.')

  if (rs < 0) {

    rs = s.length

    s += '.'

  }

  while (s.length <= rs + 2) {

    s += '0'

  }

   return s

  }

}


mpvue:不支持使用filters过滤,应该使用 计算属性 computed转换。


<template>

   <div class="contain">

      <div class="price">¥{{toDecimal2}}</div>

  </div>

</template>

computed: {

//价钱保留2位小数

toDecimal2 () {

  var f = parseFloat(x)

  if (isNaN(f)) {

    return false

  }

  var f = Math.round(x * 100) / 100

  var s = f.toString()

  var rs = s.indexOf('.')

  if (rs < 0) {

    rs = s.length

    s += '.'

  }

  while (s.length <= rs + 2) {

    s += '0'

  }

   return s

  }

}


4.下拉刷新,下拉加载

Vue.js :在vue.js中通常是使用第三方Mint-UI来刷新和加载。

mpvue:


<template>

  <div class="content">

    homePage

  </div>

</template>


<script>

  export default {

    name: 'homePage',

    methods: {

      

    },

    onReachBottom() {

      console.log('searchScrollLower')

    },

    onPullDownRefresh() {

      console.log('PullDownRefresh');

    }

  }

</script>


5.在模板中,直接绑定一个对象到style或class属性上

vue.js:在Vue中我们可以为HTML元素的class或style绑定一个对象,并按照对象内的属性值来决定是否添加对应的属性名到HTML元素的样式名。


<template>

  <div :class="styleObj"></div>

</template>

 

<script>

export default {

  data() {

    return {

      styleObj: {

         position: 'fixed',

         bottom: 0,

         top: 0,

         left: 0,

         background: 'rgba(113, 111, 111, 0.5)',

         width: '100%'

       },

    }

  }

}

</script>


mpvue:使用计算属性computed,直接生成一串样式的字符串,绑定到class或style上。


<template>

  <div :class="classStr"></div>

</template>

 

<script>

export default {

  data() {

    return {

      styleObj: {

         position: 'fixed',

         bottom: 0,

         top: 0,

         left: 0,

         background: 'rgba(113, 111, 111, 0.5)',

         width: '100%'

       }

    }

  },

  computed: {

    classStr() {

      let arr = []

      for (let p in this. styleObj) {

        if (this. styleObj[p]) {

          arr.push(p)

        }

      }

      return arr.join(' ') 

    }

  }

}

</script>


注意事项:

(1).新添加的页面有时候不会渲染出来


因为 webpack 编译的文件使用配置的 entry决定的,新增的页面并没用添加进 entry,所以需要手动重新 npm run dev 一下。

(2).相对路径的图片不显示


解决方案: 把路径import进来,或者是把图片放在static目录下引用,然而作为css background-image引用时,只能选择引用远程图片,或者相对目录小于8k(webpck配置有关)的图片,不然编译器会报错。

(3).支持V_html标签


小程序的界面并不是基于浏览器的BOM/DOM的,所以不能动态的在界面模板里直接插入HTML片段来显示,需要用<rich-text>组件或者wxParse。在转化过程中,mpvue是支持V_html的。


<div v-html="goodDetails.introduction" class="introduction">


显示界面效果:

屏幕快照 2019-03-26 上午11.43.47.png


(4).嵌套使用V-for时,必须指定索引:key="index"

屏幕快照 2019-03-26 上午11.49.33.png


<div class="mall_item" @click="godetails(item.id)" v-for="(item,index) in results" :id="item.id" :key="index">

  </div>


(5).组件名和小程序原生标签名冲突

<loading></loading>

如果冲突,会产生很多莫名其妙的Bug,例如组件之间的传值问题。


(6).监听方式的变更

mpvue 里面无法使用@click-icon这样的监听名,可以改成驼峰式的监听名。


this.$emit('click-icon');

// 修改为:

this.$emit('clickIcon');


(7).事件绑定语法

  在mpvue中把 bindchange="eventName" 事件,需要写成 @change="eventName"


 <picker mode="date" :value="date" start="2015-09-01" end="2017-09-01" @change="bindDateChange">

    <view class="picker">

      当前选择: {{date}}   

    </view>

 </picker>


(8).项目中有v-else

在项目转化为mpvue过程中,发现有些判断条件一直不执行,原来是v-else不起作用,一直很郁闷,因为官方文档支持的呀!

屏幕快照 2019-03-26 下午2.35.09.png

总结

使用mpvue可以很好的降低开发人员的学习成本,可以很大程度上实现h5(vue.js框架)和小程序代码服用,在迁移一些vue组件到小程序上时,可能都不需要改动或者改动少量代码就可以直接使用,大大减少了开发成本。



本篇独发金蝶云社区



赞 5