JinYazhou +

获取及反编译微信小程序wxapkg

准备工作

1、一部已经root的手机;

2、在此手机下载并安装微信6.6.1版本

3、安装root explorer;

4、运行小程序,并进入/data/data/com.tencent.mm/MicroMsg/xxx/appbrand/pkg/xx.wxapkg,拿不准可以用root explorer全部打包,打包后移动到手机内存卡可以读取的路径,或者用手机管理软件保存到电脑。

wxapkg解包

解包工具:
.Net Core 版本:https://github.com/chenrensong/SS.UnWxapkg
Python2版本:https://gist.github.com/feix/32ab8f0dfe99aa8efa84f81ed68a0f3e
Python3版本:https://gist.github.com/Integ/bcac5c21de5ea35b63b3db2c725f07ad
PHP版本:https://github.com/Clarence-pan/unpack-wxapkg
JAVA版本:https://github.com/moqi2011/unweapp
nodejs版本:https://github.com/thedreamwork/unwxapkg
Kaitai Struct版本:https://github.com/coolzilj/kaitai_struct_format_for_wxapkg

用法:SS.UnWxapkg.dll filepath

还原WXML


先处理page-frame.html:


添加wxml 输出方法:


function forwxml(raw){
    var str="";
    for(var i in raw){
        if(i=="tag"){
            if(raw[i]!="virtual"){
                str+="<"+raw[i];
            }
            if(raw["wx:for-items"]!=undefined){
                str+=" wx:for-items=\""+raw["wx:for-items"]+"\"";
            }
            if(raw["wx:key"]!=undefined){
                str+=" wx:key=\""+raw["wx:key"]+"\"";
            }
            if(raw["attr"]!=undefined){
                for(var j in raw["attr"]){
                    str+=" "+j+"=\""+raw["attr"][j]+"\"";
                }
            }
            if(raw[i]!="virtual"){
                str+=">";
            }
            if(raw["children"]!=undefined){
                
                for(var k in raw["children"]){
                    if(typeof(raw["children"][k])=="object"){
                        str+=forwxml(raw["children"][k]);
                    }else{
                        str+=raw["children"][k];
                    }
                }
            }
            if(raw[i]!="virtual"){
                str+="</"+raw[i]+">";
            }
        }
    }
    return str;
}

并修改如下方法(请留意单引号是否是半角):


function _v(k) {
          if (typeof(k) != ’undefined’) return {
            tag: ’block’,
            ’wx:for-items’: k,
            children: []
          };
          return {
            tag: ’virtual’,
            children: []
          };
        }


function _n(tag) {
          $gwxc++;
          if ($gwxc >= 16000) {
            throw ’Dom limit exceeded, please check if there\’s any mistake you\’ve made.’
          };
          return {
            tag: ’wx-’ + tag,
            attr: {},
            children: [],
            n: [],
            raw: {},
            generics: {}
          }
        }



       function $gwrt(should_pass_type_info) {
          function ArithmeticEv(ops, e, s, g, o) {
            var _f = false;
            var rop = ops[0][1];
            var _a, _b, _c, _d, _aa, _bb;
            switch (rop) {
            case ’?:’:
              _a = rev(ops[1], e, s, g, o, _f);
              _c = should_pass_type_info && (wh.hn(_a) === ’h’);
              _d = wh.rv(_a) ? rev(ops[2], e, s, g, o, _f) : rev(ops[3], e, s, g, o, _f);
              _d = _c && wh.hn(_d) === ’n’ ? wh.nh(_d, ’c’) : _d;
              //return _d;
              if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
                _a = _a.replace("{{", "").replace("}}", "");
              }
              return "{{" + _a + "?’" + rev(ops[2], e, s, g, o) + "’:’" + rev(ops[3], e, s, g, o) + "’}}";

              break;
            case ’&&’:
              _a = rev(ops[1], e, s, g, o, _f);
              _c = should_pass_type_info && (wh.hn(_a) === ’h’);
              _d = wh.rv(_a) ? rev(ops[2], e, s, g, o, _f) : wh.rv(_a);
              _d = _c && wh.hn(_d) === ’n’ ? wh.nh(_d, ’c’) : _d;
              //return _d;

              if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
                _a = _a.replace("{{", "").replace("}}", "");
              }
              _b = rev(ops[2], e, s, g, o);
              if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
                _b = _b.replace("{{", "").replace("}}", "");
              }
              return _a + "&&" + _b;

              break;
            case ’||’:
              _a = rev(ops[1], e, s, g, o, _f);
              _c = should_pass_type_info && (wh.hn(_a) === ’h’);
              _d = wh.rv(_a) ? wh.rv(_a) : rev(ops[2], e, s, g, o, _f);
              _d = _c && wh.hn(_d) === ’n’ ? wh.nh(_d, ’c’) : _d;
              //return _d;
              if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
                _a = _a.replace("{{", "").replace("}}", "");
              }
              _b = rev(ops[2], e, s, g, o);
              if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
                _b = _b.replace("{{", "").replace("}}", "");
              }
              return _a + "||" + _b;

              break;
            case ’+’:
            case ’*’:
            case ’/’:
            case ’%’:
            case ’|’:
            case ’^’:
            case ’&’:
            case ’===’:
            case ’==’:
            case ’!=’:
            case ’!==’:
            case ’>=’:
            case ’<=’:
            case ’>’:
            case ’<’:
            case ’<<’:
            case ’>>’:
              _a = rev(ops[1], e, s, g, o, _f);
              if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
                _a = _a.replace("{{", "").replace("}}", "");
              }
              _b = rev(ops[2], e, s, g, o, _f);
              if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
                _b = _b.replace("{{", "").replace("}}", "");
              }
              _c = should_pass_type_info && (wh.hn(_a) === ’h’ || wh.hn(_b) === ’h’);
              switch (rop) {
              case ’+’:
                _d = wh.rv(_a) + wh.rv(_b);
                break;
              case ’*’:
                _d = wh.rv(_a) * wh.rv(_b);
                break;
              case ’/’:
                _d = wh.rv(_a) / wh.rv(_b);
                break;
              case ’%’:
                _d = wh.rv(_a) % wh.rv(_b);
                break;
              case ’|’:
                _d = wh.rv(_a) | wh.rv(_b);
                break;
              case ’^’:
                _d = wh.rv(_a) ^ wh.rv(_b);
                break;
              case ’&’:
                _d = wh.rv(_a) & wh.rv(_b);
                break;
              case ’===’:
                _d = wh.rv(_a) === wh.rv(_b);
                break;
              case ’==’:
                _d = wh.rv(_a) == wh.rv(_b);
                break;
              case ’!=’:
                _d = wh.rv(_a) != wh.rv(_b);
                break;
              case ’!==’:
                _d = wh.rv(_a) !== wh.rv(_b);
                break;
              case ’>=’:
                _d = wh.rv(_a) >= wh.rv(_b);
                break;
              case ’<=’:
                _d = wh.rv(_a) <= wh.rv(_b);
                break;
              case ’>’:
                _d = wh.rv(_a) > wh.rv(_b);
                break;
              case ’<’:
                _d = wh.rv(_a) < wh.rv(_b);
                break;
              case ’<<’:
                _d = wh.rv(_a) << wh.rv(_b);
                break;
              case ’>>’:
                _d = wh.rv(_a) >> wh.rv(_b);
                break;
              default:
                break;
              }
              //return _c ? wh.nh( _d, "c" ) : _d;
              return "" + _a + rop + _b + "";
              break;
            case ’-’:
              _a = ops.length === 3 ? rev(ops[1], e, s, g, o, _f) : 0;
              _b = ops.length === 3 ? rev(ops[2], e, s, g, o, _f) : rev(ops[1], e, s, g, o, _f);
              _c = should_pass_type_info && (wh.hn(_a) === ’h’ || wh.hn(_b) === ’h’);
              _d = _c ? wh.rv(_a) - wh.rv(_b) : _a - _b;
              //return _c ? wh.nh( _d, "c" ) : _d;
              return "" + _a + rop + _b + "";
              break;
            case ’!’:
              _a = rev(ops[1], e, s, g, o, _f);
              if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
                _a = _a.replace("{{", "").replace("}}", "");
              }
              _c = should_pass_type_info && (wh.hn(_a) == ’h’);
              _d = !wh.rv(_a);
              //return _c ? wh.nh( _d, "c" ) : _d;
              return "" + rop + _a + "";

            case ’~’:
              _a = rev(ops[1], e, s, g, o, _f);
              if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
                _a = _a.replace("{{", "").replace("}}", "");
              }
              _c = should_pass_type_info && (wh.hn(_a) == ’h’);
              _d = ~wh.rv(_a);
              //return _c ? wh.nh( _d, "c" ) : _d;
              return "" + rop + _a + "";

            default:
              $gwn(’unrecognized op’ + rop);
            }
          }
          function rev(ops, e, s, g, o, newap) {
            var op = ops[0];
            var _f = false;
            if (typeof newap !== "undefined") o.ap = newap;
            if (typeof(op) === ’object’) {
              var vop = op[0];
              var _a, _aa, _b, _bb, _c, _d, _s, _e, _ta, _tb, _td;
              switch (vop) {
              case 2:
                return ArithmeticEv(ops, e, s, g, o);
                break;
              case 4:
                return rev(ops[1], e, s, g, o, _f);
                break;
              case 5:
                switch (ops.length) {
                case 2:
                  _a = rev(ops[1], e, s, g, o, _f);
                  return should_pass_type_info ? [_a] : [wh.rv(_a)];
                  return [_a];
                  break;
                case 1:
                  return [];
                  break;
                default:
                  _a = rev(ops[1], e, s, g, o, _f);
                  _b = rev(ops[2], e, s, g, o, _f);
                  _a.push(should_pass_type_info ? _b: wh.rv(_b));
                  return _a;
                  break;
                }
                break;
              case 6:
                _a = rev(ops[1], e, s, g, o);

                if (typeof(_a) != "boolean" && typeof(_a) != "number" && _a != "") {
                  _a = _a.replace("{{", "").replace("}}", "");
                }
                _b = rev(ops[2], e, s, g, o);
                if (typeof(_b) != "boolean" && typeof(_b) != "number" && _b != "") {
                  _b = _b.replace("{{", "").replace("}}", "");
                }
                if (typeof(_b) == "number") {
                  return "{{" + _a + "[" + _b + "]}}";
                }
                return "{{" + _a + "." + _b + "}}";

                var ap = o.ap;
                _ta = wh.hn(_a) === ’h’;
                _aa = _ta ? wh.rv(_a) : _a;
                o.is_affected |= _ta;
                if (should_pass_type_info) {
                  if (_aa === null || typeof(_aa) === ’undefined’) {
                    return _ta ? wh.nh(undefined, ’e’) : undefined;
                  }
                  _b = rev(ops[2], e, s, g, o, _f);
                  _tb = wh.hn(_b) === ’h’;
                  _bb = _tb ? wh.rv(_b) : _b;
                  o.ap = ap;
                  o.is_affected |= _tb;
                  if (_bb === null || typeof(_bb) === ’undefined’ || _bb === "__proto__" || _bb === "prototype" || _bb === "caller") {
                    return (_ta || _tb) ? wh.nh(undefined, ’e’) : undefined;
                  }
                  _d = _aa[_bb];
                  if (typeof _d === ’function’ && !ap) _d = undefined;
                  _td = wh.hn(_d) === ’h’;
                  o.is_affected |= _td;
                  return (_ta || _tb) ? (_td ? _d: wh.nh(_d, ’e’)) : _d;
                } else {
                  if (_aa === null || typeof(_aa) === ’undefined’) {
                    return undefined;
                  }
                  _b = rev(ops[2], e, s, g, o, _f);
                  _tb = wh.hn(_b) === ’h’;
                  _bb = _tb ? wh.rv(_b) : _b;
                  o.ap = ap;
                  o.is_affected |= _tb;
                  if (_bb === null || typeof(_bb) === ’undefined’ || _bb === "__proto__" || _bb === "prototype" || _bb === "caller") {
                    return undefined;
                  }
                  _d = _aa[_bb];
                  if (typeof _d === ’function’ && !ap) _d = undefined;
                  _td = wh.hn(_d) === ’h’;
                  o.is_affected |= _td;
                  return _td ? wh.rv(_d) : _d;
                }
              case 7:
                switch (ops[1][0]) {
                case 11:
                  o.is_affected |= wh.hn(g) === ’h’;
                  return g;
                case 3:
                  _s = wh.rv(s);
                  _e = wh.rv(e);
                  _b = ops[1][1];
                  if (g && g.f && g.f.hasOwnProperty(_b)) {
                    _a = g.f;
                    o.ap = true;
                  } else {
                    _a = _s && _s.hasOwnProperty(_b) ? s: (_e && _e.hasOwnProperty(_b) ? e: undefined);
                  }
                  if (should_pass_type_info) {
                    if (_a) {
                      _ta = wh.hn(_a) === ’h’;
                      _aa = _ta ? wh.rv(_a) : _a;
                      _d = _aa[_b];
                      _td = wh.hn(_d) === ’h’;
                      o.is_affected |= _ta || _td;
                      _d = _ta && !_td ? wh.nh(_d, ’e’) : _d;
                      return _d;
                    }
                  } else {
                    if (_a) {
                      _ta = wh.hn(_a) === ’h’;
                      _aa = _ta ? wh.rv(_a) : _a;
                      _d = _aa[_b];
                      _td = wh.hn(_d) === ’h’;
                      o.is_affected |= _ta || _td;
                      //return wh.rv(_d);
                      if (!new RegExp("{{").test(_d)) {
                        return "" + _d + "";
                      }
                      return "" + ops[1][1] + "";

                    }
                  }
                  //return undefined;
                  return "{{" + ops[1][1] + "}}";
                }
                break;
              case 8:
                _a = {};
                _a[ops[1]] = rev(ops[2], e, s, g, o, _f);
                return _a;
                break;
              case 9:
                _a = rev(ops[1], e, s, g, o, _f);
                _b = rev(ops[2], e, s, g, o, _f);
                function merge(_a, _b, _ow) {
                  var ka, _bbk;
                  _ta = wh.hn(_a) === ’h’;
                  _tb = wh.hn(_b) === ’h’;
                  _aa = wh.rv(_a);
                  _bb = wh.rv(_b);
                  for (var k in _bb) {
                    if (_ow || !_aa.hasOwnProperty(k)) {
                      _aa[k] = should_pass_type_info ? (_tb ? wh.nh(_bb[k], ’e’) : _bb[k]) : wh.rv(_bb[k]);
                    }
                  }
                  return _a;
                }
                var _c = _a
                var _ow = true
                if (typeof(ops[1][0]) === "object" && ops[1][0][0] === 10) {
                  _a = _b _b = _c _ow = false
                }
                if (typeof(ops[1][0]) === "object" && ops[1][0][0] === 10) {
                  var _r = {}
                  return merge(merge(_r, _a, _ow), _b, _ow);
                } else return merge(_a, _b, _ow);
                break;
              case 10:
                _a = rev(ops[1], e, s, g, o, _f);
                _a = should_pass_type_info ? _a: wh.rv(_a);
                return _a;
                break;
              case 125:
                var _r;
                _a = rev(ops[1], e, s, g, o);
                if (!o.ap) {
                  return should_pass_type_info && wh.hn(_a) === ’h’ ? wh.nh(_r, ’f’) : _r;
                }
                var ap = o.ap;
                _b = rev(ops[2], e, s, g, o, _f);
                o.ap = ap;
                _ta = wh.hn(_a) === ’h’;
                _tb = _ca(_b);
                _aa = wh.rv(_a);
                _bb = wh.rv(_b);
                snap_bb = $gdc(_bb, "nv_");
                try {
                  _r = typeof _aa === "function" ? $gdc(_aa.apply(null, snap_bb)) : undefined;
                } catch(e) {
                  e.message = e.message.replace(/nv_/g, "");
                  e.stack = e.stack.substring(0, e.stack.indexOf("\n", e.stack.lastIndexOf("at nv_")));
                  e.stack = e.stack.replace(/\snv_/g, " ");
                  e.stack = $gstack(e.stack);
                  if ("undefined" !== typeof debugInfo) e.stack += "\n " + " " + " " + " at " + debugInfo[g.opindex][0] + ":" + debugInfo[g.opindex][1] + ":" + debugInfo[g.opindex][2];
                  throw e;
                }
                return should_pass_type_info && (_tb || _ta) ? wh.nh(_r, ’f’) : _r;
              }
            } else {
              if (op === 3 || op === 1) return ops[1];
              else if (op === 11) {
                var _a = ’’;
                for (var i = 1; i < ops.length; i++) {
                  var xp = wh.rv(rev(ops[i], e, s, g, o, _f));
                  _a += typeof(xp) === ’undefined’ ? ’’: xp;
                }
                return _a;
              }
            }
          }
          return rev;
        }
        gra = $gwrt(true);
        grb = $gwrt(false);
        function TestTest(expr, ops, e, s, g, expect_a, expect_b, expect_affected) {
          {
            var o = {
              is_affected: false
            };
            var a = gra(ops, e, s, g, o);
            if (JSON.stringify(a) != JSON.stringify(expect_a) || o.is_affected != expect_affected) {
              console.warn("A. " + expr + " get result " + JSON.stringify(a) + ", " + o.is_affected + ", but " + JSON.stringify(expect_a) + ", " + expect_affected + " is expected");
            }
          } {
            var o = {
              is_affected: false
            };
            var a = grb(ops, e, s, g, o);
            if (JSON.stringify(a) != JSON.stringify(expect_b) || o.is_affected != expect_affected) {
              console.warn("B. " + expr + " get result " + JSON.stringify(a) + ", " + o.is_affected + ", but " + JSON.stringify(expect_b) + ", " + expect_affected + " is expected");
            }
          }
        }

        function wfor(to_iter, func, env, _s, global, father, itemname, indexname, keyname) {
          console.info(itemname);
          var _n = wh.hn(to_iter) === ’n’;
          var scope = wh.rv(_s);
          var has_old_item = scope.hasOwnProperty(itemname);
          var has_old_index = scope.hasOwnProperty(indexname);
          var old_item = scope[itemname];
          var old_index = scope[indexname];
          var full = Object.prototype.toString.call(wh.rv(to_iter));
          var type = full[8];
          if (type === ’N’ && full[10] === ’l’) type = ’X’;
          var _y;
          if (_n) {
            if (type === ’A’) {
              var r_iter_item;
              for (var i = 0; i < to_iter.length; i++) {
                scope[itemname] = to_iter[i];
                scope[indexname] = _n ? i: wh.nh(i, ’h’);
                r_iter_item = wh.rv(to_iter[i]);
                var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
                _y = _v(key);
                _(father, _y);
                func(env, scope, _y, global);
              }
            } else if (type === ’O’) {
              var i = 0;
              var r_iter_item;
              for (var k in to_iter) {
                scope[itemname] = to_iter[k];
                scope[indexname] = _n ? k: wh.nh(k, ’h’);
                r_iter_item = wh.rv(to_iter[k]);
                var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
                _y = _v(key);
                _(father, _y);
                func(env, scope, _y, global);
                i++;
              }
            } else if (type === ’S’) {
              for (var i = 0; i < 1; i++) {
                scope[itemname] = to_iter;
                scope[indexname] = _n ? i: wh.nh(i, ’h’);
                _y = _v(to_iter);
                _y["wx:key"] = keyname _(father, _y);
                func(env, scope, _y, global);
              }
            } else if (type === ’N’) {
              for (var i = 0; i < to_iter; i++) {
                scope[itemname] = i;
                scope[indexname] = _n ? i: wh.nh(i, ’h’);
                _y = _v(i);
                _(father, _y);
                func(env, scope, _y, global);
              }
            } else {}
          } else {
            var r_to_iter = wh.rv(to_iter);
            var r_iter_item, iter_item;
            if (type === ’A’) {
              for (var i = 0; i < r_to_iter.length; i++) {
                iter_item = r_to_iter[i];
                iter_item = wh.hn(iter_item) === ’n’ ? wh.nh(iter_item, ’h’) : iter_item;
                r_iter_item = wh.rv(iter_item);
                scope[itemname] = iter_item scope[indexname] = _n ? i: wh.nh(i, ’h’);
                var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
                _y = _v(key);
                _(father, _y);
                func(env, scope, _y, global);
              }
            } else if (type === ’O’) {
              var i = 0;
              for (var k in r_to_iter) {
                iter_item = r_to_iter[k];
                iter_item = wh.hn(iter_item) === ’n’ ? wh.nh(iter_item, ’h’) : iter_item;
                r_iter_item = wh.rv(iter_item);
                scope[itemname] = iter_item;
                scope[indexname] = _n ? k: wh.nh(k, ’h’);
                var key = keyname && r_iter_item ? (keyname === "*this" ? r_iter_item: wh.rv(r_iter_item[keyname])) : undefined;
                _y = _v(key);
                _(father, _y);
                func(env, scope, _y, global);
                i++
              }
            } else if (type === ’S’) {
              for (var i = 0; i < r_to_iter.length; i++) {
                iter_item = wh.nh(r_to_iter[i], ’h’);
                scope[itemname] = iter_item;
                scope[indexname] = _n ? i: wh.nh(i, ’h’);
                _y = _v(to_iter[i] + i);
                _(father, _y);
                func(env, scope, _y, global);
              }
            } else if (type === ’N’) {
              for (var i = 0; i < r_to_iter; i++) {
                iter_item = wh.nh(i, ’h’);
                scope[itemname] = iter_item;
                scope[indexname] = _n ? i: wh.nh(i, ’h’);
                _y = _v(i);
                _(father, _y);
                func(env, scope, _y, global);
              }
            } else {}
          }
          if (has_old_item) {
            scope[itemname] = old_item;
          } else {
            delete scope[itemname];
          }
          if (has_old_index) {
            scope[indexname] = old_index;
          } else {
            delete scope[indexname];
          }
        }
       if (path && e_[path]) {
          window.__wxml_comp_version__ = 0.02
          return function(env, dd, global) {
            $gwxc = 0;
            var root = {
              "tag": "wx-page"
            };
            root.children = []
            var main = e_[path].f
            if (typeof global === "undefined") global = {};
            global.f = $gdc(f_[path], "", 1);
            if (typeof(window.__webview_engine_version__) != ’undefined’ && window.__webview_engine_version__ + 1e-6 >= 0.02 + 1e-6 && window.__mergeData__) {
              env = window.__mergeData__(env, dd);
            }
            try {
              main(env, {},
              root, global);
              if (typeof(window.__webview_engine_version__) == ’undefined’ || window.__webview_engine_version__ + 1e-6 < 0.01 + 1e-6) {
                console.log(forwxml(_ev(root)));
                return _ev(root);
              }
            } catch(err) {
              console.log(err)
            }
            console.log("result:" + root) return root;
          }
        }
      }
function makeup(file, suffix) {
var _n = typeof(file) === "number";
if ( _n && Ca.hasOwnProperty(file)) return "";
if ( _n ) Ca[file] = 1;
var ex = _n ? _C[file] : file;
var res="";
for (var i = ex.length - 1; i >= 0; i--) {
var content = ex[i];
if (typeof(content) === "object")
{
var op = content[0];
if ( op == 0 )
res = transformRPX(content[1]) + "px" + res;
else if ( op == 1)
res = suffix + res;
else if ( op == 2 ) 
res = makeup(content[1], suffix) + res;
}
else
res = content + res
}
console.log(res);
return res;
}

在电脑chrome中打开page-frame.html,在控制台(console)中输入要解密的页面路径:

$gwx("./pages/index/index.wxml")();

还原WXSS

在page-frame.html的makeup方法中添加log,即可输出app.wxss样式。

其他页面,把setCssToHead的内容复制到对应的xx.wxss样式文件,并稍作修改(比如:height:[0,10],改为height:10px,auto-height:true,则在wxml组件中添加相应属性)。

还原WXJS

所有页面的wxjs的代码在page-frame.html中,直接复制到对应的xx.wxjs文件即可。

最新评论