Vue多布局模式實現(xiàn)方法詳細(xì)講解
1、目標(biāo)效果
源碼地址:multipal-layout-demo: vue2實現(xiàn)多布局+暗黑模式
默認(rèn)布局:頭部寬度100%,側(cè)邊欄、內(nèi)容區(qū)
頂部布局:頭部寬度100%,內(nèi)容區(qū)
側(cè)邊欄布局:側(cè)邊欄高度100%,頭部、內(nèi)容區(qū)
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)布局縮略圖如何實現(xiàn)?用div + css 手動實現(xiàn)布局樣式
父組件傳遞一個布局類型數(shù)組,遍歷此組件;用一個變量保存索引值,點擊不同的布局類型項時切換索引并在vuex修改當(dāng)前選中的布局類型
將縮略圖封裝成組件: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: { // 布局類型數(shù)組 layouts: { type: Array, default: () => [] } }, data() { return { // 當(dāng)前選中值 checked: 0, } }, computed: { // 獲取是否是暗黑模式,從而縮略圖實現(xiàn)暗黑效果 ...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)建立多個不同類型的布局文件:
側(cè)邊欄布局 :src/views/layout/SlideLayout.vue
<template> <!-- 側(cè)邊欄布局 --> <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>
默認(rèn)布局布局:src/views/layout/DefaultLayout.vue
<template> <!-- 默認(rèn)布局 --> <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中,因為多個組件之間進(jìn)行數(shù)據(jù)通信比較方便!通過mapState取出vuex數(shù)據(jù),然后通過computed接受mapState值,但如果想要直接修改mapState中的值則會報以下的錯誤:
computed property "isDark" was assigned to but it has no setter.
這是因為computed為只讀的。不能直接修改computed的數(shù)據(jù),要想修改則使用set
computed: { ...mapState(['isDark']), // computed property "isDark" was assigned to but it has no setter. 這是因為computed為只讀的。不能直接修改computed的數(shù)據(jù),要想修改則使用set darkMode: { get() { return this.isDark }, set(val) { this.$store.commit('set_is_dark', val) // 獲取html根元素標(biāo)簽 let html = document.documentElement if (val) { // html添加class="dark"選擇器 html.classList.add('dark') } else { // html移除class="dark"選擇器 html.classList.remove('dark') } } } },
到此這篇關(guān)于Vue多布局模式實現(xiàn)方法詳細(xì)講解的文章就介紹到這了,更多相關(guān)Vue多布局模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue指令只能輸入正數(shù)并且只能輸入一個小數(shù)點的方法
這篇文章主要介紹了vue指令只能輸入正數(shù)并且只能輸入一個小數(shù)點的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06Vue3使用pinia進(jìn)行數(shù)據(jù)添加、修改和刪除的操作代碼
Pinia?是?Vue?3?的官方狀態(tài)管理庫,旨在提供一種簡單、靈活且類型安全的狀態(tài)管理解決方案,Pinia?的設(shè)計理念與?Vuex?類似,但更加輕量且易于使用,文旨在全面解析?Vue?3?中如何使用?Pinia?進(jìn)行數(shù)據(jù)的添加、修改和刪除,需要的朋友可以參考下2025-03-03Vue入門之?dāng)?shù)據(jù)綁定(小結(jié))
本篇文章主要介紹了探索Vue高階組件的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01Vue使用pinia管理數(shù)據(jù)pinia持久化存儲問題
這篇文章主要介紹了Vue使用pinia管理數(shù)據(jù)pinia持久化存儲問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03詳解基于element的區(qū)間選擇組件校驗(交易金額)
這篇文章主要介紹了詳解基于element的區(qū)間選擇組件校驗(交易金額),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01