uni-app 运行时揭秘:styleIsolation 的转化

背景

大家好,我是 uni-app 的核心开发 前端笨笨狗。本篇是 uni-app 源码分析的第三篇文章,欢迎关注!

前两天有开发者在群里面问我 uni-app 中如何配置 styleIsolation,我告诉了他正确的配置方案,也计划写篇文章揭秘 uni-app 是如何通过运行时将开发者的配置转化为原生微信小程序的配置。

指南

选项式

在 uni-app 中,开发者可以通过在页面组件中添加 options 配置项来设置 styleIsolation,示例如下:

js 复制代码
<script>
export default {
  name: 'MyComp',
  options: {
    styleIsolation: 'isolated'
  },  
}
</script>
js 复制代码
<script>
import { defineComponent } from "vue";

export default defineComponent({
  name: "MyComp",
  options: {
    styleIsolation: "isolated",
  },
});
</script>

组合式

在使用组合式 API 的页面组件中,开发者同样可以通过 defineOptions 来设置 styleIsolation,示例如下:

js 复制代码
<script setup>
defineOptions({
  name: 'MyComp',
  options: {
    styleIsolation: 'isolated'
  }
})
</script>

原理

createComponent 这个函数大家如果看过 vue 文件的 js 编译产物就一定不会陌生,比如

js 复制代码
<script setup>
defineOptions({
  options: {
    styleIsolation: "shared",
  },
});
</script>

会被编译为

js 复制代码
const _sfc_main = {
  __name: "comp",
  options: {
    styleIsolation: "shared"
  }
  setup(__props) {
    return (_ctx, _cache) => {
      return {};
    };
  }
};
wx.createComponent(_sfc_main);

也就是 script 中写的代码会被编译成一个对象,这个对象就是 vue 组件的配置项,而微信小程序又不认识 vue 组件的配置项,那么怎么把 vue 组件的配置项转化为微信小程序的配置项呢?这就要靠 uni-app 的运行时了,在 common/vendor.js 中,createComponent 函数会调用 parseComponent 函数来解析 vue 组件的配置项,parseComponent 的返回值就是微信小程序组件的配置项,也就是 Component 构造器 的参数,可以用来构造小程序原生组件。

js 复制代码
function initCreateComponent() {
  return function createComponent(vueComponentOptions) {
    return Component(parseComponent(vueComponentOptions));
  };
}

const createComponent = initCreateComponent();
wx.createComponent = createComponent;

当 parseComponent 解析到页面组件时,会检查组件的 options 配置项,如果发现 styleIsolation,就会将其转化为微信小程序的配置项。

js 复制代码
function parseComponent(vueOptions) {
  vueOptions = vueOptions.default || vueOptions;
  const options = {
    multipleSlots: true,
    // styleIsolation: 'apply-shared',
    addGlobalClass: true,
    pureDataPattern: /^uP$/
  };
  // 将开发者在 options 中设置的配置项转化为微信小程序的配置项
  if (vueOptions.options) {
    Object.assign(options, vueOptions.options);
  }
  const mpComponentOptions = {
    options,
    // 省略其他配置项
  };
  return mpComponentOptions;
}

这样一来,开发者在页面组件中设置的 styleIsolation 就会被正确地转化为微信小程序的配置项,从而自由控制样式隔离。

相关推荐
知了学历孙老师2 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
ShineWinsu4 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
福兮说4 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
程序员老赵6 小时前
Docker 部署青龙面板:轻松搭建定时任务管理平台
前端·docker·开源
Swot6 小时前
Asciidoctor 公式数字下标错位问题:原因分析与解决方案
前端
Swot6 小时前
leo-editor 中将 Markdown 内容转成 asciidoc 格式
前端
狒狒AI7 小时前
Remotion / GSAP+Three / HyperFrames / Skia 四栈实测:代码渲染知识视频的选栈方法(附开源技能)
前端·人工智能·aigc
修炼的dance7 小时前
浏览器里导出H.265,8.5秒和55.5秒差在硬件
前端
补码缩写7 小时前
WebCodecs选编码器,探测之后还要验解码和播放
前端
大文说跨境7 小时前
亚马逊多账号管理浏览器怎么选?云登/紫鸟/AdsPower 对比
java·前端·自动化