使用Vue2+ElementUI制作的切换背景图、背景色按钮

2,712 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

介绍

这是一组(或两个)可以控制某一页面背景图的按钮,上面的按钮可以用来切换图片背景,下面的则可以用来呼出一个选色器来使背景更改为纯色背景。我将他用在了某个后台管理网页中,以获得更加可个性化的用户体验。

思路

效果图

图片背景

多次点击切换按钮将会继续切换 image.png

纯色背景

选择

image.png

清空

清空后背景色将改为代码中提前设置好的默认颜色 image.png

代码~

随机切换背景图

相关代码

<template lang="">
    <el-card shadow="hover">
        <div @click="getPaper">
            <i class="el-icon-magic-stick"></i>
            <p>切换背景图片</p>
        </div>
    </el-card>
</template>
<script>
    export default {
        name: 'WallPaper',
        data() {
            return {
                index: 0,
                wallPaperAniUrl:[
                    'https://img.xjh.me/img/59322814_p0.jpg',
                    'https://img.xjh.me/img/63045318_p0.jpg',
                    'https://img.xjh.me/img/60354469_p0.jpg',
                    'https://img.xjh.me/img/63912855_p0.jpg',
                    'https://img.xjh.me/img/65081874_p0.jpg',
                    'https://img.xjh.me/img/64082849_p0.jpg',
                    'https://img.xjh.me/img/63513874_p0.jpg',
                    'https://img.xjh.me/img/63374320_p0.jpg',
                    'https://img.xjh.me/img/57249743_p0.jpg',
                    'https://img.xjh.me/img/63301084_p0.jpg',
                    'https://img.xjh.me/img/63409027_p0.jpg',
                    'https://img.xjh.me/img/62555893_p0.jpg',
                    'https://img.xjh.me/img/59519837_p0.jpg',
                    'https://img.xjh.me/img/63606459_p0.jpg',
                    'https://img.xjh.me/img/63577828_p0.jpg',
                ],
            }
        },
        methods: {
            getPaper() {
                this.$bus.$emit('delColor')
                if(this.index === this.wallPaperAniUrl.length){
                    this.index = 0
                }
                let paperObj = {
                    url:this.wallPaperAniUrl[this.index],
                    type:'picture'
                }
                this.$bus.$emit('wallPaper',paperObj)
                this.index++
            }
        },
    }
</script>
<style scoped>
    .el-card {
        background-color: rgba(249,139,166,0.5);
        color: #FFF;
        height: 165px;
        cursor: pointer;
    }

    div {
        margin: 0 auto;
    }

    i {
        display: block;
        font-size: 100px;
        text-align: center;
    }

    p {
        text-align: center;
    }
</style>

代码讲解

以上是切换背景的按钮,因为部署的时候没有解决跨域的问题所以我删掉了请求,并且本地存好了一些图片地址,当然你可以用自己的方式向远程公共接口请求图片。

以上代码中的请求图片是某一免费的公共接口中取出来的,如果有小伙伴想要自己发请求换背景请看他们的官网 img.xjh.me/ 有接口的基本参数

index是一个类似于指针的变量,用于指向当前的壁纸。

wallPaperAniUrl中存放着提前准备好的壁纸,可以用上面的index取出

getPaper()函数:

  1. 首先使用全局事件总线告知清除颜色(将会被下方选择纯色背景的组件接收)
  2. 比对index与背景库存长度,在合适的时机让wallPaperAniUrl[index]重新指向wallPaperAniUrl的第一个元素
  3. 定义一个对象,包含着目前所选择上的背景图url与一个type,将该元素设定为picture以表示现在使用的是图片背景

打开取色器切换纯色背景

相关代码

<template lang="">
    <el-popover placement="left" width="200" trigger="click">
        <div>
            <el-color-picker v-model="color"></el-color-picker>
            <span class="chooseColor">点击选择颜色</span>
        </div>

        </div>
        <el-card shadow="hover" slot="reference">
            <div>
                <i class="el-icon-ship"></i>
                <p>切换纯色背景</p>
            </div>
        </el-card>
    </el-popover>
</template>
<script>
    export default {
        name: 'WallPaperNat',
        data() {
            return {
                color: '',
            }
        },
        watch:{
            color(newValue,oldValue){
                let paperObj = {
                    url:this.color,
                    type:'color'
                }
                if(newValue == null){
                    this.color = '#F5FFF7'
                }
                if(newValue != ''){
                    this.$bus.$emit('wallPaper',paperObj)
                }
            }
        },
        mounted() {
            if(JSON.parse(localStorage.getItem('wallPaper')).type == 'color'){
                this.color = JSON.parse(localStorage.getItem('wallPaper')).url
            }
            this.$bus.$on('delColor',() => {
                this.color = ''
            })
        },
        beforeDestroy() {
            this.$bus.$off('delColor')
        },
    }
</script>
<style scoped>
    .el-card {
        background-color: rgba(38, 157, 128, 0.5);
        color: #FFF;
        height: 165px;
        cursor: pointer;
    }

    div {
        margin: 0 auto;
    }

    i {
        display: block;
        font-size: 100px;
        text-align: center;
    }

    p {
        text-align: center;
    }

</style>

代码讲解

与上方图片背景相似。

因为我在做这个的时候时间比较赶,而且因为跨域问题没有得到解决所以这已经是改了好几次的版本了,有些变量的命名可能有歧义,例如url在这些代码里是用来存放背景信息的,并不只局限于背景图地址。

color被动态绑定于选色器中,由于elementUI自身的机制,当用户选择好颜色后点击确定后color变量才会改变。

watch配置项中配置上了color以检测该变量的变化,当该变量发生改变时,创建一个对象,type固定为color以通过全局事件总线告诉别的组件这是一个颜色背景。当用户在取色器中点击了“清空”后,color会被修改为null,因此增加一个if判断以完成当用户想要清空颜色时,将color改为默认颜色。

由于第一次进入后台管理(或清空了缓存)的用户将会使用默认背景色,于是在该组件的mounted钩子函数中写入尝试取出本次存储中的变量并进行判断的函数。该操作并不会影响背景色,但是由于color是被动态绑定于取色器中的,因此该操作只会改变取色器中的颜色,不过如果不加上这个的话取出本地背景信息失败时会出现取色器与背景色不匹配的诡异效果。

需要切换背景的容器

template

<el-main :style="getWallPaper" class="wallPaper">
    <router-view></router-view>
    <!-- ↑放入你的容器 -->
</el-main>

data:

wallPaper: {
    type: 'default'
},

type也可以填入别的,这里填入default只是区分picturecolor

computed:

getWallPaper() {
    if (this.wallPaper.type == 'picture') {
          return `background-image:url('${this.wallPaper.url}')`
    } else if (this.wallPaper.type == 'color') {
          return `background-color: ${this.wallPaper.url}`
    } else {
          return `background-color: #f3f3f3`
    }
},

背景图与背景色在这里被更换。在template中该函数被使用,主要是为了根据背景图类型切换css样式。

mounted:

if (JSON.parse(localStorage.getItem('wallPaper'))) {
  this.wallPaper = JSON.parse(localStorage.getItem('wallPaper'))
} else {
  this.wallPaper = {
    type: 'default'
  }
}
this.$bus.$on('wallPaper', val => {
  this.wallPaper = val
  localStorage.setItem('wallPaper', JSON.stringify(val))
})

在挂载后查找本地有没有存背景信息,若存在则直接修改wallPaper变量

挂载全局事件总线wallPaper,上面两个切换背景图与背景色的按钮都将会发送背景信息到这里

最后在beforeDestroy中解绑

this.$bus.$off('wallPaper')

下面是css样式,被用在会被修改背景的容器上,被设置为一张图铺满屏幕(似乎不用添加background-repeat: no-repeat;

.wallPaper {
  background-size: cover;
  background-repeat: no-repeat;
}