【问题标题】:How to get the component triggered in parent vue?如何在父 vue 中触发组件?
【发布时间】:2019-11-23 23:53:47
【问题描述】:

我正在使用 Laravel 6(混合)+ Vue.js 2。

我正在创建一个多语言词典,用户可以在其中添加单词,并且他们可以为每个单词添加多个定义及其翻译。

内部index.blade.php

<div class="modal fade" id="modal-addItem">
    <form>
        <div class="card" v-for="(value, index) in nbDefinitions">
            <div class="card-header">@{{ value }}.</div>
            <div class="card-body">
                <dl class="row">
                    <dt class="col-sm-3">English</dt>
                    <dd class="col-sm-9">
                        <autocomplete data-language="english" :search="searchDefinition" :get-result-value="getDefinitionResultValue" @submit="handleSearchDefinitionSubmit"></autocomplete>
                    </dd>
                    <dt class="col-sm-3">French</dt>
                    <dd class="col-sm-9">
                        <autocomplete data-language="french" :search="searchDefinition" :get-result-value="getDefinitionResultValue" @submit="handleSearchDefinitionSubmit"></autocomplete>
                    </dd>
                </dl>
            </div>
        </div>
        <div class="row">
            <button type="button" class="btn btn-primary" id="addItems-addDefinition" @click="addDefinition">+ Add definition</button>
        </div>
    </form>
</div>

内部myCustom.js

new Vue({
    el: '#modal-addItem',
    data:  {
        nbDefinitions: 0,
        nbSentencesPerDef: [],
        translatedDefinitions: []
    },
    methods: {
        addDefinition: function() {
            this.nbDefinitions++;
            this.nbSentencesPerDef.push(1);
            this.translatedDefinitions.push({
                english: null,
                french: null
            });
        },
        searchDefinition: function (input) {
            // How can I know which <autocomplete> is triggered?
            return new Promise(resolve => {
                if (input.length < 3) { return resolve([]); }
                fetch(`/api/v1/definitions?search=${encodeURI(input)}`)
                .then(response => response.json())
                .then(responseJson => {
                    resolve(responseJson.definitions);
                })
            })
        },
        getDefinitionResultValue: function(result) {
            // How can I know which <autocomplete> is triggered?
            let definition = result.definition;
            let item = result.item.name;
            return `${item} - ${definition}`;
        },
        handleSearchDefinitionSubmit: function(result) {
            // How can I know which <autocomplete> is triggered?
            console.log(this);
        }
    }
});

我正在使用autocomplete,这是一个全局加载的外部组件(在 Laravel 主 app.js 中)https://autocomplete.trevoreyre.com/#/

我的问题是:我如何知道在“addDefinition”、“searchDefinition”和“handleSearchDefinitionSubmit”方法中被触发的子组件是什么?因为我的 Vue 对象中有 3 个自动完成组件,而 this 指的是根(在我的情况下是 html 模态),所以我不知道触发了哪个自动完成子项。 this.$refs 也是空的。

也许这是一个架构问题,但我没有足够的经验知道如何完成它。

【问题讨论】:

  • 您是否对示例中显示的语言进行硬编码?如果是这样,您总是可以创建 searchEnglishDefinitionsearchFrenchDefinition 等调用 searchDefinition 像 searchDefintion(input, 'english')
  • 或者 - 看看this issue - 这不是你要问的,但它可能会有所启发

标签: javascript laravel vue.js vuejs2 vue-component


【解决方案1】:

组件本身并不直接支持这一点(例如,通过将自身作为函数的参数传递)。但幸运的是,在作为 props 传递的函数的情况下,我们可以使用称为“闭包”的 JS 特性——而不仅仅是函数名称,而是调用一个返回另一个函数的函数。如果发生事件,我们可以使用 Vue 的特性,允许我们在定义处理程序时访问特殊的 '$event' 值。

像这样:

  • 之前:&lt;autocomplete data-language="english" :search="searchDefinition" @submit="handleSearchDefinitionSubmit" /&gt;
  • 之后:&lt;autocomplete data-language="english" :search="getSearchDefinitionFunc('english')" @submit="handleSearchDefinitionSubmit($event, 'english')" /&gt;

...并像这样更改您的方法:

    getSearchDefinitionFunc(lang) {
      return input => this.searchDefinition(input, lang);
    },
    searchDefinition: function(input, lang) {
      console.debug(`searchDefinition called with "${input}" and "${lang}"`);

      if (input.length < 3) {
        return Promise.resolve([]);
      }

      // ...don't create new Promise, just return an existing one
      return fetch(`/api/v1/definitions?search=${encodeURI(input)}`)
          .then(response => response.json())
          .then(responseJson => responseJson.definitions);
    },
    handleSearchDefinitionSubmit: function(result, lang) {
      console.log(`Submit: ${lang}`);
    }

我还稍微重构了您的代码,因为不需要创建新的 Promise。

您可以找到工作示例here

可以通过在组件数据 (['english', 'french']) 中定义您的语言并使用 v-for 生成每一行来进一步重构

【讨论】:

    猜你喜欢
    • 2021-09-17
    • 2017-08-08
    • 1970-01-01
    • 2022-10-16
    • 2017-03-29
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多