踩坑记10 vue3、vuex4、组件化

2021.8.4

使用vuex4替换emit。进行组件化。

坑32(vuex4、keep-alive、el-tabs、标签页,缓存):背景是需要进行组件化,标签页组件将被多层嵌套,之后emit将不再适用(用起来需要多层传递)。

以下是之前的操作,主要使用emit传递打开着的标签页信息:

前传1(keep-alive基础使用): 踩坑记3 keep-alive 缓存、el-tabs 获取点击前后的参数 等_Alloom的博客-CSDN博客

前传2(keep-alive+emit保存标签页打开着的组件): 踩坑记4 keep-alive、emit 仅保存标签页打开的组件_Alloom的博客-CSDN博客

现在改用vuex4。首先是目录结构,新建store文件(与router文件平级),内新建index.js、mutations.js、actions.js文件以及modules.js文件夹(内放模块文件,例如layout.js)。actions.js和module.js暂时未用到。参考: 项目结构 | Vuex (vuejs.org)

以下是index.js,keepComponents即为保存缓存的组件名数组,该文件导出将作为store使用:

import { createStore } from 'vuex'
import mutations from './mutations'
// import actions from './actions'
// import layoutModule from './modules/layout'

const state={

    keepComponents: ['Index']

}

const store = createStore({

    state,

    mutations,

    // actions,

    // modules:{

    //     layout:layoutModule

    // }

})

export default store

以下是mutations.js,接收tabs信息(之后可能还会用于其他信息提取及存储,故而整体传输),改变keepComponents的值,该文件会被导入到index.js中:

const mutations={

    tabsChanged(state, payload){

        //tabs的name转化为components的name

        state.keepComponents=payload.tabList.map(tab=>

            tab.name.split('-')

            .map(n=>{

                n=n[0].toUpperCase()+n.slice(1)

                return n

            })

            .join(''))

    }

}

export default mutations

另外需要在main.js中增加导入import store from './store/index'和使用app.use(store)。

而组件中使用,首先必须导入import { useRouter } from 'vue-router'。

在使用el-tabs的文件内,当tabs改变后,调用commit提交mutation:

// 提交tabs改变后的信息给store,用于更新keep-alive保存的组件列表

    store.commit('tabsChanged',{

        tabList: tabList.value

    })

在使用keep-alive的文件中,读取keepComponents及使用:

//setup()中

return {

    keepComponents:computed(()=>store.state.keepComponents)

}



//template中

<router-view v-slot="{ Component }">

    <keep-alive :include="keepComponents">

        <component :is="Component" />

    </keep-alive>

</router-view>

坑33(el-breadcrumb、props):尝试了面包屑的组件化,可以达成目标效果,但最终放弃了此方案。该面包屑用于显示当前页面路径。

放弃原因:面包屑组件化后,需要从父组件通过props传值(因为设计上路由信息是在父组件中声明的router.afterEach()中获取),传递的是当前嵌套的路由;在组件化前,该路由信息直接由el-breadcrumb获取进行响应式渲染;而组件化后,其经历了props传递、computed添加响应性、由el-breadcrumb获取这几个步骤才得以渲染。

记录一下子组件读取及更新props的方法,以下是script中部分代码:

<script>

import { computed } from 'vue'

export default {

    name:'Breadcrumb',

    props:{

        matchedRoutes:Array

    },

    setup(props){

        const state=reactive({

            matchedRoutes:[]

        })

        return {

            matchedRoutes:computed(()=>props.matchedRoutes)

        }

    }

}

</script>

by 莫得感情踩坑机(限定)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值