【Vue,Vuex】为你的vue项目添加vuex支持,并实现全局动态主题颜色修改
vuex教程、vuex的使用。本文详细介绍了如何将vuex整合在vue项目里,同时以实现全局动态更换主题色为功能进行讲解。
重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。
本文原文:【Vue,Vuex】为你的vue项目添加vuex支持,并实现全局动态主题颜色修改。本文更新不及时建议到原文地址浏览。
为了让读者更加容易理解并快速掌握相关知识点,本文将从项目的创建开始进行内容的介绍。本文使用@vue/cli 3.x
工具来创建vue项目,这是笔者在撰写本文时的版本。对于此工具的安装,点击这里 查看详细信息。
本文通过改变主题色来讲解vuex的使用,篇幅上可能vuex不是很多,你可以使用目录直接查看vuex部分,也可以根着内容实现效果。本文的主题效果不是最佳解决方案,只为效果演示,读者了解原理后需自己考究实用性,并加以自身优化。
一、创建项目
通过 cli 工具,可直接使用命令创建项目,本项目名为 vuex-theme , 那么使用命令:
vue create vuex-theme
就可以很方便的创建好项目了。项目创建好之后,就可以先来一波测试运行,进入创建好的项目目录 vuex-theme, 打开命令窗口,运行命令 npm run serve
即可开启测试服务,在浏览器输入提示的地址即可看到初始项目的运行结果,如下所示:
看到了效果还不够,接下来再看看项目的目录结构:
为了不让初始项目内容对本文介绍的内容产生影响,先将自动生成的文件内容进行清理。
首先清理App.vue,删除里面的多余内容,最终效果:
<!-- App.vue -->
<template>
<div id="app">
</div>
</template>
<script>
export default {
name: 'app',
components: {}
}
</script>
然后清理 HelloWorld.vue 文件,此文件直接删除,不需要它。再将 assets 目录下的 logo.png 删除,我们也不需要它。
二、加入路由支持
默认创建的项目没有自动加入路由支持,一个单页面前端应用,既然咱们要配合vuex实现主题色切换,那必然会是多界面的,就必然需要路由帮我们导航多页面支持了。
1、安装 vue-router
使用命令 npm install vue-router --save-dev
即可完成安装。使用 --save-dev
参数,可将依赖保存到 package.json 文件,别人down了你的项目才不会把依赖落下。
2、路由代码加入
安装完成之后,便可以开始编写路由代码了。考虑到本案例虽然将会使用路由导航多个页面,但不会是很多页面。因此路由表就全部写在 main.js 里,如果自己的项目路由表较多,建议分出为一个独立的路由管理文件。打开 main.js 文件,修改内容为:
// main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
Vue.config.productionTip = false
Vue.use(VueRouter)
// 这个数组目前还没有内容,因为还没有添加任何界面。
const routes = [];
new Vue({
render: h => h(App),
router: new VueRouter({
routes: routes
}),
}).$mount('#app')
继续打开文件 App.vue ,修改内容为:
<!-- App.vue -->
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
components: {}
}
</script>
代码中添加了 router-view
组件,通过它就可以实现将 main.js 里路由数组里面的页面动态渲染到界面上。这两处代码修改完成了之后,就相当于完成了路由的加入。接下来的事情就是添加各个界面了。
三、基本功能实现 - todo事项
为了能有一个不错的功能实现,笔者选用了 TODO事项
这个知名而又小巧的功能需求作为演示。考虑到此程序将实现主题色的更换,所以,在代码实现上要兼顾颜色字段的设计,即便现在还没有加入vuex的使用,也要为后期留下可操作的途径。
1、建立默认配置文件
在项目src目录下新建一个 pageCfg.js 文件,此文件作文页面颜色配置文件,在没有任何颜色设置时,此文件可作为默认颜色配置文件。文件内容如下:
// pageCfg.js
export default {
pageBackgroundColor: '#FFFFFF', // 页面背景色
primaryColor: '#1E9FFF', // 主要点缀颜色
textPrimaryColor: '#000000', // 主要文本颜色
textSecondColor: 'gray', // 次要文本颜色
}
然后修改 main.js 文件,引入配置,将其挂载到 Vue 的 prototype 上,这样方便每一个页面都能读取到配置内容:
// main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import PageCfg from './pageCfg'
Vue.config.productionTip = false
Vue.use(VueRouter)
// 将配置挂载到 prototype 上。
Vue.prototype.pageCfg = PageCfg;
// 这个数组目前还没有内容,因为还没有添加任何界面。
const routes = [];
new Vue({
render: h => h(App),
router: new VueRouter({
routes: routes
}),
}).$mount('#app')
2、添加用户登录页
todo事项,每个人都有自己要做的事情,所以每一个todo事项列表都必须先确定一个用户,因此专门为用户登入实现一个界面,在项目目录 src 下新建目录 pages 用于保存各个不同的界面。在pages下新建文件 login.vue 实现用户登录功能,这里简单的只需要提供一个用户名即可:
<!-- login.vue -->
<template>
<div>
<!-- 登录输入框 -->
<div style="margin: 15px">
<input placeholder="请输入你的用户名" v-model="user"/>
<button @click="onLoginClick" :style="getBtnThemeColor()">登录</button>
</div>
</div>
</template>
<script>
export default {
methods: {
// 登录按钮点击
onLoginClick () {
if (!this.user) return
// 在 pageCfg 对象上为此用户分配一个存储数据的对象。
this.pageCfg[this.user] = this.pageCfg[this.user] || [];
// 转到首页
this.$router.replace({
path: "/",
query: {
user: this.user
}
});
},
// 获取配置的主题颜色。设置给按钮。
getBtnThemeColor () {
return {
color: '#FFFFFF',
backgroundColor: this.pageCfg.primaryColor,
borderColor: this.pageCfg.primaryColor
}
}
},
data () {
return {
user: ''
}
}
}
</script>
代码中记录了用户名称,保存在 user 字段,用户必须输入一个值才能下一步。当用户输入值下一步时,会在 pageCfg 对象上为该用户分配一个存储数据的空间,该用户的所有数据就都会保存在这个空间里。然后会引导用户进入todo事项列表页,并将该用户的名称传递到下一个界面。
同时,为了迎合主题切换达到效果,特意为按钮加入了 getBtnThemeColor 方法,此方法返回配置的颜色数据,设置给按钮,这样按钮就可以通过配置修改颜色了。
3、添加todo事项列表页
用户进入todo事项列表界面时,就应该展示出用户的所有数据,并且提供一个新增数据的方式,因此使用如下代码实现基本功能:
// todo.vue
<template>
<div>
<!-- 根据配置文本主色改变此标题颜色 -->
<h1 :style="getTxtPriMaryColor()">
todo事项
<button @click="onExitClick" :style="getBtnThemeColor()">退出</button>
</h1>
<ul>
<!-- 根据配置文本主色改变此标题颜色 -->
<li v-for="item in todo" :key="item.key" :style="getTxtPriMaryColor()">
{{item.txt}}
<!-- 根据配置文本次要色改变此事项颜色 -->
<small :style="getTxtSecondColor()">{{item.date.toLocaleString()}}</small>
</li>
<li>
<input ref="newTodoInput" placeholder="输入新事项内容"/>
<button @click="onAddNewClick" :style="getBtnThemeColor()">添加新事项</button>
</li>
</ul>
</div>
</template>
<script>
export default {
created () {
this.user = this.$route.query.user
this.todo = this.pageCfg[this.user]
if (!this.user || !this.todo) {
this.$router.replace("/login")
return
}
},
methods: {
onAddNewClick () {
let txt = this.$refs.newTodoInput.value
if (!txt) return
this.todo.push({
key: String(Date.now()),
txt: txt,
date: new Date()
});
this.$refs.newTodoInput.value = ''
},
onExitClick () {
this.$router.replace("/login")
},
// 获取页面文本主颜色
getTxtPriMaryColor () {
return {
color: this.pageCfg.textPrimaryColor
}
},
// 获取文本次要颜色
getTxtSecondColor () {
return {
color: this.pageCfg.textSecondColor
}
},
// 获取配置的主题颜色。设置给按钮。
getBtnThemeColor () {
return {
color: '#FFFFFF',
backgroundColor: this.pageCfg.primaryColor,
borderColor: this.pageCfg.primaryColor
}
}
},
data () {
return {
user: '',
todo: []
}
}
}
</script>
可以看到,代码中首先读取传递进入的用户名,然后根据用户名将本页的列表数据进行初始化,这样页面即可对应显示出来。同时针对页面上的按钮,也同样提供了主题色设置方法。以及h1标题、li列表事项等,都加入了主题色配置获取方法。为了更明确的展示出颜色的应用方法,我并没有将按钮提取为一个公共组件,当然在读者实际开发中有需要的话,建议将共同操作都提取为一个组件去实现。然后本页提供了一个输入框,用户可以随时新增事项。
4、页面放入路由
现在我们把页面完成了,可将这两个页面放入路由映射表了。修改 main.js 内容如下:
// main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import PageCfg from './pageCfg'
Vue.config.productionTip = false
Vue.use(VueRouter)
// 将配置挂载到 prototype 上。
Vue.prototype.pageCfg = PageCfg;
// 加入写好的页面。 这里是使用了懒加载的方式。
const routes = [
{path: "/login", component: () => import('./pages/login')},
{path: "/", component: () => import('./pages/todo')}
];
new Vue({
render: h => h(App),
router: new VueRouter({
routes: routes
}),
}).$mount('#app')
5、加入基本样式
为了让vue文件代码篇幅较小,我将一些样式写在了html文件中,打开项目目录public文件夹,编辑 index.html 文件,在其head内添加如下代码:
<style>
span,i,input,button,small,strong,b,img {
vertical-align: middle;
}
button {
display: inline-block;
border: 1px solid #d9d9d9;
padding: 6px 10px;
cursor: pointer;
}
input {
padding: 6px 8px;
outline: none;
}
</style>
6、预览初形
当上面几步完成后,再次运行npm run serve
开启测试,输入提示的地址,即可看到效果,这只是一个简单的示列,仅仅支持显示和新增,并且刷新页面将会导致数据全部丢失。效果如下:
1、尝试修改主题
看起来还不错,至少没出什么大问题。现在我们尝试更改一下主题,我们的修改并不是直接在 pageCfg.js 文件里把配置给修改了,而是在 main.js 里,将 pageCfg.js 的值进行修改,从而达到目的,修改如下:
// main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import PageCfg from './pageCfg'
Vue.config.productionTip = false
Vue.use(VueRouter)
// 将配置挂载到 prototype 上。
Vue.prototype.pageCfg = PageCfg;
Vue.prototype.pageCfg.primaryColor = "red"; // 将点缀主色修改为红色。
Vue.prototype.pageCfg.textPrimaryColor = "blue"; // 将文本主色修改为蓝色。
const routes = [
{path: "/login", component: () => import('./pages/login')},
{path: "/", component: () => import('./pages/todo')}
];
new Vue({
render: h => h(App),
router: new VueRouter({
routes: routes
}),
}).$mount('#app')
我们将点缀主色修改为红色。将文本主色修改为蓝色。再次运行,发现已经生效了:
2、适配背景
上面的一系列主题色的应用都只是将显示主色修改了,但背景一直都是白色,实际上到目前为止配置的背景色都没有应用起来。现在将其使用起来。由于背景只需要设置给网页背景,document.body 是一个不做的设置位置,但是该在哪个界面完整设置背景色这个任务?似乎在任何一个页面里实现这样的逻辑都显得有点不合理,那不如将代码放在 main.js 的 new Vue 的代码逻辑里面。修改 main.js 的代码:
// main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import PageCfg from './pageCfg'
Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.prototype.pageCfg = PageCfg;
Vue.prototype.pageCfg.primaryColor = "red"; // 将点缀主色修改为红色。
Vue.prototype.pageCfg.textPrimaryColor = "blue"; // 将文本主色修改为蓝色。
const routes = [
{path: "/login", component: () => import('./pages/login')},
{path: "/", component: () => import('./pages/todo')}
];
new Vue({
created() {
// 页面初始时就设置一下页面背景色。
document.body.style.backgroundColor = this.bgColor
},
render: h => h(App),
router: new VueRouter({
routes: routes
}),
watch: {
// 监听这个颜色的改变,实现背景动态修改。
bgColor(newvalue) {
document.body.style.backgroundColor = newvalue
}
},
data() {
return {
// 将背景色赋值给根vue对象的数据区块里。
bgColor: this.pageCfg.pageBackgroundColor
}
}
}).$mount('#app')
现在,适配完成,但是看不到任何效果,因为咱们配置的背景颜色也是白色的,所有没有发生改变。这时如果再次修改颜色的值,并且添加一些新的颜色修改,就可以实现各种主题效果,现在实现一个夜间效果模式,修改颜色如下:
// main.js
import ...
...
Vue.prototype.pageCfg.pageBackgroundColor = "#02010c"
Vue.prototype.pageCfg.primaryColor = "#6e6e6e"
Vue.prototype.pageCfg.textPrimaryColor = "#ffffff"
Vue.prototype.pageCfg.textSecondColor = "#858585"
const routes = [...]
new Vue(...)
再次运行程序,发现效果已经有了:
四、加入Vuex
目前看来,每次主题更换时,我们都需要去修改一下代码,然后重新运行(你可能感觉并没有重新运行,只是速度比较,快你感觉就是没有重新启动一样)才能看到效果。如何能做到不用修改代码,直接程序运行时,去修改状态值,并且让效果立即展示出来。当然有办法,
Vuex的加入就可以瞬间解决这个问题。vuex的作用是状态保持。可能不好理解,做一个比较你就明白了。每一个vue页面里,有一个data区域,这里面的数据和页面模板里面进行了绑定,你修改data的数据,页面就可以同时进行修改。那么这个data相当于就为这个页面做了状态保持。同样道理,vuex的作用就不仅是某个界面了,而是扩大到了整个vue应用内。
1、安装 vuex
和安装 vue-router 类似,使用命令 npm install vuex --save-dev
即可进行安装。安装完成后便可以在代码里进行使用了。
使用方式也和 vue-router 类似,直接创建对象然后注入根vue实例里。修改 main.js 文件,引入vuex(部分代码已隐藏):
// main.js
// ...
import Vuex from 'vuex'
// ...
Vue.use(Vuex);
// 直接创建对象
const store = new Vuex.Store({
state: {},
mutations: {}
});
new Vue({
created() {...},
render: h => h(App),
router: new VueRouter({
routes: routes
}),
watch: {...},
data() {...},
store: store // 将上面创建的store对象注入根vue实例
}).$mount('#app')
上面的代码就算是将vuex加入到了咱们的程序里,但还没有具体实现任何功能。可能你对此已经产生了一些疑惑。state 和 mutations 是拿来干嘛的?
思考一下,在每个页面的data数据区域里的数据,要修改它们时,是不是通常都是由页面里的 method 提供的某方法,或者对应生命周期方法里,但都离不开对应的页面。同样的道理,在这个为整个应用提供数据的store区域里如果没有一个统一的操作数据的地方,那岂不乱套了。各个页面都有各自的数据要处理,这个全局数据还搅和在里面岂不更加混乱。所以,store对象有一个固有的格式。其包含了一个 state
数据具体存放的对象、以及一个 mutations
。所有操作state数据的方法写在mutations里面。代码最后通过 store 字段将其注入 vue根实例里面,这样你就可以在每个页面通过this.$store
拿到store实例了。
现在有了这个基础,就可以继续完善 store 创建部分的代码,加入主题色相关的字段:
// main.js - 部分代码
const store = new Vuex.Store({
state: {
// 初始值就都使用配置的默认值。
pageBackgroundColor: Vue.prototype.pageCfg.pageBackgroundColor,
primaryColor: Vue.prototype.pageCfg.primaryColor,
textPrimaryColor: Vue.prototype.pageCfg.textPrimaryColor,
textSecondColor: Vue.prototype.pageCfg.textSecondColor
},
mutations: {
updateColor(state, payload) {
state[payload.key] = payload.value
}
}
});
可以看到,我们为 state 添加了一些颜色字段。为 mutations 添加了一个更新颜色的方法。这个方法有两个参数,一个state,和一个payload,payload就是更新数据时传递进来的参数。
那么如何在页面里使用这个 updateColor 方法呢? 其实你无法直接使用到这个方法,vuex的store提供了一个commit方法,这个方法可以让你执行到 updateColor 方法,例如在某个页面里,想要更新页面背景色,就可以通过 this.$store.commit('updateColor', {key: 'pageBackgroundColor', value: 'pink'})
, 从而将state里的pageBackgroundColor字段进行修改,也就达到了修改背景为粉色的效果了。
2、实现动态更改主题颜色
上一节已经了解了vuex的用法和相关代码的实现。现在可以将每个页面的与获取颜色有关的方法进行一些修改,好适配主题色的动态变化。
1)、全局背景适配
全局背景色的应用我们在第三节里写在了 main.js 里,因此,继续修改main.js文件。我们使用vuex加入后,就可以不用复杂的在main.js里绕这么多代码了,去除一些代码,然后使用store的subscribe实现每次修改主题颜色后就尝试修改背景:
// main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import PageCfg from './pageCfg'
import Vuex from 'vuex'
Vue.config.productionTip = false
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.prototype.pageCfg = PageCfg;
Vue.prototype.pageCfg.pageBackgroundColor = "#02010c"; // 修改默认背景色。
Vue.prototype.pageCfg.primaryColor = "#6e6e6e"; // 将点缀主色修改为红色。
Vue.prototype.pageCfg.textPrimaryColor = "#ffffff"; // 将文本主色修改为蓝色。
Vue.prototype.pageCfg.textSecondColor = "#858585"; // 将文本主色修改为蓝色。
const routes = [
{path: "/login", component: () => import('./pages/login')},
{path: "/", component: () => import('./pages/todo')}
];
// 直接创建对象就好了
const store = new Vuex.Store({
state: {
// 初始值就都是用配置的默认值。
pageBackgroundColor: Vue.prototype.pageCfg.pageBackgroundColor,
primaryColor: Vue.prototype.pageCfg.primaryColor,
textPrimaryColor: Vue.prototype.pageCfg.textPrimaryColor,
textSecondColor: Vue.prototype.pageCfg.textSecondColor
},
mutations: {
updateColor(state, payload) {
state[payload.key] = payload.value
}
}
})
store.subscribe((mutation, state) => {
// 每次修改state值之后,这里都会执行,不如就在这里设定背景色。
document.body.style.backgroundColor = state.pageBackgroundColor
})
new Vue({
render: h => h(App),
router: new VueRouter({
routes: routes
}),
store: store
}).$mount('#app')
上述代码中,使用 subscribe 订阅了state的修改事件,每次修改都会调用传入的方法,如果改了背景色,自然就会自动修改背景。
2)、登录页颜色适配
现在修改登录页面,使其适配vuex的加入:
login.vue
<template>
<div>
<!-- 登录输入框 -->
<div style="margin: 15px">
<input placeholder="请输入你的用户名" v-model="user"/>
<button @click="onLoginClick" :style="getBtnThemeColor">登录</button>
</div>
</div>
</template>
<script>
export default {
methods: {
// 登录按钮点击
onLoginClick () {
if (!this.user) return
// 在 pageCfg 对象上为此用户分配一个存储数据的对象。
this.pageCfg[this.user] = this.pageCfg[this.user] || [];
// 转到首页
this.$router.replace({
path: "/",
query: {
user: this.user
}
});
}
},
computed: {
// 获取配置的主题颜色。设置给按钮。
getBtnThemeColor () {
return {
color: '#FFFFFF',
backgroundColor: this.$store.state.primaryColor,
borderColor: this.$store.state.primaryColor
}
}
},
data () {
return {
user: ''
}
}
}
</script>
可以看到,在模板代码区,按钮的style将原来后面的括号移除了,js代码区,将原本在methods里面的getBtnThemeColor方法移动到了computed里面,并在getBtnThemeColor方法里面修改为使用store提供的数据。
3)、事项列表页颜色适配
适配方法和登录页相似,去除布局代码里的方法括号,将方法移动到computed里面,并修改一下数据来源,即可完成:
todo.vue
<template>
<div>
<!-- 根据配置文本主色改变此标题颜色 -->
<h1 :style="getTxtPriMaryColor">
todo事项
<button @click="onExitClick" :style="getBtnThemeColor">退出</button>
</h1>
<ul>
<!-- 根据配置文本主色改变此标题颜色 -->
<li v-for="item in todo" :key="item.key" :style="getTxtPriMaryColor">
{{item.txt}}
<!-- 根据配置文本次要色改变此事项颜色 -->
<small :style="getTxtSecondColor">{{item.date.toLocaleString()}}</small>
</li>
<li>
<input ref="newTodoInput" placeholder="输入新事项内容"/>
<button @click="onAddNewClick" :style="getBtnThemeColor">添加新事项</button>
</li>
</ul>
</div>
</template>
<script>
export default {
created () {
this.user = this.$route.query.user
this.todo = this.pageCfg[this.user]
if (!this.user || !this.todo) {
this.$router.replace("/login")
return
}
},
methods: {
onAddNewClick () {
let txt = this.$refs.newTodoInput.value
if (!txt) return
this.todo.push({
key: String(Date.now()),
txt: txt,
date: new Date()
});
this.$refs.newTodoInput.value = ''
},
onExitClick () {
this.$router.replace("/login")
}
},
computed: {
// 获取页面文本主颜色
getTxtPriMaryColor () {
return {
color: this.$store.state.textPrimaryColor
}
},
// 获取文本次要颜色
getTxtSecondColor () {
return {
color: this.$store.state.textSecondColor
}
},
// 获取配置的主题颜色。设置给按钮。
getBtnThemeColor () {
return {
color: '#FFFFFF',
backgroundColor: this.$store.state.primaryColor,
borderColor: this.$store.state.primaryColor
}
}
},
data () {
return {
user: '',
todo: []
}
}
}
</script>
4)、查看效果
现在我们再次运行,就可以看到通过vuex加入后的主题效果,所实话,和没加vuex前完全一致。。。由于我们没有再次修改颜色值,所以颜色一直保持夜间主题模式。效果就不用再展示了,和之前一样的。
5)、加入颜色动态修改
为了更好的展示效果,将在todo事项列表页添加四个颜色修改视图,这样可以非常直观的看到vuex发挥的作用。开源组件 vue-color
就帮我们完成了这样一个控件,通过它就可以方便的实现颜色选择。
第一步先安装它 npm install vue-color --save-dev
。然后就可以在页面中使用了,修改todo.vue代码如下:
// todo.vue
<template>
<div>
<!-- 根据配置文本主色改变此标题颜色 -->
<h1 :style="getTxtPriMaryColor">
todo事项
<button @click="onExitClick" :style="getBtnThemeColor">退出</button>
</h1>
<ul>
<!-- 根据配置文本主色改变此标题颜色 -->
<li v-for="item in todo" :key="item.key" :style="getTxtPriMaryColor">
{{item.txt}}
<!-- 根据配置文本次要色改变此事项颜色 -->
<small :style="getTxtSecondColor">{{item.date.toLocaleString()}}</small>
</li>
<li>
<input ref="newTodoInput" placeholder="输入新事项内容"/>
<button @click="onAddNewClick" :style="getBtnThemeColor">添加新事项</button>
</li>
</ul>
<div style="margin-top: 15px">
<div style="display: inline-block">
<span :style="getTxtPriMaryColor">背景</span>
<ChromeColorPicker v-model="pageBackgroundColor"/>
</div>
<div style="display: inline-block">
<span :style="getTxtPriMaryColor">主色</span>
<ChromeColorPicker v-model="primaryColor"/>
</div>
<div style="display: inline-block">
<span :style="getTxtPriMaryColor">文本主色</span>
<ChromeColorPicker v-model="textPrimaryColor"/>
</div>
<div style="display: inline-block">
<span :style="getTxtPriMaryColor">文本次色</span>
<ChromeColorPicker v-model="textSecondColor"/>
</div>
</div>
</div>
</template>
<script>
import { Chrome } from 'vue-color'
export default {
components: {
ChromeColorPicker: Chrome
},
created () {
this.user = this.$route.query.user
this.todo = this.pageCfg[this.user]
if (!this.user || !this.todo) {
this.$router.replace("/login")
return
}
},
methods: {
onAddNewClick () {
let txt = this.$refs.newTodoInput.value
if (!txt) return
this.todo.push({
key: String(Date.now()),
txt: txt,
date: new Date()
});
this.$refs.newTodoInput.value = ''
},
onExitClick () {
this.$router.replace("/login")
}
},
computed: {
// 获取页面文本主颜色
getTxtPriMaryColor () {
return {
color: this.$store.state.textPrimaryColor
}
},
// 获取文本次要颜色
getTxtSecondColor () {
return {
color: this.$store.state.textSecondColor
}
},
// 获取配置的主题颜色。设置给按钮。
getBtnThemeColor () {
return {
color: '#FFFFFF',
backgroundColor: this.$store.state.primaryColor,
borderColor: this.$store.state.primaryColor
}
}
},
watch: {
pageBackgroundColor (newval) {
this.$store.commit('updateColor', {
key: "pageBackgroundColor",
value: newval.hex8
})
},
primaryColor (newval) {
this.$store.commit('updateColor', {
key: "primaryColor",
value: newval.hex8
})
},
textPrimaryColor (newval) {
this.$store.commit('updateColor', {
key: "textPrimaryColor",
value: newval.hex8
})
},
textSecondColor (newval) {
this.$store.commit('updateColor', {
key: "textSecondColor",
value: newval.hex8
})
}
},
data () {
return {
user: '',
todo: [],
// -------------------
pageBackgroundColor: this.$store.state.pageBackgroundColor,
primaryColor: this.$store.state.primaryColor,
textPrimaryColor: this.$store.state.textPrimaryColor,
textSecondColor: this.$store.state.textSecondColor,
}
}
}
</script>
由于 vue-color
控件更新回执值是一个对象,因此我是用watch的方式,然后将值通过commit提交给updateColor方法,实现更新。现在来看看效果吧:
Perfect!
五、总结及源代码
使用vuex的store实现了主题颜色切换,正是基于vuex的状态保持特性,使整个app内都可以响应其变化产生的效果。除了使用它保存颜色这些全局属性,按照项目逻辑可以将更多字段保存在vuex里面。vuex是让数据在整个app内贯通及响应,它不会负责持久化保存数据,它在每次运行页面时创建。持久化数据需要自行保存并在vuex创建时将值又赋值给vuex。vuex的用法还有很多,还可以分模块进行状态管理,本文定位vuex入门,更多vuex知识请点击官网文档进行查阅。本文涉及的项目代码你可已通过此链接下载运行:百度网盘,提取码:b2u4
。
更多推荐
所有评论(0)