vue实现多布局模式

news2024/12/22 19:01:09

1、目标效果

        源码地址:multipal-layout-demo: vue2实现多布局+暗黑模式

默认布局:头部宽度100%,侧边栏、内容区

顶部布局:头部宽度100%,内容区

侧边栏布局:侧边栏高度100%,头部、内容区

2、原理分析

(1)vuex文件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // 暗黑模式
    isDark: false,
    // 布局类型
    layoutType: 'default'
  },
  mutations: {
    // 修改暗黑模式
    set_is_dark(state, val) {
      state.isDark = val
    },
    // 修改布局类型
    set_layout_type(state, val) {
      state.layoutType = val
    }
  },
  actions: {
  },
  modules: {
  }
})

        

(2)布局缩略图如何实现?用div + css 手动实现布局样式

        父组件传递一个布局类型数组,遍历此组件;用一个变量保存索引值,点击不同的布局类型项时切换索引并在vuex修改当前选中的布局类型

        将缩略图封装成组件:Thumbnail.vue

<template>
    <!-- 缩略图 -->
    <div class="thumbnail">
        <div class="layout" v-for="(item, index) in layouts" @click="changeCheck(item, index)">
            <template v-if="item.type == 'default'">
                <div class="top" :style="{ background: isDark ? 'black' : '#fff' }"></div>
                <div class="left" :style="{ background: isDark ? 'black' : '#fff' }"></div>
            </template>
            <template v-if="item.type == 'top'">
                <div class="top" :style="{ background: isDark ? 'black' : '#fff' }"></div>
            </template>
            <template v-if="item.type == 'slide'">
                <div class="top"></div>
                <div class="left" :style="{ background: isDark ? 'black' : '#fff' }"></div>
            </template>

            <i class="el-icon-check" v-show="checked == index"></i>
        </div>
    </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
    props: {
        // 布局类型数组
        layouts: {
            type: Array,
            default: () => []
        }
    },
    data() {
        return {
            // 当前选中值
            checked: 0,
        }
    },
    computed: {
        // 获取是否是暗黑模式,从而缩略图实现暗黑效果
        ...mapState(['isDark'])
    },
    methods: {
        // 切换选中值
        changeCheck(item, index) {
            this.checked = index
            this.$store.commit('set_layout_type', item.type)
        }
    }
}
</script>

<style lang="less" scoped>
.thumbnail {
    display: flex;
    width: 100%;

    .layout {
        position: relative;
        width: 50px;
        height: 50px;
        border: 1px solid gray;
        overflow: hidden;
        background: #f0f0f0;
        border-radius: 5px;
        cursor: pointer;

        .top {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 25%;
        }

        .left {
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            width: 25%;
            height: 100%;
        }

        .el-icon-check {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            font-size: 20px;
        }
    }
}
</style>

(3)建立多个不同类型的布局文件: 

 

 侧边栏布局 :src/views/layout/SlideLayout.vue

<template>
  <!-- 侧边栏布局 -->
  <div>
    <Sliderbar></Sliderbar>
    <Header></Header>
    <div class="content-box">
      <router-view />
    </div>
  </div>
</template>

<script>
import Sliderbar from '@/components/Sliderbar.vue'
import Header from '@/components/Header.vue'
export default {
  components: {
    Header,
    Sliderbar,
  },
}
</script>

<style lang="less" scoped></style>

默认布局布局:src/views/layout/DefaultLayout.vue 

<template>
  <!-- 默认布局 -->
  <div>
    <Header></Header>
    <Sliderbar></Sliderbar>
    <div class="content-box">
      <router-view />
    </div>
  </div>
</template>

<script>
import Header from '@/components/Header.vue'
import Sliderbar from '@/components/Sliderbar.vue'
export default {
  components: { Header, Sliderbar },
}
</script>

<style lang="less" scoped></style>

顶部布局:src/views/layout/TopLayout.vue 

<template>
  <!-- 顶栏布局 -->
  <div>
    <Header></Header>
    <div class="content-box">
      <router-view />
    </div>
  </div>
</template>

<script>
import Header from '@/components/Header.vue'
export default {
  components: {
    Header,
  },
}
</script>

<style lang="less" scoped></style>

  

 (4)首页组件 Home.vue,Home.vue下面渲染二级路由 

 

<template>
    <!-- vuex获取选中的布局类型 -->
    <div>
        <defaultLayout v-show="layoutType == 'default'"></defaultLayout>
        <slideLayout v-show="layoutType == 'slide'"></slideLayout>
        <topLayout v-show="layoutType == 'top'"></topLayout>
    </div>
</template>

<script>
import defaultLayout from './layout/DefaultLayout.vue'
import slideLayout from './layout/SlideLayout.vue'
import topLayout from './layout/TopLayout.vue'
import { mapState } from 'vuex'

export default {
    components: { defaultLayout, slideLayout, topLayout },
    computed: {
        ...mapState(['layoutType'])
    },
}
</script>

<style lang="less" scoped></style>

 (5)暗黑模式、布局类型变量都是保存在vuex中,因为多个组件之间进行数据通信比较方便!通过mapState取出vuex数据,然后通过computed接受mapState值,但如果想要直接修改mapState中的值则会报以下的错误:

         computed property "isDark" was assigned to but it has no setter.

        这是因为computed为只读的。不能直接修改computed的数据,要想修改则使用set

  computed: {
    ...mapState(['isDark']),
    // computed property "isDark" was assigned to but it has no setter.  这是因为computed为只读的。不能直接修改computed的数据,要想修改则使用set
    darkMode: {
      get() {
        return this.isDark
      },
      set(val) {
        this.$store.commit('set_is_dark', val)
        // 获取html根元素标签
        let html = document.documentElement
        if (val) {
          // html添加class="dark"选择器
          html.classList.add('dark')
        } else {
          // html移除class="dark"选择器
          html.classList.remove('dark')
        }
      }
    }
  },

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/450830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python+vue课堂教学效果实时评价系统

系统权限按管理员&#xff0c;教师和学生这三类涉及用户划分。 (a) 管理员&#xff1b;管理员使用本系统涉到的功能主要有&#xff1a;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;教学视频管理&#xff0c;教学课件管理&#xff0c;类型管理&#xff0c;视频…

ArcGIS Pro导航工具

主要导航工具为浏览工具 、屏幕导航器 、书签 、转到XY工具 。 其它还包括链接视图、地图比例&#xff08;2D&#xff09;、场景高度&#xff08;3D&#xff09;、暂停并刷新绘制、照相机属性、在3D模式下导航、键盘快捷键等。 1 主要导航工具 地图和场景的默认工具为浏览工具…

【python视图3】networkx图操作示例

一、说明 根据定义&#xff0c;图是节点&#xff08;顶点&#xff09;以及已识别的节点对&#xff08;称为边、链接等&#xff09;的集合。在 NetworkX 中&#xff0c;节点可以是任何可哈希对象&#xff0c;例如文本字符串、图像、XML 对象、另一个图形、自定义节点对象等。 如…

如何区分高压和低压电阻接地系统

电阻接地系统或电阻接地中性线系统是通过一个或多个电阻在中性线和大地之间有意连接的系统。在这些系统中&#xff0c;接地故障期间造成的损坏远小于在牢固接地系统中接地故障期间造成的损坏&#xff0c;并且设备上的机械应力也大大降低。 电阻通常具有比接近接地点的系统电抗…

WIN10-22H2专业版_电脑维修人员专用装机系统镜像【04.20更新】

WIN10-22H2专业版是由站长亲自封装的电脑维修人员专用装机系统镜像&#xff0c;系统干净无广告&#xff0c;稳定长效不卡顿&#xff0c;适合电脑维修店用来维修电脑重装系统。此版本是WIN10系统里非常稳定的正式版本之一&#xff0c;适合在维修电脑时重装系统或者大批量装机使用…

2023-spring 1. 补给马车

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340; 算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;2023-spring 1. 补给马车 题目描述&#xff1a;远征队即将开启未知的冒…

防晒服饰赛道持续加速扩容 未来行业集中度有望进一步提升

一、防晒服饰行业概述 国内防晒服饰市场主要包括具有防晒功能的衣服、伞具、帽子、墨镜、口罩、面罩、披肩、袖套及手套等产品。相比较防晒护肤品需要定时补涂、具有过敏风险、防晒效果欠佳以及消耗量大的缺陷&#xff0c;防晒服饰具有覆盖面广、使用方便、防晒效果好、对身体…

ChatGPT: 如何利用OpenAI的GPT-3.5构建智能对话助手

ChatGPT: 如何利用OpenAI的GPT-3.5构建智能对话助手 GPT-3.5&#xff1a;OpenAI的语言模型在自然语言处理领域的重要地位和应用潜力 GPT-3.5是OpenAI开发的一种强大的语言模型&#xff0c;具有广泛的应用潜力和在自然语言处理领域的重要地位。作为OpenAI最新一代的语言模型&…

初识C++之C++11

目录 一、C11的概念 二、统一的列表初始化 1.{ }初始化 2.initializer_list 三、decltype 四、lambda表达式 1. lambda表达式的出现原因 2. lambda表达式的使用 2.1 捕捉列表 2.2 参数列表 2.3 mutable 2.4 返回值类型 2.5 函数体 2.6 使用方式 3. lambda表达式…

c++积累11-强制类型转换运算符(static_cast/reinterpret_cast/const_cast/dynamic_cast)

1、背景 将类型名作为强制类型转换运算符的做法是C语言的老式做法&#xff0c;C为保持兼容而予以保留。强制类型转换是有一定风险的&#xff0c;C引入新的转换机制&#xff0c;主要为了客服C语言转换的三个缺点&#xff1b; 1、没有从形式上体现转换功能和风险的不同。 例如&a…

LeetCode特训 --- Week2 (主打滑动窗口 + 字符串匹配题目)

目录 滑动窗口原理 真懂了滑动窗口? 滑动 字符串细节 开干切题 滑动窗口原理 滑动窗口&#xff1a;维护一前一后两根指针, 或者说一左一右两个指针。更主要的是维护左右指针中的区间. 同时不断的向前滑动&#xff0c;直到整个序列滑动结束&#xff0c;前指针走到序列末尾…

总结:Grafana Mimir调用

一、背景 Prometheus单实例&#xff0c;可用性低&#xff0c;可靠性低&#xff0c;不能存储更多数据。 解决业务问题 如&#xff1a;当前QKE是一个集群一个项目一个prometheus实例&#xff0c;那么当我一个应用分多个集群部署的时候&#xff0c;查询数据时就得从三个promethe…

streamlit (python构建web可视化框架)笔记

文章目录 一、安装使用streamlit二、streamlit使用1.展示和数据样式2.dataframe()生成交互表和table()方法生成静态表3.绘制折线图4.绘制地图5.一些组件slider()滑动条 checkbox()确认框 selectbox()选择器6.侧边栏7.布局分列8.多页 三、Steamlit可视化简单应用--冒泡排序可视化…

java获取当前系统时间

在Java中&#xff0c;可以使用以下几种方法获取当前系统时间&#xff1a; 方法1&#xff1a;使用java.util.Date类 java import java.util.Date; public class Main { public static void main(String[] args) { Date date new Date(); System.out.println("当前时间&…

短视频app开发:如何设计个性化推荐算法

短视频app的迅速崛起已经成为了移动互联网领域中的一股热潮。然而&#xff0c;如何设计个性化推荐算法已经成为了这个领域中的一个核心问题。在本文中&#xff0c;我们将深入探讨如何为短视频app开发设计个性化推荐算法&#xff0c;以及如何使用短视频源码来实现这一目标。 简…

类间关系和内部类和数组

Final关键词 定义Pepole类&#xff0c;运用了final修饰方法eat()&#xff0c;该方法不能被改写&#xff0c;但可以随类进行继承。 用final修饰的类&#xff0c;不能有子类。 内部成员类定义方式 外部类.成员类 对象名 new 外部类&#xff08;&#xff09;.new 内部类。 局部…

[附源码]计算机毕业设计基于SSM和UNIAPP的选课APP

项目初衷 教育要实现现代化&#xff0c;高质量发展&#xff0c;就必须拥抱互联网。在此推动下&#xff0c;教育APP软件的开发非常受欢迎。通过APP自主选择教育课程的专业和课程&#xff0c;教授讲课&#xff0c;课程APP可以在线合作。通过APP自主选课的方式&#xff0c;更能激…

深度强化学习——actor-critic算法(4)

一、本文概要&#xff1a; actor是策略网络&#xff0c;用来控制agent运动&#xff0c;你可以把他看作是运动员&#xff0c;critic是价值网络&#xff0c;用来给动作打分&#xff0c;你可以把critic看作是裁判&#xff0c;这节课的内容就是构造这两个神经网络&#xff0c;然后…

项目结束倒数2

今天,解决了,多个点的最短路问题 用的dfs,配上了floyed计算出的广源距离 难点是要记录路线,dfs记录路线就很烦 但是好在结束了,经过无数的测试,确保没啥问题(应该把) 来看看我的代码 void dfs(int b[], int x, int* sum, int last, int sums, int a[], BFS& s, Floyd_A…

Java核心技术 卷1-总结-14

Java核心技术 卷1-总结-14 映射更新映射项弱散列映射链接散列集与映射枚举集与映射 视图与包装器轻量级集合包装器 映射 更新映射项 处理映射时的一个难点就是更新映射项。正常情况下&#xff0c;可以得到与一个键关联的原值&#xff0c;完成更新&#xff0c;再放回更新后的值…