【问题标题】:Architecture vue application架构vue应用
【发布时间】:2019-03-04 16:41:58
【问题描述】:

应用程序具有各种工具(页面)及其结构。例如酒店搜索工具(在列表的左侧窗格中,在右侧地图上),或者报告工具(全宽页面),这样的工具有很多。

我在github 上发现了一个用于处理面板的有趣组件。然后他开始做这样的事情:

//MyPanes.vue
<splitpanes class="default-theme" horizontal>
        <span>
            <div class="left-panel"><slot name="left"></slot></div> 
        </span>
        <span splitpanes-min="20" splitpanes-max="50" :splitpanes-default="horizontal_splitter[1]">
            <div class="right-panel"><slot name="right"></slot></div>
        </span>
</splitpanes>

//HotelTool.vue      
<MyPanes>
      <template slot="left">
        <v-btn @click.native="add">Add counter</v-btn>
      </template>
      <template slot="right">
        <div>{{ counter }}</div>
        <v-map />
      </template>
</MyPanes>

..
data: {
   counter: 0
},
methods: {
   add() { this.counter++; }
}
.. 

计数器是为测试而设计的。但它不起作用。可能是因为slot的内容不知道parent的数据。

于是问题就来了。如何实现这种行为?需要放弃插槽?

当然,你可以通过event bus或者store来实现,但是我有很多工具,用这种方式传输数据不是很方便。我想在一个文件中创建仪器,在其中为左右部分编写逻辑,以便它们相互了解。所有工具也是如此。

你能分享你的想法吗?如何在单亲上下文中更改插槽之间的数据?还有其他解决方案吗?

Example tool Example tool 左侧和右侧可能有不同的组件。

完整代码:

<template>
    <MyPanes>
        <template v-slot:left>
            <h1>Мониторинг</h1>
            <v-btn @click.native="add">{{ counter }}</v-btn>
        </template>
        <template v-slot:right>
            {{counter}}
        </template>
    </MyPanes>
</template>

<script>
    export default {
        data() {
            return {
                counter: 0,
            }
        },
        methods: {
            add: function () {
                this.counter++;
            }
        }
    }
</script>

【问题讨论】:

    标签: javascript vue.js architecture


    【解决方案1】:

    场景解决方案

    这里的数据范围应该没有问题,因为对数据的引用都是在“HotelTool”实例中完成的。

    不要忘记 'data' 是一个在 Vue 中返回对象的函数:

    data() {
       return {
           counter: 0
       }
    },
    methods: {
       add() { this.counter++; }
    }
    

    请同时更新您的@click 事件,将 .native 替换为 .passive

    <v-btn @click.passive="add">Add counter</v-btn>
    

    拆分反应性

    Splitpanes 文档声称默认情况下在 their website 上禁用或阻止反应性。您可以添加 watch-slots 元素来恢复反应性。

    <splitpanes watch-slots class="default-theme" horizontal>
    ....
    

    一般答案:在 Vue 实例之间传递数据

    作为对未来读者提出相同问题的更一般的答案,可以通过以下方式在 Vue 中的实例之间共享数据:

    传递给道具和发射事件(推荐): VueJS.org Props 和, VueJS.org Custom Events

    全局数据“存储”: Vuex Guide

    我建议您习惯第一个选项,因为这在 Vue 文档中是推荐的,并且适用于大多数情况。 Vuex 方法开始对大型应用程序有用。

    提示:Vue 的控制台错误非常有用,通常是查找涉及范围的错误的首选位置。他们还提供 Chrome 扩展程序,以帮助实时查看您的应用程序状态。

    【讨论】:

    • 我在标题中插入了我的代码的详细示例。由于某种原因,这不起作用。计数器增加,但在插槽中它等于 0。
    • 尝试将点击事件从原生改为被动。我相信按钮的本机事件正在阻止您的点击事件触发添加功能。 @click.passive="add()" 代替 @click.native="add"
    • console.log (this.counter) - 有效,但 DOM 未更新
    • hrm... 尝试将 v-slot:left / v-slot:right 替换为 slot="left" / slot="right"。我已经设法在这里使用标准 DIV 标签而不是“splitpanes”元素获得了它的工作版本。我会尝试为你做一个 CodePen
    • 如果工具的所有部分都在同一个文件中(左、右)会很方便,并且它们会有通用的方法和变量。无需创建商店、事件总线等。
    猜你喜欢
    • 2018-09-03
    • 2018-01-28
    • 1970-01-01
    • 2019-03-19
    • 2014-04-21
    • 2018-09-14
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多