DCloud_heavensoft
DCloud_heavensoft
  • 发布:2019-04-10 04:53
  • 更新:2019-07-31 16:21
  • 阅读:14081

微信小程序转换uni-app详细指南、小程序转uni-app转换器、wepy转uni-app

分类:uni-app

本文首先分享转换步骤和原理,文末会分享三方开发者根据本文思路制作的小程序转uni-app的转换器wepy转uni-app思路

小程序转换uni-app的步骤

微信小程序的语法,其实是vue.js语法的裁剪定制版,在数据绑定、自定义组件等很多方面都有相似之处。
以下是一个小程序源码转换步骤指南:

客户端代码转换

  1. 新建一个uni-app项目,把之前的app.js、app.wxss的代码,挪到app.vue里,分别放到script和style节点下面
    如果其中有globalData等全局变量或方法,也直接放到app.vue的script下
    export default {    
        globalData: {    
            text: 'text'    
        },    
        onLaunch: function() {    
            console.log('App Launch')    
        }  
    }    

    读取globalData或赋值的方法是getApp().globalData.text = 'test'

  2. 转换app.json为pages.json,把每个小程序page目录下的index.json(或页面名称对应的json)里的配置取出来,放到pages.json的style下
  3. pages下每个页面目录放一个vue空文件模板
  4. 把之前页面的wxss内容复制到vue文件的style中,无需改动
  5. 把之前页面的js内容复制到vue文件的script中,然后执行如下改动
    • 5.1 之前js里面的data,放到新的data return下
      之前
      Page({  
      data: {  
      show1: false  
      }  
      })  

      现在

      <script>  
      export default {  
      data() {  
          return {  
              show1: false  
          }  
      }  
      }  
      </script>  
    • 5.2 之前js里面的自定义方法,放到新的method下
      之前
      Page({  
      toggleActionSheet1() {  
      this.setData({show1: true});  
      }  
      })  

      现在

      <script>  
      export default {  
      methods: {  
          toggleActionSheet1() {  
              this.show1 = true  
          }  
      }  
      }  
      </script>  
    • 5.3 之前js里面的生命周期函数onLoad、onShow等,直接放到export default下
      之前
      Page({  
      onLoad() {  
      console.log("page load");  
      }  
      })  

      现在

      <script>  
      export default {  
      onLoad() {  
          console.log("page load");  
      }  
      }  
      </script>  
    • 5.4 setdata的处理方式
    • 方式一:从 this.setData({loading: false,areaList: response.data.data}) 改为 this.loading = false;this.areaList = response.data.data
    • 方式二:重写setdata方法,如下
      setData:function(obj){    
      let that = this;    
      let keys = [];    
      let val,data;    
      Object.keys(obj).forEach(function(key){    
       keys = key.split('.');    
       val = obj[key];    
       data = that.$data;    
       keys.forEach(function(key2,index){    
           if(index+1 == keys.length){    
               that.$set(data,key2,val);    
           }else{    
               if(!data[key2]){    
                  that.$set(data,key2,{});    
               }    
           }    
           data = data[key2];    
       })    
      });    
      }    

      以上代码出处:https://ask.dcloud.net.cn/article/35020

  6. 把之前页面的wxml内容复制到vue文件的template下的view下,然后执行如下改动
    • 属性绑定从
      attr="{{ a }}",改为 :attr="a"
      title="复选框{{ item }}" 改为 :title="'复选框' + item"
    • 事件绑定从 bind:click="toggleActionSheet1" 改为 @click="toggleActionSheet1"
    • 阻止事件冒泡 从 catch:tap="xx" 改为 @tap.native.stop="xx"
    • wx:if 改为 v-if
    • wx:for="{{ list }}" wx:key="{{ index }}" 改为`v-for="(item,index) in list"
  7. 微信小程序自定义组件处理
    之前引入的自定义组件,需要放到wxcomponents下,并在pages.json里注册。如果这里有js,并且被其他代码引入,要注意修改引用代码的路径指向。如下:
    {  
    "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages  
        {"path": "pages/dashboard/dashboard"},  
        {  
            "path": "pages/action-sheet/action-sheet",  
            "style":{  
                "navigationBarTitleText":"ActionSheet 上拉菜单",  
                "usingComponents":{ //这里单页面引入action-sheet组件  
                    "van-action-sheet": "/wxcomponents/vant/action-sheet/index"  
                }  
            }  
        }  
    ],  
    "globalStyle": {  
        "navigationBarTitleText": "Vant For Uni-app",  
        "usingComponents": { //这里给所有页面全局引入了如下组件  
            "demo-block": "/wxcomponents/vant/demo-block/index",  
            "van-button": "/wxcomponents/vant/button/index",  
            "van-cell": "/wxcomponents/vant/cell/index",  
            "van-cell-group": "/wxcomponents/vant/cell-group/index",  
            "van-icon": "/wxcomponents/vant/icon/index",  
            "van-loading": "/wxcomponents/vant/loading/index",  
            "van-toast": "/wxcomponents/vant/toast/index"  
        }  
    }  
    }  

    微信自定义组件虽然可以这样转换。但转换后只能用于微信和App。如果想用于支付宝百度头条,则需要新建swancomponents等目录,将微信自定义组件复制到这些目录,改造测试。虽然各小程序平台均支持自定义组件,但细节有差异,仍需自己测试。无论如何,H5端不支持这些自定义组件。
    比较妥善的跨端做法,是在uni-app插件市场寻找类似功能的vue组件,废弃之前的小程序自定义组件。比如把wx-charts换成ucharts、把wx-parser换成uparser。

辅助工具

贡献几个替换用的正则

str = str.replace(/bindtap/g, '@onclick');  
str = str.replace(/wx:if/g, 'v-show');  
str = str.replace(/src=\'\{\{/g, ":src='");  
str = str.replace(/wx\:key=\"\*this\"/g, ' ');  
str = str.replace(/wx\:key\=\"index\"/g, ' ');  
str = str.replace(/wx:for="{{/g, v-for= "(item,index) in ');  
str = str.replace(/bindinput/g, '@input');   

wx.是否要替换为uni.

关于js api中的wx.,不要全局替换为uni.。因为有的wx的api是微信独有的,替换为uni后,反而在微信下没法用了。

同时uni-app编译器提供了把wx.编译为不同平台的机制,所以直接使用wx.的api完全可以正常在各端运行。

所以对于老代码,替不替换不重要,不影响运行,只影响语法提示和转到定义。

但是新写的代码,还是要用uni.的api,在代码提示、转到定义方面更强大。

App端迁移,还需处理服务端相关代码

如果把微信小程序转换为uni-app,仍然用于发布微信小程序,那服务器端代码不变。

但如果要发布到App、其他小程序等平台,服务器也需要调整部分代码。比如登陆、支付、推送、定位、地图等联网服务。

uni-app在客户端侧提供了统一的代码,比如uni.login、uni.requestPayment,在不同端均可以实现登陆、支付。

但服务器端的接口不一样,比如微信的App支付和小程序支付的申请开通、服务器接口都不一样,所以配置和服务器接口仍需单独处理。

比如把小程序转换uni-app后,需要打包发布为app,则需要向微信申请app支付的资质,拿到appkey等信息,填写到uni-app工程的 manifest-app -> sdk配置 -> 微信支付 下面,然后打包才能成效(如果是离线打包,参考离线打包的文件)。同时服务器需要按照微信的App支付的接口再开发对接。

同样微信小程序里内置的定位、地图,在app上,需要单独向高德等三方服务商申请,否则无法在app里使用这些服务。

这些sdk申请方式在 manifest -> app sdk配置 下有教程链接。

其他注意

参考:这里有一个转换示例,把vant weapp的小程序演示demo,转换为uni-app工程,里面的pages下同时保留了wxml和vue,可用于对比参考。http://ext.dcloud.net.cn/plugin?id=302

如果是mpvue的小程序,转换uni-app很方面,参考文档:https://ask.dcloud.net.cn/article/34945

感谢zhangdaren开源了一个小程序到uni-app的转换器

https://github.com/zhangdaren/miniprogram-to-uniapp
对应的教程:https://ask.dcloud.net.cn/article/36037
这个转换工具的案例:https://ext.dcloud.net.cn/plugin?id=666

另附wepy转uni-app思路:https://juejin.im/post/5c877cd35188257e3b14a1bc#heading-14

14 关注 分享
萌龙 Trust 圆号 斌疯 306816224@qq.com 逐鹿实验室 DCloud_UNI_HT weliff@163.com 不能为null chipsl@qq.com skysowe gtolin@126.com heoo547627@gmail.com joelewis

要回复文章请先登录注册

375890534@qq.com

375890534@qq.com

回复 940152991@qq.com:
在app.vue里,将this.gloabalData.xxx改成this.$options.globalData.xxxx就可以使用了。
2019-07-31 16:21
940152991@qq.com

940152991@qq.com

回复 375890534@qq.com:
小程序本身是可以引用,转成uni-app后,再运行就不能引用了
2019-07-31 15:51
940152991@qq.com

940152991@qq.com

回复 375890534@qq.com:
在自定义组件引用不了globalData怎么解决
2019-07-31 15:50
375890534@qq.com

375890534@qq.com

对于globalData那里,在其他页面都是正常可以按微信的方式来调用gloabalData的,但在App.vue里,this并不能直接引用到globalData。需要改成 this.$options.globalData.xxxx = "xxxx"的方式,当然后,如果官方能直接改成微信的通用方式也未偿不可。
2019-07-29 09:16
375890534@qq.com

375890534@qq.com

回复 940152991@qq.com:
经过测试,在app.vue里使用 this.globalData.xxx = "xxxx"这种是无效的,因为this并不能直接引用到globalData。

在其他页面该怎么调用怎么调用,,但在App.vue里,需要这样赋值: this.$options.globalData.xxxx = "xxxx"
2019-07-29 09:14
375890534@qq.com

375890534@qq.com

回复 940152991@qq.com:
确实有这个问题。
2019-07-27 19:31
940152991@qq.com

940152991@qq.com

小程序的自定义组件,拿不到globalData里面的值,------这是uni-app文件,但是小程序组件我没有修改,直接复制引用的。
const app = getApp()
Component({
/**
* 组件的属性列表
*/
data: {
StatusBar: getApp().globalData.StatusBar,
CustomBar: getApp().globalData.CustomBar,
Custom: getApp().globalData.Custom
}
)}
2019-07-24 20:49
940152991@qq.com

940152991@qq.com

回复 DCloud_heavensoft:
globalData在app.vue里面的onLaunch赋的值都没有弄到globalData上,只有在其他页面上往globalData赋值才可以赋值成功。然后就是小程序自定义的组件,没有办法引用globalData的属性
2019-07-24 20:44
DCloud_heavensoft

DCloud_heavensoft (作者)

回复 940152991@qq.com:
不会。uni-app支持globalData,至于小程序组件是否转vue,看你要跨几端了。app端可以直接运行小程序组件
2019-07-24 20:02
940152991@qq.com

940152991@qq.com

小程序转uni-app,,,,小程序里面的自定义组件也要转成vue文件的格式么
2019-07-24 19:51
940152991@qq.com

940152991@qq.com

一个神坑bug,定义在App.vue里面的globalData,根本拿不到任何值,不管在哪个页面赋值过去,都存不住的,本身自己的小程序可以用globalData,但是转成uni-app后,再在微信端就用不了
2019-07-24 19:36
chenghaiqi@vip.qq.com

chenghaiqi@vip.qq.com

<template>(.*?)</template> 替换为 <template><view>\1</view></template>
2019-07-22 13:27
chenghaiqi@vip.qq.com

chenghaiqi@vip.qq.com

v-if="{{(.?)}}" 替换为: v-if="\1"
v-else-if="{{(.?)}}" 替换为: v-else-if="\1"
2019-07-22 13:26
chenghaiqi@vip.qq.com

chenghaiqi@vip.qq.com

回复 chenghaiqi@vip.qq.com:
v-if="{{(.*?)}}" 替换为: v-if="\1"
v-else-if="{{(.*?)}}" 替换为: v-else-if="\1"
2019-07-22 13:26
chenghaiqi@vip.qq.com

chenghaiqi@vip.qq.com

wx:key=".*?" 替换为: 空
2019-07-22 13:21
577816250@qq.com

577816250@qq.com

回复 577816250@qq.com:
4、v-if /v-else-if 中 {{}}需要去掉 全局替换 "{{ 为 " ,替换 }}"为" ;5 条件判断的注意双引号转单引号
2019-07-19 16:53
577816250@qq.com

577816250@qq.com

原生小程序转换器转换之后不能直接编译:1、全局替换<template>为<template><view>,</template>为</view></template>(template下只能有一个子元素) ;2、全局替换></input> 为 /> (input为单标签); 3、 全局替换 ?" 为 ?', ":" " 为':' ' (双引号内部是单引号) 。之后99%就能编译了,接下来就看控制台提示那个文件报错了
2019-07-19 15:31
375890534@qq.com

375890534@qq.com

回复 风雅:
转换工具,支持导入自定义组件,试试嘛~~
2019-07-02 21:43
375890534@qq.com

375890534@qq.com

回复 109606325@qq.com:
是不是也没有权限?试着提权试试?
2019-07-02 21:42
DCloud_heavensoft

DCloud_heavensoft (作者)

回复 风雅:
参考:http://ext.dcloud.net.cn/plugin?id=302
2019-06-30 19:28
风雅

风雅

wxcomponents组件 拷贝过去后 pages.json 注册 运行提示Emitted value instead of an instance of Error
2019-06-30 19:12
109606325@qq.com

109606325@qq.com

回复 375890534@qq.com:
在win下的cmd里面输入npm install miniprogram-to-uniapp -g提示不是内部或者外部命令
2019-06-21 21:43
109606325@qq.com

109606325@qq.com

回复 375890534@qq.com:
先安装Node.js,下载地址:https://nodejs.org/zh-cn/This
这步安装好了,提示如下
package has installed:
* Node.js v12.4.0 to /usr/local/bin/node
* npm v6.9.0 to /usr/local/bin/npm
Make sure that /usr/local/bin is in your $PATH.
然后在控制台运行npm install miniprogram-to-uniapp -g
还是爆了错误
zhangbingkundeiMac:~ zhangbingkun$ npm install miniprogram-to-uniapp -g
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
npm ERR! path /usr/local/lib/node_modules
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall access
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
npm ERR! [Error: EACCES: permission denied, access '/usr/local/lib/node_modules'] {
npm ERR! stack: "Error: EACCES: permission denied, access '/usr/local/lib/node_modules'",
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'access',
npm ERR! path: '/usr/local/lib/node_modules'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator (though this is not recommended).

npm ERR! A complete log of this run can be found in:
npm ERR! /Users/zhangbingkun/.npm/_logs/2019-06-21T13_33_58_160Z-debug.log
2019-06-21 21:39
375890534@qq.com

375890534@qq.com

回复 109606325@qq.com:
npm是node.js的命令,您需要安装node.js,下载地址是https://nodejs.org/zh-cn/,下载【长期支持版】安装即可运行npm了
2019-06-21 21:27
109606325@qq.com

109606325@qq.com

回复 375890534@qq.com:
如果是win系统呢,我在cmd里面运行npm install miniprogram-to-uniapp -g,提示不是内部或外部命令,这个npm是UNIX的系统么
2019-06-21 21:14
375890534@qq.com

375890534@qq.com

回复 109606325@qq.com:
如果是mac,请在”终端“里输入
2019-06-21 20:19
109606325@qq.com

109606325@qq.com

回复 375890534@qq.com:
这篇说在命令行输入,是指cmd里面的dos命令么,如果苹果操作系统该在哪里输入。控制台?
2019-06-20 21:47
375890534@qq.com

375890534@qq.com

回复 109606325@qq.com:
使用文档,请参考http://ask.dcloud.net.cn/article/36037
2019-06-20 15:41
2239146847@qq.com

2239146847@qq.com

回复 109606325@qq.com:
大佬有使用教程吗
2019-06-20 14:39
109606325@qq.com

109606325@qq.com

https://github.com/zhangdaren/miniprogram-to-uniapp
请问这个怎么安装使用,有详细一点的教程么
2019-06-19 06:24
DCloud_heavensoft

DCloud_heavensoft (作者)

回复 逐鹿实验室:
三方已出转换器,欢迎参考[https://github.com/zhangdaren/miniprogram-to-uniapp](https://github.com/zhangdaren/miniprogram-to-uniapp)
2019-06-17 23:33
DCloud_UNI_GSQ

DCloud_UNI_GSQ

回复 玩屎的阿拉蕾:
vue里没有globalData属性,使用API来修改globalData
2019-05-31 16:24
jeman888@qq.com

jeman888@qq.com

回复 807889091@qq.com:
不一定是index.json,官方说法有误,应该是 pages/pagea/pagea.json、pages/pageb/pageb.json对应目录下的*.json那个文件
2019-05-21 16:17
15439509@qq.com

15439509@qq.com

str = str.replace(/bindtap/g, '@onclick');
str = str.replace(/wx:if/g, 'v-show');
str = str.replace(/src=\'\{\{/g, ":src='");
str = str.replace(/wx\:key=\"\*this\"/g, ' ');
str = str.replace(/wx\:key\=\"index\"/g, ' ');
str = str.replace(/wx:for="{{/g, v-for= "(item,index) in ');
str = str.replace(/bindinput/g, '@input');


这些正则到底在HBX的哪里执行啊?一脸懵逼 ,在线等
2019-05-20 15:55
逐鹿实验室

逐鹿实验室

回复 超级大乐透:
正在埋头苦学中!
2019-05-17 09:29
超级大乐透

超级大乐透

回复 逐鹿实验室:
千差万别,自己写点代码吧
2019-05-15 10:57
807889091@qq.com

807889091@qq.com

我的小程序了找不到page目录下的index.json 只有index.js 这2个文件是一样的吗
2019-05-07 17:11
逐鹿实验室

逐鹿实验室

强烈建议官方将微信小程序转uni-app转换器整合到hbuilderX当中
2019-05-06 14:37
逐鹿实验室

逐鹿实验室

咱们官方就出一个小程序转uni-app的转换器呗,何必天天让大家跳坑啊
2019-04-25 21:45
玩屎的阿拉蕾

玩屎的阿拉蕾

请问小程序 APP.JS 里这样的写法要怎么替换到 app.vue里。


App(
Provider(store)(
{
globalData: {
emitter: null,
netcallController: null,
ENVIRONMENT_CONFIG,
PAGE_CONFIG
},
...
}
)
)
2019-04-25 11:38
1750352431@qq.com

1750352431@qq.com

模板里需要改变单引号为双引号,class='badge' 改成 calss="badge"
2019-04-23 10:21