是否可以在不同的窗口中使用两个vue.js实例使用相同的数据?

时间:2016-02-11 03:34:24

标签: vue.js

我希望能够在我的vue.js应用程序中使用两个窗口,一个用于管理数据,另一个用于显示相同的数据。 (想象一下现场演示,我可以在笔记本电脑的一个窗口中动态更改内容,但我的观众看到数据的简化表示 - 即,他们看不到所有编辑工具 - 在一个单独的窗口中投影屏幕。)

作为原型,我尝试过实现一个基本的todo应用程序,如下所示:

<html>
<body id="app">

<div id="entry-form">

    <input type="text" placeholder="enter a todo item" v-model="todo">

    <button v-on:click="addTodo">+</button>

</div>

<div id="todo-list">
    <ol>
        <li v-for="t in todos">
            <span>{{ t }}</span><button v-on:click="delTodo">-</button>
        </li>
    </ol>
</div>

<button v-on:click="openViewer">Viewer</button>

<script src="vue.min.js"></script>

<script>
    var stateData = {
        todo : '',
        todos : [],
    }

    new Vue({
       el: '#app',
       data: stateData,

       methods : {
          addTodo : function() {
             if ( this.todo ) {
                this.todos.push(this.todo);
                this.todo = '';
             }
          },

          delTodo : function(index) {
             this.todos.splice(index,1);
          },

          openViewer : function() {
             var w = window.open("viewer.html", "viewer");
             w.getStateData = function() {
                return stateData;
             }
          }
       },
    });
</script>

</body>
</html>

然后是一个viewer.html(由上面文件中的openViewer函数打开),如下所示:

<html>
<body id="viewer">

<div id="todo-list">
    <ol>
        <li v-for="t in todos">
            <span>{{ t }}</span>
        </li>
    </ol>
</div>

<script src="vue.min.js"></script>
<script>
    window.onload = function() {
        new Vue({ el: "#viewer", data: getStateData() });
    }
</script>

</body>
</html>

这似乎让我在那里中途。我可以输入一些待办事项并单击“查看器”按钮,然后会打开第二个窗口,显示预期的待办事项。但是,当我在打开查看器窗口后开始输入新的待办事项时,事情开始表现得很奇怪。输入字段在模糊时清除,并且待办事项列表不再出现在主窗口中,但仍可在查看器窗口中使用。

显然,我正在滥用vue.js的工作方式。是我试图用vue.js实现的吗?如果是这样,请告诉我如何以vue.js方式完成这项工作?

由于

1 个答案:

答案 0 :(得分:3)

我认为localStorage API就是您所需要的。 localStorage在数据更新时触发事件 - 您可以从其他窗口读取的事件。

观看演示:http://html5demos.com/storage-events

信息链接到文档:Javascript; communication between tabs/windows with same origin

github上的一个库,用于处理交叉表通信,如果您有兴趣:https://github.com/diy/intercom.js/

我认为您希望在Vue组件中添加watch功能,每当stateData值更新时,您都希望更新localStorage中的相应变量。这会将事件发送到另一个窗口。类似的东西:

应用窗口:

new Vue({
    el: '#app',
    data: {
        todo : '',
        todos : [],
    },
    methods : {
        addTodo : function() {
            if ( this.todo ) {
                this.todos.push(this.todo);
                this.todo = '';
            }
        },
        delTodo : function(index) {
            this.todos.splice(index,1);
        },
        openViewer : function() {
            window.open("viewer.html", "viewer");
        }
    },
    watch:{
        stateData: {
            deep:true,
            handler:function(newValue){
                window.localStorage.setItem('viewer-demo',newValue);
            }
        }
    }
});

查看器窗口:

new Vue({ 
    el: "#viewer", 
    data: {
        stateData: {
            todo : '',
            todos : []
        }
    },
    ready:function(){
        addEvent(window, 'storage', function (event) {
            if (event.key == 'viewer-demo') {
                this.stateData = event.newValue;
            }
        }.bind(this));
    } 
});