Vue 3 中使用 JSX 如何绑定 scopeId
vue3 scopeId
前言
在特定情况下,我需要在 SFC 组件中使用 JSX 的方法进行部分页面内容处理,但是在默认的情况下,JSX 并不会带 scopeId
,这导致我不能通过 scope css 的方法修改 JSX 的样式。在 jsx 这个插件的 github issues 中,查找到了在组件中带上组件 scopeId
的方法,虽然略显累赘,但终归是可以用。
方法
在 vue 中,导出对象有 withScopeId
这样一个函数,它可以传递一个
- 参数1:
scopeId
前组件的 scopeId
执行后,它会返回另一个函数 withCtx
。
这个 withCtx
函数可以传递两个参数,执行后返回 renderFnWithContext
,它的返回值是一个带 scopeId 的 VNode。
- 参数1:
fn
jsx 函数,签名() => JSX.Element
- 参数2:
ctx
vue 实例,ComponentInternalInstance | null | undefined
至此,我们的 JSX 就带上了 scopeId
。
封装成成一个简单的 hooks 供调用
hooks.ts
import { JSX } from '@babel/types';
import { getCurrentInstance, withScopeId } from 'vue';
/**
* 给 jsx/tsx 加 CSS Scope
* @description jsx/tsx 在 Vue3 中不支持 CSS 的 Scope,目前用这个方法使得 jsx/tsx 元素添加 Scope Id 属性
*/
export function useScope() {
const vm = getCurrentInstance();
const scopeId = (vm?.type as any).__scopeId;
const withScopeIdFunction = withScopeId(scopeId);
const withScope = (element: () => JSX.Element) => withScopeIdFunction(element, vm) as VNodeFunction;
return {
scopeId, // scopedId
vm, // vue 实例
withScope, // 用这个函数包含 () => jsx/tsx 即可
};
}
sample.vue
<script lang="tsx" setup>
// 得到带有 scope 的虚拟 DOM
const jsxWithScope = withScope(() => (
<div class="my-class" onClick={xxx}>
示例文本
</TinyButton>
))
</script>
参考资料
https://github.com/vuejs/babel-plugin-jsx/issues/51#issuecomment-770400811
评论
全部评论 (0)