저는 최근 몇 달 동안 Vue의 작은 모바일 데모 작업을 해왔는데, 그 중 하나는 각 페이지의 통합 스킨 기능을 구현하는 것입니다. 이번 글에서는 주로 Vue 기반의 스킨 변경 기능의 샘플 코드를 소개하고 있는데, 에디터가 꽤 괜찮다고 생각해서 지금부터 공유하고 참고용으로 올려보겠습니다. 편집자를 따라가서 살펴보겠습니다.
먼저 구현을 살펴보겠습니다
테마 색상 설정
합리적으로 단계별로 말할 수 있고 구현할 수 있는 몇 가지 사항이 있다고 생각합니다.
1. 색상 값
2. scss의 일부 틈새 용도(다변수 CSS 값 일괄 설정)
3. 글로벌 이벤트 버스 적용
1 색상 값의 선택 및 원리
읽어 보시기 바랍니다. Ant Financial의 디자인 가이드라인입니다. 일반적인 상호 작용 및 인터페이스 디자인에 대한 좋은 가이드라인과 제안 사항이 포함되어 있습니다. 독서를 좋아하는 사람들은 "모두를 위한 디자인 북"도 읽어볼 수 있습니다.
인터페이스의 색상 요소에 대해 일반적으로 시각적 연속성, 즉 동일한 색상 세트를 유지해야 하며 동일한 색상환의 색상 값을 사용하려고 노력해야 합니다
색상 값 색상 세트로 같은 반지에 코디하면 더 조화로워보일 것 같아요
그래서 여기서는 개미 디자인의 제안을 채택하고 특정 색상 값 열을 시리즈의 테마 색상으로 사용합니다(공식 참조) 특정 색상 값은 웹사이트에서 확인하세요~)
그리고 일부 특별한 경우에는 색상의 차이를 표현해야 합니다. 예를 들어 동전 던지기 페이지의 두 가지 색상은
2 형식 색상 값을 변환합니다. 16진수 색상 값으로
여기에서는 테마 색상의 투명도를 설정하여 다양한 색상을 구분합니다. 그런 다음 #123456과 같은 16진수 색상 전역 변수를 테마로 저장합니다. 여기서는 이러한 형식으로 색상 값을 변환해야 합니다. 백업을 위해 코드는 다음과 같습니다
hexToRgba (hex, opacity = 0.3) { let color = [] let rgb = [] hex = hex.replace(/#/, '') for (let i = 0; i < 3; i++) { color[i] = '0x' + hex.substr(i * 2, 2) rgb.push(parseInt(Number(color[i]))) } return `rgba(${rgb.join(',')},${opacity})` }
3 scss의 일부 틈새 용도
드디어 원하는 테마 색상 목록을 얻었습니다
코드를 복사하세요 코드는 다음과 같습니다:
$colors: #f04134, #00a854, #108ee9, #f5317f , #f56a00, #7265e6, #ffbf00, #00a2ae, #2e3238;
매우 간단한 아이디어입니다. 텍스트와 아이콘의 색상, 머리의 배경색 등과 같이 각 보기 페이지에서 테마를 설정하는 데 필요한 요소의 색상을 정의합니다. 따라서 우리는 앱에서 색상 변수를 정의하고 이를 각 보기 구성 요소에 배포합니다. 이 전역 변수를 사용하여 모든 라우팅 페이지의 색상을 제어하여 다양한 테마 효과를 얻습니다.
dispatch 구현은 다음 섹션에서 논의할 것입니다. 여기에서 우리의 요구 사항을 쉽게 추출할 수 있습니다.
4 전역 색상 설정 및 저장
인터페이스에 대한 작은 사항:
이 기능을 홈페이지에서 직접 구현해봤습니다. 프로젝트에서는 mint-ui 프레임워크(Ele.me 팀의 모바일 프레임워크입니다. element.ui만큼 사용하기 불편한 점이 아쉽습니다.) 상호 작용 설정은 탄력적 레이어 mt-popup 형식입니다. 그러면 색상 블록을 직접 클릭하여 해당 색상 값을 설정하세요
<!-- 設置顏色 --> <mt-popup v-model="changColor" position="bottom" class="color-panel"> <p class="color-items"> <span class="color-item" v-for="(item, $index) in colors" :key="$index" @click="chooseColor(item)"> <span class="color-cycle" :class="'bg-color' + ($index + 1)"></span> </span> </p> </mt-popup>
그러면 위 코드에서 색상 블록 p가 표시됩니다. 이런 CSS 스타일시트를 쉽게 볼 수 있습니다
.bg-color1 {background: #f04134} .bg-color2 {background: #f04134} .bg-color3 {background: #f04134} .bg-color4 {background: #f04134} ···
Write 코딩을 하다 보면 일반적으로 비슷한 것이 반복적으로 나타나는 것을 발견하면 막연하게 이제 시작해야 할 때라는 느낌을 갖게 됩니다. 프로젝트가 성장한 후에는 color1, borderColor1...과 같은 테두리 색상에 대한 단일 설정 글꼴 색상이나 스타일 시트가 많이 있을 수 있습니다. 이런 식으로 테마 색상 배열에 따라 각 표현 형식을 작성해야 합니다. 수정 비용도 높아집니다. 그래서 내 글쓰기 스타일은 이렇습니다.
// mixin.scss: $colors: #f04134, #00a854, #108ee9, #f5317f, #f56a00, #7265e6, #ffbf00, #00a2ae, #2e3238; // setColor.vue: @import '~@/assets/mixin.scss'; ··· @for $i from 1 to 10 { .bg-color#{$i} { background-color: nth($colors, $i) } }
scss 일반적으로 사용되는 클래스 이름의 중첩 쓰기 외에도 반복 쓰기가 필요한 이러한 유형의 스타일에는... 은밀하고 고급스러운 구문이 많이 있습니다. , 내 동의 반복 루프 스타일을 작성해야 할 때 mixin 파일에 scss 변수를 추가하여 변수로 도입하는 것입니다.스타일 작성 시 sass 루프를 사용하여 해당 값을 참조합니다. 색상 설정 스타일이 어떻게 확장되고 변경되는지는 색상이 지정된 배경인지 테두리인지는 중요하지 않습니다. 믹스인 파일의 색상 값만 유지하면 됩니다. 프로젝트에서 글꼴 크기와 간격 값을 통일합니다. Bar
5 작은 것들
这个项目里面localstorage 基本被当成数据库使用了,所以点击色块设置主题时候,我们假装发出请求,在localstorage存储我们改变的颜色就好了( ./static/api.json 是一个返回helloword 的json, 为了写实在这里这么用,$bus 事件巴士下面说, 作用就是设置全局的主题颜色变量,localStorage 模拟我们把设置存储到后台,每次重新打开页面就去获取这些设置值), 目前为止,我们的设置页面就大致完成了
// 假装调用接口设置颜色 chooseColor (color) { this.$axios.get('./static/api.json') .then((data) => { this.$bus.$emit('set-theme', color) this.changColor = false localStorage.setItem('themeColor', color) }) .catch((data) => { console.log(data) }) }
6 事件巴士的运用
在上一步最后我们有个关键的东西没完成, this.$bus.$emit('set-theme', color) ,将选取的颜色设置到全局,我的代码结构是这样的
子组件
68d8f6da816bfab17f7bba8f32b5bcb7 是 home 页面 的一个子组件,而在一开始我们已经说了,我们想在我们在app.vue (home.vue和其他view的父组件) 里面定义一个color变量,派发到各个view组件里面去。 于是这其实就是个,从 setColor 触发 app.vue 的设置颜色事件, 子组件向父组件通信的问题。
我们可以很直接地用绑定事件配合 emit() 的做法,在 app.vue 定义一个 setglobalColor 方法, 并绑定到router-view(包含了home.vue),接着在home组件继续定义一个 setglobalColor 方法, 实现的功能就是 emit('setglobalColor') 去触发app.vue的方法, 并把 home.vue 的这个 setglobalColor 继续绑定到组件, 组件里面点选颜色时候,直接emit这个方法就行了。
为什么我想用事件巴士.vue 的事件巴士和 vuex, 在一些有追求的程序员手里总是小心翼翼的,我也一样,因为作为涉及全局的东西,一般觉得能不用就不用,代码能精简就精简,我们经常用一个词,不提倡。
可是有朝一日我经常在想,代码的可读性可维护性,和性能以及“风险”相对比,到底哪个更重要。对于事件巴士和vuex 这类全局性质的方案的主要担忧大部分在于, 他们是全局的,可能因为一个事件名变量名一致就造成冲突,在小型项目还会造成冗余和额外开销。 但事实上,事件和变量的命名我们都可以通过约定去规范,而在表现上,使用了事件巴士和vuex的项目,在性能上和直接 props 传递数据,emit 回调事件的项目相比,其实并没有太大区别,反而是无止境的 props 和 emit ,给人一种麻烦难以维护的感觉。 像上述的 setglobalColor , 仅仅是跨越了两层组件, 过程就显得繁琐了。所以我建议在出现两级以上组件层次,数据流稍微多的项目中都可以这么去做,定义一个全局的事件巴士
export default (Vue) => { let eventHub = new Vue() Vue.prototype.$bus = { $on (...arg) { eventHub.$on(...arg) }, $off (...arg) { eventHub.$off(...arg) }, $emit (...arg) { eventHub.$emit(...arg) } } }
将事件巴士绑定到当前vue对象,使用时候只需要:
this.$bus.$on('set-theme', (color) => {··· }) this.$bus.$emit('set-theme', '#000000')
在这个demo中,我在app.vue 绑定了
this.$bus.$on('set-theme', (color) => { this.loadingColor = color this.userinfo.color = color })
而在 setColor.vue 则在点击颜色块时候触发 this.$bus.$emit('set-theme', color), 则能实现我们设置全局颜色的效果。这样的好处在于,对于跨了多个层次,或者兄弟组件的通信,我们不再需要太繁琐的props,比如我在header.vue 也绑定了 this.$bus.$on('set-theme', (color) => { }) ,在 this.$bus.$emit 发生时候,header 的背景颜色就能直接改变,而不需要等待app.vue 将 全局的color值props传递到header.vue里面(仅做示例,这里 header.vue 只是 app.vue 的下一层级,通过props数据流会更清晰)
而对于其他路由页面组件,和 app.vue 都是直接上下级关系,我们依然采用props保持一个清晰的数据流向下传递, demo 里我是将 color 存在userinfo(以后还有其他数据), userinfo传到每个子路由, 最后,每个页面在创建时候,通过拿到这个全局的颜色,再用dom去更改对应的样式就好啦,例如
mounted () { this.$nextTick(() => { // 绑定设置主题的事件,一旦触发修改主题,则将当前字体颜色改为对应颜色 this.$el.querySelector('.myTitle').style.color = this.userinfo.color this.$el.querySelector('.weui-btn_primary').style.backgroundColor = this.userinfo.color this.$el.querySelector('.add_icon').style.color = this.userinfo.color }) }
详细的实现请参照项目代码,这里我只挑一些比较清奇的点出来讨论,项目和代码的一些规范和习惯还是挺重要的,希望有好的实践能互相借鉴进步~
相关推荐:
jQuery结合jQuery.cookie.js插件实现换肤功能示例
Javascript结合css实现网页换肤功能_javascript技巧
위 내용은 Vue 스킨 변경 기능 예제 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!