惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
腾讯CDC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
WordPress大学
WordPress大学
Engineering at Meta
Engineering at Meta
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
宝玉的分享
宝玉的分享
阮一峰的网络日志
阮一峰的网络日志
N
Netflix TechBlog - Medium
罗磊的独立博客
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
美团技术团队
MongoDB | Blog
MongoDB | Blog
雷峰网
雷峰网
Recent Announcements
Recent Announcements
The Cloudflare Blog
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
The GitHub Blog
The GitHub Blog
博客园 - Franky
博客园 - 三生石上(FineUI控件)
T
Tenable Blog
A
Arctic Wolf
www.infosecurity-magazine.com
www.infosecurity-magazine.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V2EX - 技术
V2EX - 技术
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Threat Research - Cisco Blogs
D
Docker
Y
Y Combinator Blog
博客园 - 叶小钗
PCI Perspectives
PCI Perspectives
P
Privacy & Cybersecurity Law Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
C
CERT Recently Published Vulnerability Notes
P
Proofpoint News Feed
NISL@THU
NISL@THU
C
Cyber Attacks, Cyber Crime and Cyber Security
GbyAI
GbyAI
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
L
LangChain Blog
N
News and Events Feed by Topic
量子位

webfem

react-virtualized AutoSizer 实现原理详解 - webfem JWT技术详解:从入门到精通 - webfem 如何在电脑上调试手机网页 - webfem react-virtualized 的用法详解 - webfem MongoDB 入门详解 - webfem react-virtualized 无限列表图片闪屏问题修复 - webfem 博客搭建-创建文章接口 - webfem 代码相似性检查机制 - webfem WebSocket 技术详解:实时通信的利器 - webfem 小米YU7购车记-新能源购置税计算器的诞生 - webfem 手动搭建个人博客 - webfem 博客搭建-项目工程搭建 - webfem Base64编码详解:原理、应用与实践 - webfem 字数统计算法深度解析:从Unicode到实际应用的硬核技术实现 - webfem 衬线体与无衬线体:字体设计的经典对决 - webfem 性能优化-核心指标-FP - webfem MD5算法原理及其实现 - webfem 性能优化-核心指标-SI 的介绍与优化 - webfem 如何设计一个后端管理平台 - webfem
如何把 小程序 转换为 VUE - webfem
yimin,2316114920@qq.com · 2025-09-12 · via webfem

背景

在开发中,会遇到这样的场景,我们开发的小程序,想在 PC 上预览效果,或者,低代码平台脱出来的小程序代码,想预览效果。

这些过程,都涉及到一个核心关键步骤,将 小程序代码转换为 VUE 代码。

本文将从几个方面讲讲转换的核心思路

核心方向

转换方向

要完成整个工作,我们需要从这个这四个方面分别做代码转换

具体方案

wxml -> Template

我们先分析 wxml 和 vue template 的语法区别

语法 wxml template
数据绑定 <view>{{ message }}</view> <div>{{ message }}</div>
列表 1. 默认字段<br> <br><view wx:for="{{array}}"><br> {{index}}: {{item.message}}<br></view><br>2. 自定义自定<br> <br><view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"><br> {{idx}}: {{itemName.message}}<br></view> <li v-for="(item, index) in items"><br> {{ parentMessage }} - {{ index }} - {{ item.message }}<br></li>
条件 <view wx:if="{{length > 5}}"> 1 </view><br><view wx:elif="{{length > 2}}"> 2 </view><br><view wx:else> 3 </view> <div v-if="type === 'A'"> A</div><br><div v-else-if="type === 'B'">B<br></div><br><div v-else-if="type === 'C'">C</div><br><div v-else> Not A/B/C</div>
事件绑定 bindtap="" @click=""

通过分析,我们可以将以上的差异点逐个转化,过程还是比较容易的。

转换过程,我们使用到 cheerio 这个HTML解析工具。

以if语句为例

<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>

我们的核心逻辑 是 将标签属性 wx:if -> v-if wx:elif -> v-else-if`wx:else -> v-else`

使用 cheerio 转换代码如下

const cheerio = require('cheerio');

/**
 * 预处理HTML,转义可能干扰解析的特殊字符
 * @param {string} html - 原始HTML字符串
 * @returns {string} 处理后的HTML字符串
 */
function sanitizeHtml(html) {
  // 转义可能导致解析问题的特殊字符组合
  return html
    // 处理未闭合的花括号
    .replace(/{{([^}]+)$/, '{{$1}}') // 补全末尾未闭合的}}
    .replace(/^([^{]+)}}/, '{{$1}}') // 补全开头未闭合的{{
    // 转义HTML实体
    .replace(/&(?!amp;|lt;|gt;|quot;|#39;)/g, '&amp;')
    // 处理可能的特殊字符序列
    .replace(/\[\[/g, '&#91;&#91;')
    .replace(/\]\]/g, '&#93;&#93;')
    .replace(/\]\[/g, '&#93;&#91;');
}

/**
 * 将微信小程序的wx:if系列属性转换为Vue的v-if系列属性
 * @param {string} html - 包含wx:if属性的HTML字符串
 * @returns {string} 转换后的HTML字符串
 */
function convertWxIfToVueIf(html) {
  try {
    // 预处理HTML,清理特殊字符
    const sanitizedHtml = sanitizeHtml(html);

    // 加载HTML字符串,使用更兼容的配置
    const $ = cheerio.load(sanitizedHtml, {
      xmlMode: true,
      decodeEntities: false,
      lowerCaseTags: false,
      recognizeSelfClosing: true,
      normalizeWhitespace: false
    });

    // 处理wx:if属性
    $('[wx\:if]').each((i, el) => {
      const $el = $(el);
      const ifValue = $el.attr('wx:if');
      $el.attr('v-if', ifValue);
      $el.removeAttr('wx:if');
    });

    // 处理wx:elif属性
    $('[wx\:elif]').each((i, el) => {
      const $el = $(el);
      const elifValue = $el.attr('wx:elif');
      $el.attr('v-else-if', elifValue);
      $el.removeAttr('wx:elif');
    });

    // 处理wx:else属性
    $('[wx\:else]').each((i, el) => {
      const $el = $(el);
      $el.attr('v-else', '');
      $el.removeAttr('wx:else');
    });

    // 恢复转义的特殊字符
    return $.html()
      .replace(/&#91;&#91;/g, '{{')
      .replace(/&#93;&#93;/g, '}}')
      .replace(/&#93;&#91;/g, '][');

  } catch (error) {
    console.error('转换过程出错:', error);
    // 尝试更严格的错误恢复模式
    try {
      const $ = cheerio.load(html, {
        xmlMode: false,
        decodeEntities: false,
        ignoreParseErrors: true // 忽略解析错误
      });
      return $.html();
    } catch (fatalError) {
      console.error('无法恢复的解析错误:', fatalError);
      return html; // 返回原始内容,避免完全失败
    }
  }
}

// 示例用法
const wxHtml = `
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2 && type[[0]] == 'test'}}"> 2 </view>
<view wx:else> 3 </view>
`;

const vueHtml = convertWxIfToVueIf(wxHtml);
console.log('转换后的Vue模板:');
console.log(vueHtml);

这里有个小优化 wx:elif 作为属性去查询,会报错 throw new Error("Attribute selector didn't terminate");于是将 wx:elif 转化为 wx\:elif再处理。

其余的方法类似,可以使用AI生成,就不一一列举了。

wxs -> script

还是先分析差异点

语法 wxs script
data <br>{<br> data: {<br> array: [1, 2, 3, 4, 5, 1, 2, 3, 4]<br> }<br>}<br> <br>{<br> data() {<br> return {<br> array: [1, 2, 3, 4, 5, 1, 2, 3, 4]<br> }<br> }<br>}<br>
数据赋值 <br>this.setData({<br> myValue: 'leaf'<br> })<br> this.myValue = 'leaf'

先列这些差异点,实际开发中差异点可能更多,我们根据实际问题处理即可

转换JS推荐使用 AST 分析的方法去处理,具体 AST 转化工具可以使用 babel。

以数据赋值为例

this.setData({
  myValue: 'leaf'
})

// 转化为
this.myValue = 'leaf'

转化过程

const babel = require('@babel/core');
const t = require('@babel/types');

// Babel插件:将this.setData({...})转换为直接赋值
const setDataTransformer = {
  visitor: {
    // 访问调用表达式
    CallExpression(path) {
      const node = path.node;

      // 检查是否是this.setData调用
      if (
        t.isMemberExpression(node.callee) &&
        t.isThisExpression(node.callee.object) &&
        t.isIdentifier(node.callee.property, { name: 'setData' }) &&
        node.arguments.length === 1 &&
        t.isObjectExpression(node.arguments[0])
      ) {
        // 获取setData的参数对象
        const dataObject = node.arguments[0];

        // 创建多个赋值表达式语句
        const assignments = dataObject.properties.map(prop => {
          // 处理对象属性
          if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {
            const key = prop.key.name;
            return t.expressionStatement(
              t.assignmentExpression(
                '=',
                t.memberExpression(
                  t.thisExpression(),
                  t.identifier(key)
                ),
                prop.value
              )
            );
          }
          // 对于其他情况,返回原属性(不转换)
          return prop;
        });

        // 替换原setData调用为多个赋值语句
        path.replaceWithMultiple(assignments);
      }
    }
  }
};

// 转换函数
function transformCode(code) {
  const result = babel.transform(code, {
    plugins: [setDataTransformer]
  });
  return result.code;
}

// 示例用法
const wxCode = `
// 简单赋值
this.setData({
  myValue: 'leaf',
  count: 100,
  isActive: true
});

// 包含表达式的赋值
this.setData({
  total: this.count + 1,
  message: 'Hello ' + name
});

// 不转换的其他代码
this.otherMethod({
  param1: 'value1'
});
`;

// 执行转换
const transformedCode = transformCode(wxCode);
console.log('转换后的代码:');
console.log(transformedCode);

同上,其他的转换逻辑直接 AI 生成

wxss -> style

微信样式是web样式的子集 因此这部分不用特殊转换,直接复制过来就行

WX API -> Web API

由于 web 端没有 wx 提供的API,如果执行代码,会报错。

解决这个问题,可以在 web 端模拟 wx 的相关 API,比如

// 此处是A页面
wx.navigateTo({
  url: 'B?id=1'
})

可以在web端实现如下

window.wx = {
  navigateTo() {}
}

这里navigateTo不需要真的跳转,只需要能跑通就行

至此整个转换工作已完成

总结

本文主要讲小程序到vue组件的转化思路,提供核心方法和思考链路,很多过程没有写代码,但是可以通过AI 生成。希望整个过程有个抛砖引玉的效果。

原文地址:https://webfem.com/post/wx2vue,转载请注明出处