如何结合使用cytoscape.js和vue.js动态组件的keep-alive?

问题描述:

我正在尝试使用Vue.js 2.0构建单页应用程序。该应用程序应该具有多种操作模式,我想使用Vue.js dynamic component来实现这些操作模式。由于每种模式的状态应该在切换时保留,我决定使用Vue.js提供的keep-alive功能。其中一种模式应该是使用Cytoscape.js创建的网络视图。如何结合使用cytoscape.js和vue.js动态组件的keep-alive?

这里来了我的问题。当我第一次切换到网络时,网络被正确初始化,但来回切换后,网络视图冻结。保持活力正常工作(据我了解),并带回Cytoscape实例和正确的HTML部分。不知何故,Cytoscape实例和HTML部分之间的连接似乎丢失了,尽管我不明白如何以及为什么。

下面是一个示例代码。

//sample data for network 
 
var testElements = [ 
 
    { data: {id: 'a'} }, 
 
    { data: {id: 'b'} }, 
 
    { data: { 
 
     id: 'ab', 
 
     source: 'a', 
 
     target: 'b' 
 
     } 
 
    } 
 
]; 
 
    
 
//Vue components 
 
Vue.component('otherView', { 
 
    template: '<div>This is another mode</div>' 
 
}); 
 

 
Vue.component('network', { 
 
    template: '<div id="container" class="cy"></div>', 
 
    mounted: function() { 
 
     cy1 = cytoscape({ 
 
      container: document.getElementById("container"), 
 
      elements: testElements 
 
     }); 
 
    } 
 
}); 
 

 
//Vue dynamic component 
 
var vm = new Vue({ 
 
    el: "#dynamic", 
 
    data: { 
 
     currentView: 'otherView' 
 
    } 
 
});
.cy { 
 
    width: 500px; 
 
    height: 500px; 
 
    position: absolute; 
 
    top: 100px; 
 
    left: 10px; 
 
}
<script src="https://rawgit.com/cytoscape/cytoscape.js/master/dist/cytoscape.js"></script> 
 
<script src="https://unpkg.com/vue/dist/vue.js"></script> 
 

 
<div id="dynamic" > 
 
    <div id="selectorButton"> 
 
     <button id="button1" @click="currentView='otherView'">Other view</button> 
 
     <button id="button2" @click="currentView='network'">Network</button> 
 
    </div> 
 

 
    <keep-alive> 
 
     <component :is="currentView"></component> 
 
    </keep-alive> 
 

 
</div>

如果您删除Cytoscape实例,则已将其销毁。请确保Vue不会破坏您的DOM元素或每次从JSON创建新的Cytoscape实例:http://js.cytoscape.org/#cy.json

+0

因此,总之,它不工作?选项1(“要么确保Vue不会销毁你的DOM元素”)在我的情况下使用Vue.js和动态组件obsolet,以及选项2(“或者每次从JSON创建一个新的Cytoscape实例”)由于运行时间长而不适用。 至于我的情况,我将选择1并隐藏ctoscape实例,当我不需要它时,用'style ='display:none;''。 – PhJ

+0

图的整个状态可以通过json进行串行化。在状态方面,使用相同的json创建新实例与保留旧实例通常没有区别。 – maxkfranz

我不能完全理解你的问题,但你可以尝试转移你写在网络组件的安装oroperty到被激活的属性代码如下

Vue.component('network', { 
     template: '<div id="container" class="cy"></div>', 
     activated: function() { 
      if(initial state){ 
       cy1 = cytoscape({ 
        container: document.getElementById("container"), 
        elements: testElements 
       }); 
      } 

     } 
    }); 

这可能会有所帮助,因为当一个对象是保持活动状态挂载的挂钩仅在f在第一次输入组件时,在随后的输入中不会再次调用组件,而在每次输入组件时都会调用激活的钩子,此时保持活动状态

+0

谢谢您的回答! 虽然你说得对,这种方法可以防止网络视图冻结,但使用** keep-alive **的主要目的是在切换过程中保持组件的状态。如果我使用**激活的**挂钩,则此功能会丢失,并且每次访问组件时都会将网络重新加载到其初始状态。这是(对于这个例子)与丢弃** keep-alive **标签基本相同。 – PhJ

+0

@PhJ然后尝试在激活的钩子中使用if语句,只有当状态发生改变时才执行,否则保持不变 –

+0

我很抱歉,但现在我很困惑。据我了解你的建议,一方面网络会在每次改变时重新初始化(例如选择一个节点),这是我不想要的,因为我想预先保存这些改变(因此我尝试使用** keep-alive **功能)。另一方面,如果网络没有改变(这是好的),网络将不会被重新初始化,但是我仍然有问题,即Cytoscape实例以某种方式中断(最好通过测试节点选择或拖放是否仍然有效) 。 – PhJ