class State{ constructor(context){ this.context = context } widthChange(width){ if(width <=90){ this.toState(this.context.miniState) } else if(width <=160){ this.toState(this.context.middleState) } else{ this.toState(this.context.normalState) } } showTabBody(){ return true } showTabTitle(){ return false } showIcon(){ return false } showTitle(){ return true } close(){} toState(state){ if(this.context.state !== state){ if(this.context.state === this.context.normalState){ this.context.selectedTab.isShow = false console.log('dddd') } if(state === this.context.normalState){ this.context.selectedTab.isShow = true } this.context.state = state } } stateClass(){ return '' } } class NormalState extends State{ constructor(context){ super(context) } clickTab(clickedTab){ this.context.tabs.forEach(tab => { tab.isShow \= (tab.name == clickedTab.name) this.context.selectedTab = clickedTab }); } } //需要弹出式显示标签内容 class ListState extends State{ constructor(context){ super(context) } showTabBody(){ return this.context.selectedTab.isShow } showTabTitle(){ return true } showIcon(){ return true } showTitle(){ return true } close(){ this.context.selectedTab.isShow = false } clickTab(clickedTab){ this.context.tabs.forEach(tab => { if(tab === clickedTab){ tab.isShow \= !tab.isShow this.context.selectedTab = clickedTab } else{ tab.isShow \= false } }); } } //该状态显示图标跟标题 class MiddleState extends ListState{ constructor(context){ super(context) } stateClass(){ return 'middle-size' } } //该状态只显示图标 class MiniState extends ListState{ constructor(context){ super(context) } showTitle(){ return false } stateClass(){ return 'mini-size' } }
控件脚本代码:
export default { name: 'WidgetTabs', data() { return { tabs: \[\], state: null, selectedTab :null, dockLeft:false, } }, created() { this.tabs = this.$children; this.normalState = new NormalState(this) this.middleState = new MiddleState(this) this.miniState = new MiniState(this) this.state = this.normalState }, computed: { stateClass(){ return this.state.stateClass() }, showIcon(){ return this.state.showIcon() }, showTitle(){ return this.state.showTitle() }, showTabBody(){ return this.state.showTabBody() }, showTabTitle(){ return this.state.showTabTitle() }, }, methods: { click(clickTab) { this.state.clickTab(clickTab) }, mouseMove(){ if(this.$refs.widget){ this.dockLeft = this.$refs.widget.offsetLeft < 50 this.state.widthChange(this.$refs.widget.offsetWidth) } }, mouseDown(event){ document.addEventListener('mousemove', this.mouseMove) }, mouseUp(event){ document.removeEventListener('mousemove', this.mouseMove) }, close(){ this.state.close() } }, mounted () { document.addEventListener('mousedown', this.mouseDown) document.addEventListener('mouseup', this.mouseUp) this.tabs.forEach(tab => { if(tab.isShow){ this.selectedTab = tab } }); }, beforeDestroyed() { document.removeEventListener('mousedown', this.mouseDown) document.removeEventListener('mouseup', this.mouseUp) }, }
组件创建时初始化各种状态。需要注意的一点是,需要在窗口变化时动态获取控件宽度,来确定控件是处在哪个状态。JS中DIV没有resize事件,可以通过鼠标事件来代替。我们的窗口大小是通过鼠标拖动实现的,所以跟踪鼠标拖动事件,动态查询控件大小,然后分发事件。
这个控件至此就完成了,写这个文章的事件比写代码时间长,天生是个程序员不是writer。
整个项目在这个历史节点的代码,请到我的Github上查看: https://github.com/vularsoft/...
找到该历史节点的方法:
RXEditor是一个Boostrap代码可视化编辑工具,本系列记录了该软件的开发过程,有问题的朋友请在ithub上给我留言。
总结
到此这篇关于Vue状态模式实现窗口停靠功能(灵动、自由, 管理后台Admin界面)的文章就介绍到这了,更多相关vue状态模式实现窗口停靠内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章: