最近接到一个让我很头疼的需求:产品要求咱们系统页面上全部的模块都支持顺序的变更。
好比有 模块A、B、C、D,能够无序的展现在页面上,我刚听到这个需求的时候我是崩溃的,若是是在项目开发以前提出这个需求,那么个人前期页面的架构确定不会直接写死的。如今,若是想知足这个需求,我只能翻掉以前的页面从新开发.....
目前项目是有八个模块,我是每一个模块封装一个单独的组件,而后再index页面统一引入。css
浏览了一番vue的官网,仍是有所收获的。发现了动态组件 & 异步组件这个东西!!!简直是救命啊!!!html
动态组件:vue
异步组件:node
有了动态组件这个东西以后,咱们就能够根据:is绑定不一样的值来渲染不一样的组件。好比,拿到后台给咱们返回的要渲染组件顺序的数组,咱们经过循环数组,构建出一个最终咱们想要的数据格式。关键点在于动态修改 () => import('')里面的值。每一个组件要传给子组件的值和接收子组件emit的事件也能够动态的绑定上去。好了,废话很少说了,贴代码吧!ios
首先是HTML层:axios
<template> <div class="temp"> <!-- tempList是通过处理后的数组--> <div v-for="com in tempList" :key="com.key"> <component v-bind="com.props" v-on="com.fn" :is="com.app" /> </div> </div> </template>
js层:
<script>数组
import axios from 'axios'; import Volume from "com/Volume"; import ServiceStatus from "com/ServiceStatus"; import FixStatus from "com/FixStatus"; export default { name: 'about', props: { msg: String }, data() { return { isShow: false, tempList: [], tempData: [], VolumeOptions: 'VolumeOptionsValueFromParent ', ServiceStatusOptions: 'ServiceStatusOptionsValueFromParent', FixStatusOptions: 'FixStatusOptionsValueFromParent' }; }, created() { this.createTempData() }, methods: { // 获取组件的顺序 getTempList() { //这里是我本身用nodejs mock的一个接口,返回的数据在下面贴出来 return axios.get('http://localhost:9999/search/detail').then(res => { return res.data.data }) }, async createTempData() { const result = await this.getTempList(); // 动态修改options绑定的变量 result.forEach((val) => { let key = val.tempName; switch (key) { case 'Volume': val.options = this.VolumeOptions break; case 'ServiceStatus': val.options = this.ServiceStatusOptions break; case 'FixStatus': val.options = this.FixStatusOptions break; } }) this.tempData = result; console.log(this.tempData); this.init() }, init() { // 构建渲染页面组件的数组 this.tempList = this.tempData.map((value, index) => { return { app: () => import(`com/${value.tempName}`), //异步组件 key: index, props: { options: value.options, //传给子组件的options }, fn: { change: this.changeTest //接收来自子组件的$emit事件 } }; }); }, changeTest(e) { console.log('监听子组件获得的值是:' + e) } } };
子组件代码:
1.Volume组件:架构
<template> <div id="test"> Volume page <div @click="$emit('change', 'Volume')">props的值:{{options}}</div> </div> </template> <script> export default { name: 'Volume', props: { options: { type: String, default: '' } } } </script>
2.FixStatus组件:app
<template> <div id="FixStatus" class="comm"> 组件名:FixStatus page <div @click="$emit('change', 'FixStatus')">props的值:{{options}}</div> </div> </template> <script> export default { name: 'FixStatus', props: { options: { type: String, default: '' } } } </script> <style lang="scss" scoped> @import url('../assets/scss/comm.scss'); </style>
3.ServiceStatus组件:异步
<template> <div id="ServiceStatus" class="comm"> 组件名:ServiceStatus page <div @click="$emit('change', 'ServiceStatus')">props的值:{{options}}</div> </div> </template> <script> export default { name: 'ServiceStatus', props: { options: { type: String, default: '' } } } </script> <style lang="scss" scoped> @import url('../assets/scss/comm.scss'); </style>
接口返回的数据:
{"code":"0000","msg":"请求成功!","data":[{"id":0,"tempName":"ServiceStatus","options":"''"},{"id":1,"tempName":"Volume","options":"''"},{"id":2,"tempName":"FixStatus","options":"''"}]}
data的数组就是咱们能够自定义顺序的数组。好了,是否是能够随意的玩起来了!下面看一下demo页面效果吧。
能够看到:页面组件的排列顺序就是根据接口返回的顺序排列的、每一个子组件props获得的值也是能够的、控制台console是我点击不一样组件,emit给父组件的值。这是我目前想到最稳当的方案,若是有巨佬有更好的思路,欢迎指导! 扣扣 602353272。溜了溜了....