반응형
어레이 자동 갱신에 Dynamite Vue 컴포넌트가 필요한 이유
다이너마이트 Vue 컴포넌트에 대해 내 능력 밖의 문제가 있습니다.여기서 질문이 있습니다.
1. 아이콘 클릭
2. 컴포넌트를 어레이에 배치하고 컴포넌트를 동적으로 클릭하여 컴포넌트를 렌더링한다.
3. 탭을 클릭하면 탭이 삭제되고 탭과 관련된 컴포넌트가 탭과 창에 너무 가깝게 삭제됩니다.
오른쪽에서 탭이나 창을 닫으면 모든 것이 정상입니다만, 액티브한 창보다 인덱스가 적은 탭이나 창을 닫으면 활성화 창이 새로 고쳐집니다.여러 가지 방법으로 해결했지만 작동하지 않습니다.
다른 사람도 같은 문제를 겪었거나 제안해 준 적이 있나요? 감사합니다.
라우터:
var router = [{
path: '',
redirect: '/layout'
}, {
path: '/',
component: App,
redirect: '/layout',
children: [{
path: '/login',
component: login,
beforeEnter: redirectToHome
},
{
path: '/layout',
component: layout
},
{
path: '/getbackPwd',
component: getbackPwd
},
{
path: '/*',
component: notfound
}]
}]
레이아웃:
<div class="mu-layout">
<LayoutHead>
<div class="mu-layout-head-left">
<a class="mu-layout-showdesk" @click="toggleShowDesk"></a>
<a class="mu-layout-toggle-sidebar" @click="toggleSidebar">
<i class="el-icon-menu"></i>
</a>
<layout-tab v-for="(tab, i) in iconTabs"
:key="i"
:title="tab.title"
:component="tab.componentName"
:img="tab.img"
:minisize="tab.showMinisize"
:current="tab.current"
@close="closeTab"
@choose="chooseTab"
:tabIdx="i"
></layout-tab>
</div>
<div class="mu-layout-head-right">
<a class="mu-layout-head-link">
<i class="el-icon-search"></i>
</a>
<a class="mu-layout-head-link">
<i class="el-icon-warning" title="通知"></i>
</a>
<a class="mu-layout-head-link">
<i class="iconfont icon-act7"></i>
<span class="head-user-wrap">
{{loginUser && loginUser.username}}
</span>
</a>
<el-popover placement="bottom"
width="160"
trigger="hover"
popper-class="rect-popper"
>
<ul class="mu-layout-list mu-setting-list">
<li class="mu-layout-item">
<a class="mu-layout-item-inner" @click="openSetting"><i class="el-icon-edit-outline"></i>修改密码</a>
<a class="mu-layout-item-inner" @click="logout"><i class="el-icon-logout"></i>注销</a>
</li>
</ul>
<a class="mu-layout-head-link" slot="reference"><i class="icon-more"></i></a>
</el-popover>
</div>
</LayoutHead>
<div class="mu-layout-content">
<div class="swiper-container swiper-no-swiping">
<div class="swiper-wrapper">
<div class="swiper-slide">
<layout-iconmenu-panel>
<layout-icon-menu :img="imenu.img"
:component="imenu.component"
:title="imenu.title"
:menu-id="imenu.menu_id"
v-for="(imenu, i) in iconMenus"
:key="i"
@click="clickIconMenu"
></layout-icon-menu>
</layout-iconmenu-panel>
</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<div class="swiper-pagination"></div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
</div>
<win-panel :title="comp.title"
:tool-title="`${comp.title}(${comp.componentName})`"
:minisize-event="minisize"
@close-event="close"
:component="comp.componentName"
:ref="comp.componentName"
@choose="chooseWin"
:current="comp.current"
v-for="(comp, i) in wpanels"
:key="i"
v-model="comp.show"
:resizable="comp.resizable"
:win-width="comp.width"
:win-height="comp.height"
:is-sys="comp.isSys"
:clazz="comp.classname"
@monitor-win="monitorWin"
:rect="{drag_x: comp.drag_x, drag_y: comp.drag_y , resize_x: comp.resize_x, resize_y: comp.resize_y}"
>
<component :is="comp.comp" ></component>
</win-panel>
<layout-sidebar v-model="sidebarModel"></layout-sidebar>
</div>
import $ from 'jquery'
import LayoutHead from './head'
import LayoutFoot from './foot'
import LayoutLaunch from './button'
import LayoutIconMenu from './iconmenu'
import LayoutIconmenuPanel from './iconmenu-panel'
import LayoutTab from './tabs'
import LayoutPost from './post'
import LayoutSidebar from './sidebar'
import WinPanel from './winpanel'
import * as Components from '../getComponent'
import {
setActivePanel,
getActivePanel,
removeActivePanel,
logout,
getLoginUser,
getLoguserMenus,
setMenuId,
getMenuId
} from '../utils/auth'
import { stopPropagation } from '../utils'
import Swiper from 'swiper'
export default {
components: {
LayoutTab,
LayoutHead,
LayoutPost,
LayoutFoot,
LayoutLaunch,
LayoutSidebar,
LayoutIconMenu,
LayoutIconmenuPanel,
WinPanel,
},
data() {
var _userMenus = getLoguserMenus()
var $menus = _userMenus ? JSON.parse(_userMenus).map(e => {
return {
img: e.menu_icon,
component: e.menu_component,
title: e.menu_name,
menu_id: e.menu_id
}
}).filter(e => e.component!= 'login') : [] //排除登录组件
return {
Components,
sidebarModel: false,
loginUser: getLoginUser(),
iconMenus: $menus,
iconTabs: [],
wpanels: [],
showDeskModel: false,
activeIdx: 0, //当前激活的索引
}
},
methods: {
/*
* 根据传入的arrs进行map 操作,在回调中传入遍历的参数
*/
filterArrs(comName, cb, arrs) {
arrs = arrs ? arrs : this.iconTabs
arrs = arrs.map(e => {
cb(e)
return e
})
},
/*
* 切换sidebar事件
*/
toggleSidebar(e) {
stopPropagation(e)
this.sidebarModel = !this.sidebarModel
},
/*
* 选择窗口
*/
chooseWin(comName) {
this.toggleTab( comName )
},
/*
* 点击tab的操作事件
*/
chooseTab(comName, minisize, current) {
this.setMenuids(comName)
if(current) {
this.filterArrs(comName, e => {
if(e.componentName == comName) {
e.current = false
}
})
this.filterArrs(comName, e => {
if(e.componentName == comName ) {
e.show = false
}
}, this.wpanels)
}
else {
this.filterArrs(comName, e => {
if(e.componentName == comName ) {
e.current = true
} else {
e.current = false
}
})
this.filterArrs(comName, e => {
if(e.componentName == comName ) {
e.show = true
e.current = true
}
}, this.wpanels)
}
},
/*
* 切换不同的tab
*/
toggleTab(comName) {
this.filterArrs(comName, e => {
if(e.componentName == comName) {
e.current = true
} else {
e.current = false
}
})
this.showDeskModel = !this.showDeskModel
setActivePanel(comName)
this.setMenuids(comName)
},
/*
* 点击icon 菜单
*/
clickIconMenu(componentName, title, img, menuId, config) {
var filters = this.iconTabs.filter(e => e.componentName == componentName)
if(filters.length == 0) {
var _config = {
title,
componentName,
img,
showMinisize: false,
current: true,
comp: Components[componentName],
show: true,
menuId
}
if(componentName == 'sysSetting') {
_config.isSys = true
}
if(config) {
_config = Object.assign(_config, config)
}
this.iconTabs.push(_config)
this.wpanels = this.iconTabs.slice(0)
} else {
this.wpanels = this.wpanels.map(function(e) {
if(e.componentName == componentName) {
e.current = true
e.show = true
} else {
e.current = false
}
return e
})
this.iconTabs = this.iconTabs.map(function(e) {
if(e.componentName == componentName) {
e.current =true
} else {
e.current = false
}
return e
})
}
this.toggleTab( componentName )
this.filterArrs(componentName, e => {
if(e.componentName == componentName) {
e.current = true
} else {
e.current = false
}
}, this.wpanels)
},
/*
* 自动选择最后一个tab 和 窗口
*/
autoChooseLast() {
if(this.iconTabs.length > 0) {
var $fs = this.iconTabs.filter(e => e.current)
if($fs.length == 0) {
setTimeout(_ => {
this.iconTabs.forEach((e, i) => {
if(i == this.iconTabs.length - 1) {
e.current = true
this.wpanels[i].current = true
this.wpanels[i].show = true
setActivePanel(e.componentName)
}
})
})
}
} else {
removeActivePanel()
}
},
/*
* 窗口最小化
*/
minisize(id, component, e) {
// stopPropagation(e)
this.filterArrs(component, el => {
if(el.componentName == component) {
el.current = false
}
})
this.filterArrs(component, el => {
if(el.componentName == component) {
el.show = false
el.current = false
}
}, this.wpanels)
// this.autoChooseLast()
},
/*
* 关闭窗口事件
* 和关闭tab 相同,需要阻止冒泡,否则最外层的事件会冲突
*/
close(component, e) {
stopPropagation(e)
this.closeTab(component, e)
},
/*
* 关闭tab,同时关闭相关联的窗口
*/
closeTab(comName, e) {
stopPropagation(e)
this.iconTabs = this.iconTabs.filter(el => el.componentName != comName)
this.wpanels = this.wpanels.filter(e => e.componentName != comName)
this.autoChooseLast()
},
/*
* 切换显示菜单
*/
toggleShowDesk() {
if(this.iconTabs.length == 0 || this.wpanels.length == 0) {
return
}
if(!this.showDeskModel) {
this.iconTabs = this.iconTabs.map(function(e) {
e.current = false
return e
})
this.wpanels = this.wpanels.map(function(e) {
e.show = false
return e
})
} else {
this.wpanels = this.wpanels.map(function(e) {
e.show = true
return e
})
this.autoChooseLast()
}
this.showDeskModel = !this.showDeskModel
}
},
}
실제로 대부분의 컴포넌트는 라우터와 관련이 없지만 다이너마이트하게 컴포넌트 렌더링을 하고 있습니다.웹사이트는 웹 OS와 비슷하며 모든 아이콘에는 자체 페이지가 있으며 모두 레이아웃되어 있습니다.vue 페이지, 라우터 경로는 항상 '/filename'입니다.
언급URL : https://stackoverflow.com/questions/52368196/why-dynamite-vue-components-in-an-array-auto-refresh
반응형
'programing' 카테고리의 다른 글
클린 모드에서 일식을 실행하는 방법그렇게 하면 어떻게 되나요? (0) | 2022.07.03 |
---|---|
여러 조건에 따라 배열 내의 항목 값을 변경하려면 어떻게 해야 합니까? (0) | 2022.07.03 |
axios(vue.js)에서 다이내믹 인증 헤더를 사용하는 방법 (0) | 2022.07.03 |
Array List와 Vector의 차이점은 무엇입니까? (0) | 2022.07.03 |
Java 문자열의 날짜 형식 변경 (0) | 2022.07.03 |