Vue.js 2.x将函数传递给组件

Mar*_*mal 0 javascript vue.js vuejs2

我需要使用不同的信息多次渲染相同的组件,当有人选择它时,它应该在主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>
Run Code Online (Sandbox Code Playgroud)


渲染:

<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>
Run Code Online (Sandbox Code Playgroud)

编辑:包括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;
                }
            });
    },
Run Code Online (Sandbox Code Playgroud)

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

编辑2:我可能清理的是组件正在渲染良好.以防我将添加组件注册:

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

小智 5

要将函数作为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>
Run Code Online (Sandbox Code Playgroud)

但是,我还建议您使用$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>
Run Code Online (Sandbox Code Playgroud)

父范围中的组件标记:

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