前言
这段时间在公司pnpm+monorepo开发项目的时候,发现一些公司内部组件库需要用到的存在一些主题色传导问题,最后决定使用uniapp提供的globalData,而搜索引擎提供的方案比较啰嗦古老且不优雅
请使用defineOptions解决globalData定义问题!
分析与试错
如图,很多项目都使用了这个内部组件库,且里面依赖了主题色,在我们的组件封装中用到了sass变量$xxx-color,我们的自己开发组件库我们可以通过scss/css变量处理,但是组件库依赖了线上开源的组件库,其组件(radio,switch...)之类的组件,是依赖color变量来改变颜色的

于是我总结了几种方案:
1.css变量
js
// .scss
page{
--xxx-color:$xxx-color
}
// .vue 内部组件库
<up-button color="var(--xxx-color)"></up-button>
<up-radio activeColor="var(--xxx-color)"></up-radio>
然而并没有很理想,一部分组件没问题,一部分有问题,所以使用css变量就排除了
2. 使用globalData
js
// app.vue 搜索引擎例子
<script>
export default {
globalData: { color: '#ccc' }
}
</script>
<script setup>
import { onLaunch } from '@dcloudio/uni-app'
onLaunch(() => {})
</script>
// .vue 内部组件库
<up-button :color="color"></up-button>
<up-radio :activeColor="color"></up-radio>
const color=getApp().globalData.color
这样就可以统一一个变量,比起其他的设置颜色方式好多了
3. 使用本地存储(下策方案)
js
// app.vue
uni.setStorageSync("xxx-color","#ccc")
// .vue 内部组件库
<up-button :color="color"></up-button>
<up-radio :activeColor="color"></up-radio>
const color=uni.getStorageSync("xxx-color")
跟使用globalData代码层面差不多,但是本地的读写肯定不如缓存直接拿
为什么不选择传参或者pinia之类的存储呢?(globalData搜索引擎给的其他方案)
- 组件库颜色传参导致一到使用都得去看一下主题色变量对应的颜色
- 公共组件库无法使用依赖项目的pinia缓存的变量(直接报错)
那搜索引擎给的都是vue2的写法,然后vue3 setup的语法,比较不优雅


官方给的也是vue2的例子

...
要么都是在错的基础上让别人转其他方案(vuex,pinia,provide-inject),要么就提供一些通过生命周期设置或者双script的写法
其他方案(vuex,pinia,provide-inject)不符合我的需求
通过生命周期或者双script,如果是在vue3.3之前我是双手支持的
吐槽一下,uniapp官方没有给出setup语法下的globalData正确定义用法,很多2024年开发者出的文章也是千篇一律的陈旧写法普及,没有丝毫营养,建议发文章的朋友慢慢看文档,自己提升的同时,让后来者得到更好的解决方式,而不是快餐式的复制
解决方式
来了它来了,defineOptions ,很重要的一句话:这个宏可以用来直接在 <script setup>
中声明组件选项,而不必使用单独的 <script>
块
js
// app.vue
<script setup>
defineOptions({
globalData: {
color:"#ccc"
}
})
... 其他内容
</script>
// .vue 内部组件库
<up-button :color="color"></up-button>
<up-radio :activeColor="color"></up-radio>
const color=uni.getStorageSync("xxx-color")
- 解决了双script代码不优雅及别扭
- 解决了需要使用生命周期设置值(亡羊补牢的方式)
- 符合公共组件库总结获取变量的方式
总结
写下这篇文章是想提供更好的更新的解决方式给后来者,vue3.3已经发布许久,这是一个很简单的知识点defineOptions,愿大家做更正确的引路人