vue动态调节背景图片

vue动态调节背景图片

在一些场景下我们需要使用户可以进行自定义背景图片,包括背景图片和其透明度(当然,还有许多也可以,这里就以这两个为例子,都差不多),这里我就为大家详细介绍如何动态设置背景图片(伪类绑定样式属性值)。

其中声音播放部分详情在 https://blog.csdn.net/qq_45803593/article/details/125653908

先上效果图
在这里插入图片描述

在这里插入图片描述

1、调节数据

首先我们先设置改变背景图片的组件,其实就是一个计数器和选择器(这里的透明度我们设置步长为 0.1,最小值为 0.5,最大值为1,精确 1 位小数)

        <div class="opacityChoice">
            <div>
                <span>聊天背景透明度</span>
            </div>
            <div>
                <el-input-number size="mini" v-model="theme.opacity" :min="0.5" :max="1" :precision="1" :step="0.1" label="透明度"></el-input-number>
            </div>
        </div>
        <div class="bgImgChoice">
            <div>
                <span>聊天背景选择</span>
            </div>
            <div>
                <el-select size="mini" v-model="theme.bgImg" placeholder="请选择背景图片" @change="seeBackGround()">
                    <el-option
                        v-for="item in bgImgs"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value">
                    </el-option>
                </el-select>
            </div>
            <div>
                <el-image style="width: 120px; height: 80px" :src="bgImg"></el-image>
            </div>
        </div>
        <div class="updateThemeBtn">
            <el-button type="primary" @click="updateThemeInfo()">确认修改</el-button>
        </div>

data 部分

  data () {
    return {
      theme: {},
      ...
      bgImg: '', // 目前选择的图片
      ...
      bgImgs: [
        {
          value: 'http://localhost:8081/upload/chat/bg/1.jpg',
          label: '默认'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/2.jpg',
          label: '宇航员'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/3.jpg',
          label: '星空'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/4.jpg',
          label: '星云'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/5.jpg',
          label: '天空'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/6.jpg',
          label: '云雾'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/7.jpg',
          label: '夕阳'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/8.jpg',
          label: '月狼'
        }
      ]
    }
  },

在页面创建时,我们将数据进行初始化

  created () {
    this.hasSound = this.$store.state.user.userInfo.notifySound !== 'none'
    this.theme = this.$store.state.user.userInfo
    this.bgImg = this.$store.state.user.userInfo.bgImg
  },

在选中的背景图片发生变化时,我们替换相应的图片,并在点击提交时向数据库提交数据

  methods: {
    seeBackGround () {
      this.$nextTick(() => {
        this.bgImg = this.theme.bgImg
      })
    },
    updateThemeInfo () {
      if (!this.hasSound) {
        this.theme.notifySound = 'none'
      }
      userApi.updateThemeInfo(this.theme).then(res => {
        this.$message.success('修改主题信息成功n(*≧▽≦*)n')
        this.$store.dispatch('user/SET_USERINFO', res.data.userInfo)
      })
    }
  }

2、展示页面

      <el-container class="myImg" :style="{'--myImgPath': 'url(' + userInfo.bgImg + ')', '--myOpacity': userInfo.opacity}">
        <el-aside width="350px" style="height: inherit;border-right: 1px solid #c8c8c8;">
          <router-view></router-view>
        </el-aside>
        <el-container>
          <el-header>
            <div class="conversationName">
              <span style="font-size:24px">{{ currentConversation.name }}</span>
            </div>
          </el-header>
          <el-main>
            <my-main
              v-if="currentConversation.id"
              :currentConversation="currentConversation" />
            <div class="no-conversation hor-ver-center" v-else>
              <p class="text">聊天~打开心灵的窗户</p>
              <chat-svg width="800" height="648"/>
            </div>
          </el-main>
        </el-container>
      </el-container>

我们将其父元素背景设置为透明

.chat {
  height: inherit;
  background: transparent;
}

然后我们为其插入伪类样式,其中 var(--myImgPath)var(--myOpacity) 是用来动态传值的,在 vue 中我们可以使用 :style="{'--myImgPath': 'url(' + userInfo.bgImg + ')', '--myOpacity': userInfo.opacity}" 的形式来为其进行赋值,从而实现背景图片与背景透明度根据我们的调节来进行动态的显示

.myImg::before {
  background-image: var(--myImgPath);
  background-repeat:no-repeat;
  background-size: cover;
  background-attachment: fixed;
  content: '';
  opacity: var(--myOpacity);
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: -1;
}

3、组件代码

<template>
    <div class="theme" style="height:240px;overflow: auto;">
        <div class="audioSound">
                <div>
                    <span>新消息通知声音</span>
                </div>
                <div v-if="hasSound">
                    <audio :src="notifyAudio" ref="sound" muted></audio>
                    <el-select size="mini" v-model="theme.notifySound" placeholder="请选择提示音" @change="playSound()">
                        <el-option
                            v-for="item in sounds"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value">
                        </el-option>
                    </el-select>
                </div>
                <el-switch
                    v-model="hasSound"
                    active-color="#13ce66"
                    inactive-color="#ff4949">
                </el-switch>
        </div>
        <div class="opacityChoice">
            <div>
                <span>聊天背景透明度</span>
            </div>
            <div>
                <el-input-number size="mini" v-model="theme.opacity" :min="0.5" :max="1" :precision="1" :step="0.1" label="透明度"></el-input-number>
            </div>
        </div>
        <div class="bgImgChoice">
            <div>
                <span>聊天背景选择</span>
            </div>
            <div>
                <el-select size="mini" v-model="theme.bgImg" placeholder="请选择背景图片" @change="seeBackGround()">
                    <el-option
                        v-for="item in bgImgs"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value">
                    </el-option>
                </el-select>
            </div>
            <div>
                <el-image style="width: 120px; height: 80px" :src="bgImg"></el-image>
            </div>
        </div>
        <div class="updateThemeBtn">
            <el-button type="primary" @click="updateThemeInfo()">确认修改</el-button>
        </div>
    </div>
</template>
<script>
import userApi from '@/api/modules/user'
const notifySoundMap = {
  default: require('../../../static/audio/default.mp3'),
  apple: require('../../../static/audio/apple.mp3'),
  pcqq: require('../../../static/audio/pcqq.mp3'),
  momo: require('../../../static/audio/momo.mp3'),
  huaji: require('../../../static/audio/huaji.mp3'),
  mobileqq: require('../../../static/audio/mobileqq.mp3'),
  none: ''
}
export default {
  name: 'MessageNotification',
  data () {
    return {
      theme: {},
      hasSound: true,
      notifyAudio: '',
      BGIMG_URL: 'http://localhost:8081/upload/chat/bg/',
      bgImg: '',
      sounds: [
        {
          value: 'default',
          label: '默认'
        },
        {
          value: 'apple',
          label: '苹果'
        },
        {
          value: 'pcqq',
          label: '电脑端qq'
        },
        {
          value: 'momo',
          label: '陌陌'
        },
        {
          value: 'huaji',
          label: '滑稽'
        },
        {
          value: 'mobileqq',
          label: '手机qq'
        }
      ],
      bgImgs: [
        {
          value: 'http://localhost:8081/upload/chat/bg/1.jpg',
          label: '默认'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/2.jpg',
          label: '宇航员'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/3.jpg',
          label: '星空'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/4.jpg',
          label: '星云'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/5.jpg',
          label: '天空'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/6.jpg',
          label: '云雾'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/7.jpg',
          label: '夕阳'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/8.jpg',
          label: '月狼'
        }
      ]
    }
  },
  created () {
    this.hasSound = this.$store.state.user.userInfo.notifySound !== 'none'
    this.theme = this.$store.state.user.userInfo
    this.bgImg = this.$store.state.user.userInfo.bgImg
  },
  methods: {
    playSound () {
      this.notifyAudio = notifySoundMap[this.theme.notifySound]
      this.$nextTick(() => {
        this.$refs['sound'].play()
      })
    },
    seeBackGround () {
      this.$nextTick(() => {
        this.bgImg = this.theme.bgImg
      })
    },
    updateThemeInfo () {
      if (!this.hasSound) {
        this.theme.notifySound = 'none'
      }
      userApi.updateThemeInfo(this.theme).then(res => {
        this.$message.success('修改主题信息成功n(*≧▽≦*)n')
        this.$store.dispatch('user/SET_USERINFO', res.data.userInfo)
      })
    }
  }
}
</script>
<style>
.theme {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    padding: 0 25px;
}
.theme .audioSound {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 60px;
}
.theme .opacityChoice {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 60px;
}
.theme .bgImgChoice {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}
</style>

其相关的所有代码

<template>
    <div class="theme" style="height:240px;overflow: auto;">
        <div class="audioSound">
                <div>
                    <span>新消息通知声音</span>
                </div>
                <div v-if="hasSound">
                    <audio :src="notifyAudio" ref="sound" muted></audio>
                    <el-select size="mini" v-model="theme.notifySound" placeholder="请选择提示音" @change="playSound()">
                        <el-option
                            v-for="item in sounds"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value">
                        </el-option>
                    </el-select>
                </div>
                <el-switch
                    v-model="hasSound"
                    active-color="#13ce66"
                    inactive-color="#ff4949">
                </el-switch>
        </div>
        <div class="opacityChoice">
            <div>
                <span>聊天背景透明度</span>
            </div>
            <div>
                <el-input-number size="mini" v-model="theme.opacity" :min="0.5" :max="1" :precision="1" :step="0.1" label="透明度"></el-input-number>
            </div>
        </div>
        <div class="bgImgChoice">
            <div>
                <span>聊天背景选择</span>
            </div>
            <div>
                <el-select size="mini" v-model="theme.bgImg" placeholder="请选择背景图片" @change="seeBackGround()">
                    <el-option
                        v-for="item in bgImgs"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value">
                    </el-option>
                </el-select>
            </div>
            <div>
                <el-image style="width: 120px; height: 80px" :src="bgImg"></el-image>
            </div>
        </div>
        <div class="updateThemeBtn">
            <el-button type="primary" @click="updateThemeInfo()">确认修改</el-button>
        </div>
    </div>
</template>
<script>
import userApi from '@/api/modules/user'
const notifySoundMap = {
  default: require('../../../static/audio/default.mp3'),
  apple: require('../../../static/audio/apple.mp3'),
  pcqq: require('../../../static/audio/pcqq.mp3'),
  momo: require('../../../static/audio/momo.mp3'),
  huaji: require('../../../static/audio/huaji.mp3'),
  mobileqq: require('../../../static/audio/mobileqq.mp3'),
  none: ''
}
export default {
  name: 'MessageNotification',
  data () {
    return {
      theme: {},
      hasSound: true,
      notifyAudio: '',
      BGIMG_URL: 'http://localhost:8081/upload/chat/bg/',
      bgImg: '',
      sounds: [
        {
          value: 'default',
          label: '默认'
        },
        {
          value: 'apple',
          label: '苹果'
        },
        {
          value: 'pcqq',
          label: '电脑端qq'
        },
        {
          value: 'momo',
          label: '陌陌'
        },
        {
          value: 'huaji',
          label: '滑稽'
        },
        {
          value: 'mobileqq',
          label: '手机qq'
        }
      ],
      bgImgs: [
        {
          value: 'http://localhost:8081/upload/chat/bg/1.jpg',
          label: '默认'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/2.jpg',
          label: '宇航员'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/3.jpg',
          label: '星空'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/4.jpg',
          label: '星云'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/5.jpg',
          label: '天空'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/6.jpg',
          label: '云雾'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/7.jpg',
          label: '夕阳'
        },
        {
          value: 'http://localhost:8081/upload/chat/bg/8.jpg',
          label: '月狼'
        }
      ]
    }
  },
  created () {
    this.hasSound = this.$store.state.user.userInfo.notifySound !== 'none'
    this.theme = this.$store.state.user.userInfo
    this.bgImg = this.$store.state.user.userInfo.bgImg
  },
  methods: {
    playSound () {
      this.notifyAudio = notifySoundMap[this.theme.notifySound]
      this.$nextTick(() => {
        this.$refs['sound'].play()
      })
    },
    seeBackGround () {
      this.$nextTick(() => {
        this.bgImg = this.theme.bgImg
      })
    },
    updateThemeInfo () {
      if (!this.hasSound) {
        this.theme.notifySound = 'none'
      }
      userApi.updateThemeInfo(this.theme).then(res => {
        this.$message.success('修改主题信息成功n(*≧▽≦*)n')
        this.$store.dispatch('user/SET_USERINFO', res.data.userInfo)
      })
    }
  }
}
</script>
<style>
.theme {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    padding: 0 25px;
}
.theme .audioSound {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 60px;
}
.theme .opacityChoice {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 60px;
}
.theme .bgImgChoice {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}
</style>

<template>
  <div class="chat">
    <el-container style="height: inherit;">
      <audio :src="NotifyAudio" ref="audio" muted></audio>
      <el-aside width="60px" style="height: inherit;background-color:#2f2e2e">
        <my-menu />
      </el-aside>
      <el-container class="myImg" :style="{'--myImgPath': 'url(' + userInfo.bgImg + ')', '--myOpacity': userInfo.opacity}">
        <el-aside width="350px" style="height: inherit;border-right: 1px solid #c8c8c8;">
          <router-view></router-view>
        </el-aside>
        <el-container>
          <el-header>
            <div class="conversationName">
              <span style="font-size:24px">{{ currentConversation.name }}</span>
            </div>
          </el-header>
          <el-main>
            <my-main
              v-if="currentConversation.id"
              :currentConversation="currentConversation" />
            <div class="no-conversation hor-ver-center" v-else>
              <p class="text">聊天~打开心灵的窗户</p>
              <chat-svg width="800" height="648"/>
            </div>
          </el-main>
        </el-container>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import myMenu from '@/views/layout/MyMenu'
import myMain from '@/views/layout/myMain'
import chatSvg from '@/SVGComponents/chat'
import conversationApi from '@/api/modules/conversation'
const notifySoundMap = {
  default: require('../../static/audio/default.mp3'),
  apple: require('../../static/audio/apple.mp3'),
  pcqq: require('../../static/audio/pcqq.mp3'),
  momo: require('../../static/audio/momo.mp3'),
  huaji: require('../../static/audio/huaji.mp3'),
  mobileqq: require('../../static/audio/mobileqq.mp3'),
  none: ''
}
export default {
  name: 'Chat',
  components: { myMain, myMenu, chatSvg },
  data () {
    return {
      NotifyAudio: '', // 播放的声音
      notifySound: '' // 目前设置的声音
    }
  },
  created () {
    this.notifySound = this.userInfo.notifySound
    this.getMyConversationsList()
  },
  sockets: {
    // 客户端connect事件,服务端可针对connect进行信息传输
    connect: function () {
      this.$message.info('连接成功')
      console.log('socket connected:', this.$socket.id)
    },
    onlineUser (data) {
      // console.log('当前在线用户列表:', data)
      this.$store.dispatch('user/SET_ONLINE_USER', data)
    },
    receiveMessage (news) {
      this.$refs['audio'].play()
      // 不是现在所处的房间就新增未读消息
      if (news.roomId !== this.$store.state.conversation.currentConversation.roomId || JSON.stringify(this.$store.state.conversation.currentConversation) === '{}') {
        this.$store.dispatch('conversation/SET_UNREAD_NUM', {type: 'add', data: news})
      }
    },
    receiveValidateMessage (news) { // 同时向系统消息页面发送未读消息
      this.$refs['audio'].play()
    },
    receiveAgreeFriendValidate (data) {
      this.$refs['audio'].play()
    }
  },
  computed: {
    currentConversation () {
      return this.$store.state.conversation.currentConversation
    },
    userInfo () {
      return this.$store.state.user.userInfo
    }
  },
  watch: {
    userInfo: {
      handler (newVal, oldVal) {
        this.userGoOnline()
      },
      deep: true,
      immediate: true
    },
    notifySound: {
      handler (notifySound) {
        this.NotifyAudio = notifySoundMap[notifySound]
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    // 用户上线
    userGoOnline () {
      if (this.userInfo) { // 有用户信息时才发送给后端进行保存
        this.$socket.emit('goOnline', this.userInfo)
      }
    },
    // 将会话信息存入vuex
    getMyConversationsList () {
      conversationApi.getMyConversationsList(this.$store.state.user.userInfo.id).then(res => {
        this.$store.dispatch('conversation/SET_RECENT_CONVERSATION', {type: 'init', data: res.data.myConversationsList})
      })
    }
  }
}
</script>
<style>
.chat {
  height: inherit;
  background: transparent;
}
.myImg::before {
  background-image: var(--myImgPath);
  background-repeat:no-repeat;
  background-size: cover;
  background-attachment: fixed;
  content: '';
  opacity: var(--myOpacity);
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: -1;
}
.el-footer {
  background-color: #f7f7f7;
  color: #333;
  text-align: center;
  line-height: 60px;
}
.el-aside {
  color: #333;
  text-align: center;
}
.el-main {
  color: #333;
}
.conversationName {
  display: flex;
  height: inherit;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
}
.no-conversation {
  text-align: center;
}
.no-conversation .text {
  color: #909399;
  font-size: 20px;
}
.hor-ver-center {
  position: absolute;
  top: 60%;
  left: 60%;
  transform: translate(-50%, -60%);
}
</style>

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值