【问题标题】:Vue.js 2.x Passing function to componentVue.js 2.x 向组件传递函数
【发布时间】:2018-02-13 00:49:48
【问题描述】:

我需要用不同的信息多次渲染同一个组件,当有人选择一些东西时,它应该在主 Vue 实例中加载一个函数。

到目前为止,我无法将动态函数作为属性传递,例如 @change="onchange"

[Vue 警告]: 事件“更改”的无效处理程序:未定义

发现于

---> 在 resources\assets\js\components\GeographyField.vue

组件:

<template>
    <fieldset class="form-group col-md">
        <label :for="name" class="control-label" v-html="label"></label>
        <select class="form-control" :name="name" :id="name" :model="_default" :disabled="disabled" @change="onchange">
            <option :value="0" v-html="placeholder"></option>
            <option v-for="object in collection" :value="object.id">{{ object.name }}</option>
        </select>
    </fieldset>
</template>

<script>
    module.exports = {
        props: {
            label: {
                type: String,
                default: 'Options'
            },
            _default: {
                type: Number,
                default: 0
            },
            disabled: {
                type: Boolean,
                default: false
            },
            placeholder: {
                type: String,
                default: 'Choose an option'
            },
            name: {
                type: String,
                required: true,
            },
            collection: {
                type: Array,
                required: true
            },
            onchange: {

            }
        },
        data: function() {
            return {

            }
        },
        methods: {

        }
    }
</script>


渲染:

<div class="row">
    <!-- Country -->
    <geography-field
            label="Pa&iacute;s"
            :_default="selectedCountry"
            placeholder="Choose a country"
            name="country"
            :collection="countries"
            :onchange="selectCountry()"
    ></geography-field>
    <!-- Department -->
    <geography-field
            label="Departamento"
            :_default="selectedDepartment"
            :disabled="selectedCountry < 1"
            placeholder="Choose a department"
            name="department"
            :collection="departments"
            :onchange="selectDepartment()"
    ></geography-field>
    <!-- Location -->
    <geography-field
            label="Localidades"
            :_default="selectedLocation"
            :disabled="selectedDepartment < 1"
            placeholder="Choose a location"
            name="location"
            :collection="localities"
            :onchange="selectLocation()"
    ></geography-field>
    <!-- Zone -->
    <geography-field
            label="Zonas"
            :_default="selectedZone"
            :disabled="selectedLocation < 1"
            placeholder="Choose a zone"
            name="zone"
            :collection="zones"
    ></geography-field>
</div>

编辑:包括selectCountry()

selectCountry: function() {
        if(this.selectedCountry < 1) { return; }
        axios.get('/get_country/' + this.selectedCountry)
            .then(function (response) {
                var data = response.data;
                if(data.departments.length > 0) {
                    var departments = [];
                    $.each(data.departments, function (index, value) {
                        departments.push(value);
                    });
                    app.departments = departments;
                }
            });
    },

我应该如何正确地将函数传递给组件?任何建议表示赞赏

编辑 2: 我可能要澄清的是组件渲染得很好。以防万一我会添加组件注册:

Vue.component('geography-field', require('./components/GeographyField'));
...
const app = new Vue({

【问题讨论】:

  • 方法都定义在new Vue({ ... methods: { ... } ..}或者父组件中?
  • @btl,selectCountry()selectDepartment()selectLocation() 方法在 *app.js^ 的父元素中定义,我在其中注册组件。
  • 您能否包含app.js 代码。可能会有所帮助
  • 我编辑了问题以包含一个函数作为示例,因为文件太长而无法包含。

标签: javascript vue.js vuejs2


【解决方案1】:

要将函数作为 prop 传递给组件,您需要去掉函数名称的尾括号。否则,Vue 将评估函数。例如:

<geography-field
  label="Pa&iacute;s"
  :_default="selectedCountry"
  placeholder="Choose a country"
  name="country"
  :collection="countries"
  :onchange="selectCountry" // strip off the parentheses
></geography-field>

但是,我还建议您使用 $emit 而不是传递函数。你可以这样做:

组件定义:

<template>
  <fieldset class="form-group col-md">
    <label :for="name" class="control-label" v-html="label"></label>
    <select class="form-control" :name="name" :id="name" :model="_default" :disabled="disabled" @change="onchange">
      <option :value="0" v-html="placeholder"></option>
      <option v-for="object in collection" :value="object.id">{{ object.name }}</option>
    </select>
  </fieldset>
</template>

<script>
module.exports = {
  props: {
    label: { type: String, default: 'Options' },
    _default: { type: Number, default: 0 },
    disabled: { type: Boolean, default: false },
    placeholder: { type: String, default: 'Choose an option' },
    name: { type: String, required: true },
    collection: { type: Array, required: true }
  },
  methods: {
    onchange() {
      this.$emit("onchange"); 
    }
  }
}
</script>

父作用域内的组件标签:

<geography-field
  label="Pa&iacute;s"
  :_default="selectedCountry"
  placeholder="Choose a country"
  name="country"
  :collection="countries"
  @onchange="selectCountry" // use @
></geography-field>

【讨论】:

  • @JacobGoh 如果您像 wang 建议的那样发出 onchange 事件,这是正确的。 +1 这个答案,因为它遵循道具向下,事件向上的约定。 vuejs.org/v2/guide/components.html#Composing-Components
  • 对不起..我的错。
  • 我将其标记为正确,但父元素 selectedCountry 仍然没有被更改
  • @Maramal 很可能是因为您在 &lt;select&gt; 标签上有 :model="_default" 而不是 v-model="_default"
  • 是的,经过几次测试,我已经检查过了。谢谢
【解决方案2】:

例如 :onchange="selectCountry"

传递函数时不要放()。它将触发函数执行,无论函数返回什么都将传递给onchange

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2023-03-04
  • 2020-06-21
  • 2017-03-31
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多