Requirements: Dynamic routing should be embedded in external chain page, need to pass token, need lazy loading, need URL can handle not too exposed
juejin.cn/post/684490…
It’s rough. There must be some space to optimize
1. Generate a list of IFrames in the process of generating dynamic routes:
If (omenu.path. includes(' HTTP ')){let hasFlag = false // iframeList from localStorage, Let iframeList = localstorage.getitem ('iframeList')? Parse (localstorage.getitem ('iframeList')) : [] // let obj = {name: omenu. name, label: oMenu.path.split('/').length===7?'page-' + oMenu.path.split('/')[6]:oMenu.path, id: oMenu.id, path: oMenu.path } for(let i=0; i<iframeList.length; I ++){if(iframeList[I].id === obj.id){iframeList[I] = obj hasFlag = true}} hasFlag && iframeList.push(obj) localStorage.setItem('iframeList',JSON.stringify(iframeList)) }Copy the code
The generated data looks something like this:
[{label: "page-cost-supplement-list".name:"xxx".path:"http://xxx/xx/xx/xx/cost-supplement-list"},... ]Copy the code
Add an iframe specific getPath method, which you’ll use later
getIframePath(params){ const { page } = params let result = page || '/' if (page.includes('page-')) { result = `/out/page? ${objToform(params)}` } return result },Copy the code
2. Add iframe related routes to the fixed router
Component: Layout, redirect: '/out', children: [{path: ':page ', // children: [{path:' :page ', // children: [{path: ':page ', // children: [{path:' :page ', // children: [' :page ', // children: [' :page ']] 'iframe', component: () => import ( /* webpackChunkName: "page" */ '@/components/iframe/main'), props: true }] },Copy the code
3, handle the left menu bar click jump method
open(item) { if (this.screen <= 1) this.$store.commit("SET_COLLAPSE"); this.$router.$avueRouter.group = item.group; If (/^ HTTP /.test(item.path)){this.$router.push({path: This.$router.$avueRouter. GetIframePath ({SRC: this.changepath (item)}), query: item.query, }).catch(() => {}); }else{ this.$router.push({ path: this.$router.$avueRouter.getPath({ name: item[this.labelKey], src: item[this.pathKey] }), query: item.query }).catch(() => {}); }}Copy the code
4, handle the method of modifying tagList when the page jumps in the route navigation guard
let value = to.query.src || to.fullPath const label = to.query.name || to.name if (meta.isTab ! == false && ! validatenull(value) && ! Validatenull (label)) {// iframe, If (to.query.page && to.query.page. Includes ('page-')){value = to.query.page const arr = Json. parse(localstorage.getitem ('iframeList')) store.com MIT ('ADD_TAG', { arr.filter(item => item.label === value)[0].name, value: value, params: to.params, query: to.query, group: router.$avueRouter.group || [], }) }else{ store.commit('ADD_TAG', { label: label, value: value, params: to.params, query: to.query, group: router.$avueRouter.group || [], }) } } next()Copy the code
5. Next, deal with the iframe component.
<template> <div> <basic-container> <keep-alive> <router-view></router-view> </keep-alive> <component v-for="item in hasOpenComponentsArr" :key="item.name" :is="item.name" v-show="item.label === getLabel($route.query.page)" ></component> </basic-container> </div> </template>Copy the code
export default { data () { return { componentsArr: [], clientHeight: ",}}, created () {let componentsArr = this.componentSarr () componentsArr. {template: '<iframe SRC ='${this.getSrc(this.$route.query.page)}'}' Class ="iframe"></iframe> '}) !!!! Let STR = item.path +'? token='+ token Vue.component(item.name,{template:`<iframe src='${str}' class="iframe"></iframe>`}) }) this.componentsArr = componentsArr this.isOpenIframePage(); }, props: ['routerPath'], watch: { $route: function () { this.isOpenIframePage(); }, }, computed: {// implement lazy loading, Rendering has been open only (hasOpen: true) hasOpenComponentsArr iframe page () {return this.com ponentsArr. Filter (item = > item. HasOpen); } }, methods: { getLabel(val){ const arr = JSON.parse(localStorage.getItem('iframeList')) return arr.filter(item => item.label === val)[0].name }, Parse (localstorage.getitem ("pig-access_token")).content const arr = JSON.parse(localStorage.getItem('iframeList')) return arr.filter(item => item.label === val)[0].path + '?token=' + token }, HasOpen isOpenIframePage() {const target = this.ponentsarr.find (item => {return item.label === = this.getLabel(this.$route.query.page) }); if (target && ! target.hasOpen) { target.hasOpen = true; }}, // traverses all pages of the route, GetComponentsArr () {const iframeArr = json.parse (localstorage.getitem ('iframeList')) console.log(iframeArr) return iframeArr.map((item) => { return { label: Name: 'a'+item.id, path: item.path, hasOpen: }} </script>Copy the code
Don’t forget to make changes in vue.config.js since you are using Vue.com Ponent to register the component
Module. exports = {runtimeCompiler: true, // this line is enough}Copy the code
6, multi-tab click method should also make corresponding modifications
openTag(item) { let tag; if (item.name) { tag = this.findTag(item.name).tag; If (item.name! $route.path){iframe if(item.name.includes('page-')){SRC = Page this.$route. push({path: $router. this.$router.$avueRouter.getIframePath({ page: tag.value }), }) }else{ this.$router.push({ path: this.$router.$avueRouter.getPath({ name: tag.label, src: tag.value }), query: tag.query }) } } } },Copy the code
So I’m done and it looks something like this
It is the first time to share experience, but I hope you can forgive me