1

所以我正在使用 Laravel Spark 构建一个应用程序,因此我趁机学习了一些 Vue.js。

我花了比我想要的时间更长的时间来解决它,但我几乎让 Vue-multiselect 为一组选项工作,其中选定的选项是通过获取请求检索然后更新的。

到目前为止,我所采用的方式可能远非最佳,所以请耐心等待,但它似乎只在大约 60% 的时间内加载选定的选项。需要明确的是 - 控制台中永远不会记录任何警告/错误,如果我检查网络选项卡,获取导师仪器的请求总是成功返回相同的结果......

我已经声明了一个全局数组准备好了:

var vm = new Vue({
    data: {
        tutorinstruments: []
    }
});

然后我的主要组件发出请求并更新变量:

    getTutor() {
        this.$http.get('/get/tutor')
            .then(response => {
                this.tutor = response.data;
                this.updateTutor();
            });
    },

    updateTutor() {
        this.updateTutorProfileForm.profile = this.tutor.profile;
        vm.tutorinstruments = this.tutor.instruments;
    },

我来自 Vue-multiselect 的自定义多选然后获取所有可用的工具并更新可用的工具,以及那些被选中的工具:

    getInstruments() {
        this.$http.get('/get/instruments')
            .then(response => {
                this.instruments = response.data;
                this.updateInstruments();
            });
    },

    updateInstruments() {
        this.options = this.instruments;
        this.selected = vm.tutorinstruments;
    },

可用的选项始终存在。

这是一个 YouTube 链接,如果您一遍又一遍地刷新页面,它的外观

我愿意接受任何建议,欢迎提供帮助!

4

2 回答 2

1

你的全局数组var vm = new Vue({...})是一个单独的 Vue 实例,它位于处理用户界面的主 Vue 实例之外。

这就是您在组件中同时使用的this原因vm。在您的方法中,this指向处理用户界面的 Vue 实例,同时vm指向您在 Vue 实例之外初始化的全局数组。

请再次查看此指南页面:https ://vuejs.org/v2/guide/instance.html

如果您查看初始化所有 Vue 功能的生命周期图,您会注意到它在很多地方都提到了Vue 实例。这些功能(反应性、数据绑定等)旨在在 Vue 实例中运行,而不是跨多个实例。它可能会在时机合适的时候偶尔起作用,但不能保证会起作用。

要解决此问题,您可以重新设计您的应用程序,使其拥有一个Vue 实例来处理用户界面和数据。

理想情况下,我希望您tutorinstruments被加载到初始化您的应用程序的代码中(使用mounted根组件中的钩子),并存储在Vuex 状态中。一旦你的数据处于Vuex 状态,所有组件都可以访问它。

Vuex 参考:https ://vuex.vuejs.org/en/intro.html

希望能帮助到你!我知道我没有直接解决你的问题。如果您无法将应用程序重组为单个 Vue 实例,也许我们可以等待更直接的答案。

于 2017-02-04T05:25:15.757 回答
1

Mani 写的是 100% 正确的,我要插话的原因是因为我刚刚用 PHP 和 Vue 构建了一个非常大规模的项目,我觉得我可以给你一些建议 /我在构建 PHP(服务器端)网站的过程中学到的东西,但在前端模板中添加了 Vue(客户端)。

这可能比您的多选问题的范围大一点,但我也会给您一个坚实的开端。

首先,您需要确定其中哪一个将在您的 Web 应用程序中进行路由(当用户访问正在处理流量的页面时),因为这将决定您使用 Vue 的方式。假设为了讨论,您决定使用 PHP 进行身份验证(如果您有登录名),但您将在前端使用 Vue 处理路由。在这种情况下,您肯定希望拥有一个主 Vue 实例,并且或多或少地设置类似于Vue Router中的这个示例的东西,假装 HTML 文件是您在 web 根目录中的 PHP index.php,这最终应该是就模板而言,您需要的唯一 .php 文件,我让它处理所有页眉元和页脚版权内容,在正文中,您基本上只需要一个带有 ID 应用程序的 div。

然后,您只需使用 vue 路由器和路由来加载所有页面的 vue 组件(每个页面或页面类别一个很容易工作)。如果您在主 app.vue 中查找并计算出使用动态组件来基于路由延迟加载页面组件,那么您的包会保持较小,那么您将获得奖励积分。

*提示你还需要一个带有 babel 的 polyfill 来做这个模板

<Component :is="dynamicComponent"/>

脚本

components: {
  Account: () => import('./Account/Account.vue'),
  FourOhFour: () => import('../FourOhFour.vue')
},
computed: {
  dynamicComponent() {
    return this.$route.name;
  }
},

既然我们在这里,我们可以处理您的多选问题(这基本上也将帮助您了解一种简单的方法,将您在网上找到的任何 Vue 组件加载到您的站点中)。在您的一个页面组件中,当有人访问路由时加载您可以说 /tutor (我还通过本地化将我的身份验证信息从 PHP 传递到我的路由中,然后使用道具、元字段和路由器防护,这一切都在该文档中所以如果你想探索,我会把它留给你)在tutor.vue上,我们会称你的页面组件是你想要在多选中调用的地方。同样在这一点上,我们仍然连接到我们的主 Vue 实例,所以如果你想引用它或你的路由来自 tutorial.vue,你几乎可以使用 Vue API 来代替 Vue 或 vm 来实现这一点。

这就是我从这一点开始处理添加外部组件的方式,将它们包装在您控制的另一个组件中,并使它们成为页面组件的子组件。这是一个非常简单的多选示例,假设父级是tutor.vue。

我还有一个全局事件总线正在运行,我想你可能会喜欢这个想法 https://alligator.io/vuejs/global-event-bus/

导师.vue

<template>
  <div
    id="user-profile"
    class="account-content container m-top m-bottom"
  >

    <select-input
      :saved-value="musicPreviouslySelected"
      :options="musicTypeOptions"
      :placeholder="'Choose an your music thing...'"
      @selected="musicThingChanged($event)"
    />

  </div>
</template>

<script>
import SelectInput from './SelectInput';
import EventBus from './lib/eventBus';

export default {
    components: {
        SelectInput
    },

    data() {
        return {
            profileLoading: true,
            isFullPage: false,
            isModalActive: false,
            slackId: null,
            isActive: false,
            isAdmin: false,
            rep: {
                id: null,
                status: '',
                started: '',
                email: '',
                first_name: '',
            },
            musicTypeOptions: []
        };
    },

    created() {
        if (org.admin) {
            this.isAdmin = true;
        }
        this.rep.id = parseInt(this.$route.params.id);
        this.fetchData();
    },

    mounted() {
        EventBus.$on('profile-changed', () => {
          // Do something because something happened somewhere else client side.
        });
    },

    methods: {
      fetchData() {
        // use axios or whatever to fetch some data from the server and PHP to 
        // load into the page component so say we are getting the musicTypeOptions 
        // which will be in our selectbox.
      },

      musicThingChanged(event) {
        // We have our new selection "event" from multiselect so do something
      }
    }
};
</script>

这是我们的子 Multiselect 包装器 SelectInput.vue

<template>
  <multiselect
    v-model="value"
    :options="options"
    :placeholder="placeholder"
    label="label"
    track-by="value"
    @input="inputChanged" />
</template>

<script>
import Multiselect from 'vue-multiselect';

export default {
    components: { Multiselect },
    props: {
        options: {
            type: [Array],
            default() {
                return [];
            }
        },

        savedValue: {
            type: [Array],
            default() {
                return [];
            }
        },

        placeholder: {
            type: [String],
            default: 'Select Option...'
        }
    },

    data() {
        return {
            value: null
        };
    },

    mounted() {
        this.value = this.savedValue;
    },

    methods: {
        inputChanged(selected) {
            this.$emit('selected', selected.value);
        }
    }
};
</script>

<style scoped>
@import '../../../../../node_modules/vue-multiselect/dist/vue-multiselect.min.css';
</style>

现在您可以确保您正在管理页面的生命周期以及何时拥有哪些数据,您可以等到获得 musicTypeOptions 后再将其传递给 SelectInput 组件,该组件将依次设置 ​​Multiselect 或任何其他组件,然后处理传递数据通过 this.$emit('hihiwhatever') 返回,它被模板中组件上的@hihiwhatever 拾取,该组件回调函数,现在您可以对新选择执行任何操作并将不同的数据传递给SelectInput 和 MultiSelect 将始终保持同步。

现在我的最后一条建议来自经验。抵制诱惑,因为您每天阅读 650 次有关它的内容,并且在这样的设置中使用 Vuex 似乎是正确的做法。您已经拥有 PHP 和数据库,使用它就像在 Node.js 中使用 Vuex 一样使用它,同时也有由 PHP 和数据库服务器端管理的数据,一旦您开始让多个用户登录并弄乱来自 PHP 服务器端的 Vuex 数据,您将无法保留一个点的真理。如果您没有服务器端数据库,可以使用 Vuex,但不要头疼,等到 100% 使用 Node.js 后再尝试。

如果您想管理比页面视图的生命周期更长的数据客户端,请使用https://github.com/gruns/ImmortalDB之类的东西,它对我很有帮助。

抱歉,这变成了一篇博文哈哈,但我希望它可以帮助某人拯救自己几个星期。

于 2019-01-05T03:30:47.240 回答