应用换肤这个 “毫无卵用” 又浪费时间的的功能却是许多产品经理们喜欢玩的(某信国民应用都不做的功能)。
首先我坦白,我TM就从没用过 应用换肤 这种功能,其次我 氪金 跟有没有 换肤 这个功能毫无关系,真是受够了这种沙雕产品,虽然我在产品经理提出这个需求之前已经解决了产品经理本人。但是在这里先拯救一下正在受难中的卑微的程序员鄙视链底端的 web前端。
下面教大家用一种简单的方式来实现这个 令人作呕 的需求
实现方式:CSS变量 + Vuex
如果是使用小程序官方的语法,没有Vuex的情况下也可以通过 全局变量 的方式实现,多添加一步读取的操作即可。
效果图
下面是具体的代码,源码可前往我的uni-app插件主页下载
源码地址:https://ext.dcloud.net.cn/plugin?id=6215
在线体验:https://mydarling.gitee.io/uniapp-extend
项目入口文件 /main.js
import Vue from 'vue'
import App from './App'
// 引用 Vuex 文件
import store from './store'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
// 使用 Vuex
store,
...App
})
app.$mount()
Vuex文件 /store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
// 写上默认皮肤的数据
skin: `
--nav-bg:#42b983;
--nav-color:#ffffff;
`
},
getters: {
},
mutations: {
// 皮肤更换
skinPeeler(state,skin = []){
// 将皮肤配置JSON转为以 ; 分割的字符串(style 值)
let style = skin.map((item,index)=>{
return `${item.name}:${item.value}`
}).join(";");
state.skin = style;
}
}
})
export default store
页面使用
<template>
<view :style="skin">
<view class="nav-bar">换肤示例</view>
<view style="padding: 100rpx;">
<button type="default" hover-class="none" class="btn">按钮 - 页面中的元素</button>
</view>
<view class="card">
<view style="padding-bottom: 20rpx;">请选择皮肤风格</view>
<radio-group @change="radioChange">
<label class="h-flex-x list-item" v-for="(item, index) in items" :key="index">
<view>
<radio :value="index.toString()" :checked="index === current" />
</view>
<view style="padding-left: 30rpx;">{{item.name}}</view>
</label>
</radio-group>
</view>
</view>
</template>
<script>
export default {
data() {
return {
items: [
{
value: [
{name:'--nav-bg',value:'#42b983'},
{name:'--nav-color',value:'#ffffff'}
],
name: '默认'
},
{
value: [
{name:'--nav-bg',value:'#12b7f5'},
{name:'--nav-color',value:'#333'}
],
name: '手机QQ'
},
{
value: [
{name:'--nav-bg',value:'#ff5500'},
{name:'--nav-color',value:'#F0E0DC'}
],
name: '淘宝'
},
],
current: 0
}
},
computed: {
skin() {
return this.$store.state.skin;
}
},
methods: {
radioChange: function(e) {
let item = this.items[Number(e.detail.value)].value;
this.$store.commit("skinPeeler",item);
}
}
}
</script>
<style lang="scss">
page {
background-color: #fff;
font-size: 28rpx;
}
.h-flex-x{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
align-content: center;
}
.card{
background-color: var(--nav-bg);
color:var(--nav-color);
padding: 30rpx;
}
.list-item{
height: 90rpx;
border-top: var(--nav-color) solid 1px;
}
.nav-bar {
box-sizing: content-box;
height: 44px;
background-color: var(--nav-bg);
padding-top: var(--status-bar-height);
color: var(--nav-color);
line-height: 44px;
text-align: center;
font-size: 16px;
}
.btn {
background-color: var(--nav-bg) !important;
color: var(--nav-color) !important;
}
</style>
作者:黄河爱浪 QQ:1846492969,邮箱:helang.love@qq.com
本文原创,著作权归作者所有,转载请注明原链接及出处