最近接到一個讓我很頭疼的需求:產品要求咱們系統頁面上全部的模塊都支持順序的變更。
好比有 模塊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。溜了溜了....