此次开发是为了应对一家私立医院的要求进行的主题定制。公众号这块的主力开发不是我,所以本文主要谈小程序。
简单说说公众号这块吧,公众号在app.vue中调用接口拿到后台配置的色值与vant全局主题定制相结合。如果接口没值就使用全局默认样式。文件中的字体颜色和背景颜色都改为使用全局样式,很多引用图片做背景图的地方改用纯色,把icon图标改成不着色版(需要ui帮忙),对图标做一个蒙版效果,组件写法如下:
<template>
<div class="base-icon">
<div class="base-icon-img"></div>
</div>
</template>
<script lang="ts">
import { commonUtils } from '@utils';
import { computed, defineComponent, toRefs } from 'vue';
export default defineComponent({
components: {},
props: {
icon: {
type: String,
required: true,
},
active: {
type: Boolean,
default: true,
},
color: {
type: String,
default: 'var(--bg-color-primary)',
},
height: {
type: String,
default: undefined,
},
width: {
type: String,
default: undefined,
},
padding: {
type: Boolean,
default: false,
},
},
setup: (props) => {
const { icon, color, active, width, height, padding } = toRefs(props);
const backgroundImage = computed(() => {
return `url(${commonUtils.getImageSrc(`base-icons/ic_${icon.value}.png`)}) no-repeat`;
});
const backgroundColor = computed(() => {
return active.value ? color.value : '#666';
});
const heightComputed = computed(() => {
if (height.value) {
return height.value;
}
if (padding.value) {
return '6.8rem';
}
return '1.2rem';
});
const widthComputed = computed(() => width.value || heightComputed.value);
const bgColorComputed = computed(() => {
if (padding.value) {
return '#f8f8f8';
}
return 'transparent';
});
const paddingComputed = computed(() => {
if (padding.value) {
return '1rem';
}
return '0';
});
return {
backgroundImage,
backgroundColor,
widthComputed,
heightComputed,
bgColorComputed,
paddingComputed,
};
},
});
</script>
<style lang="scss" scoped>
.base-icon {
display: inline-block;
width: v-bind(widthComputed);
height: v-bind(heightComputed);
padding: v-bind(paddingComputed);
background-color: v-bind(bgColorComputed);
}
.base-icon-img {
width: 100%;
height: 100%;
background-color: v-bind(backgroundColor);
// 蒙版效果
-webkit-mask: v-bind(backgroundImage);
mask: v-bind(backgroundImage);
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
}
</style>
我这边一直都是使用的公众号做一些基础操作,然后跳转到小程序做一些视频通话这种功能,所以很多参数是需要公众号从url上传过来。如:
pages/consultation-detail/consultation-detail?imAccount=ct-stage_36528a6a799eb43dc8&imToken=36528a6a999eb43dc8&requestUrl=https://dev1.unihealths.com/CT-Stag/&token=eyJhbGciOiJIUzI1NiJ9.yJPcmdhbml6YXRpb25Vbml0WElEIjoiMTA0ODYwMSIsIkRFVklDRSI6IjMwMDcwMDAwNyIsInNob3BVVUlEIjoiNWM3ZWIzYzlkY2VjNDJmM2ExMjBhMGRlMDIyYzY5NWIiLCJVc2VyWElEIjoiMTA3MTY4NSIsInVzZXJUeXBlIjoiNTAxIiwiaW52YWxpZFRpbWUiOiIxNjUwMzU4Mzc0NzU1IiwiZXhwIjoxNjcwOTIyMjA0LCJpYXQiOjE2NzAzMTc0MDR9.UXDUbcvlRKBcOcXza2AW_h0oEDr-ST5bJn1KeQnjlMA&visitId=6906&contextOrganizationGroupId=&organizationId=104861&contextOrganizationId=104860
下面说一说小程序怎么做:
app.wxss中写全局默认样式
page{
--bg-color-primary: #819CFC;
--bg-color-primary-gradient: linear-gradient(0deg, #8796ff, #93b1ff);
--font-color-primary: #7891EC;
}
小程序具体页面的js文件下这样写:
Page({
data: {
setStyle: ``,
},
async onLoad(options) {const info = await request(
{
url: `XHealthWebServic/XPatientHome/theme?organizationId=${options.contextOrganizationId}`,
method: "get",
},
wx.getStorageSync("requestUrl")
).data;
if (info) {
wx.setStorageSync("themeInfo", info);
wx.setStorageSync(
"styleInfo",
`${
info.themeColor
? `--bg-color-primary: ${info.themeColor};--bg-color-primary-gradient: ${info.themeColor};`
: ``
}${info.textColor ? `--font-color-primary: ${info.textColor}` : ``}`
);
this.setData({
setStyle: wx.getStorageSync("styleInfo"),
});
if (info.themeColor) {
wx.setNavigationBarColor({
frontColor: "#ffffff",
backgroundColor: info.themeColor,
});
}
}
)}
})
其实就是调用接口之后给data中的变量赋值我们要用到的颜色并顺带给标题栏背景色改成接口里的值。
然后我们在wxml页面里最外层的view标签里这样写:
<view style="{{setStyle}}"></view>
成功达到覆盖最外层wxss里样式的效果。
组件的js文件里写法类似如上文,如:
Component({
data: { setStyle: `` },
ready: function () {
this.setData({
setStyle: wx.getStorageSync("styleInfo"),
});
},
});
本人开发中参考了小程序js改变全局样式;具体怎么用还需要根据各位的项目来定嗷。