【问题标题】:Vue.js pass function as prop and make child call it with dataVue.js 将函数作为道具传递并让孩子用数据调用它
【发布时间】:2017-01-21 12:39:31
【问题描述】:

我有一个帖子列表组件和一个帖子组件。

我将一个从帖子列表调用的方法传递给帖子组件,所以当一个按钮被点击时,它将被调用。

但我想在点击此功能时传递帖子ID

代码:

let PostsFeed = Vue.extend({
    data: function () {
        return {
          posts: [....]
        }
    },
    template: `
      <div>
        <post v-for="post in posts" :clicked="clicked" />
      </div>
    `,
    methods: {
      clicked: function(id) {
        alert(id);
      }
    }
  }
                           
  let Post = Vue.extend({
    props: ['clicked'],
    data: function () {
        return {}
    },
    template: `
      <div>
        <button @click="clicked" />
      </div>
    `
}

正如您在 Post 组件中看到的那样,您有一个运行他从道具获得的方法的点击,我想向该方法添加一个变量。

你是怎么做到的?

【问题讨论】:

    标签: javascript vue.js vue-component


    【解决方案1】:

    通常,click 事件处理程序将接收该事件作为其第一个参数,但您可以使用 bind 告诉函数将什么用于其 this 和第一个参数:

    :clicked="clicked.bind(null, post)
    

    更新答案:但是,让子 emit 事件并让父处理它可能更直接(并且更符合 Vue 标准)。

    let Post = Vue.extend({
      template: `
          <div>
            <button @click="clicked">Click me</button>
          </div>
        `,
      methods: {
        clicked() {
          this.$emit('clicked');
        }
      }
    });
    
    let PostsFeed = Vue.extend({
      data: function() {
        return {
          posts: [1, 2, 3]
        }
      },
      template: `
          <div>
            <post v-for="post in posts" @clicked="clicked(post)" />
          </div>
        `,
      methods: {
        clicked(id) {
          alert(id);
        }
      },
      components: {
        post: Post
      }
    });
    
    new Vue({
      el: 'body',
      components: {
        'post-feed': PostsFeed
      }
    });
    <script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
    <post-feed></post-feed>

    【讨论】:

    • 删除props: ['clicked'],
    • 只是对此的跟进,但感觉这是非常隐含的行为,很难跟踪可能发出的事件。有没有办法在组件定义的顶层声明这个?
    • 我不这么认为。通常组件很小,可以直接检查模板以查看 v-ons 调用了哪些方法,以及查看哪些方法发出了哪些事件。
    • 无赖 - 希望不必在我所有的表单提交事件中写 .stop.prevent,并创建一个自定义表单,它会这样做一次以隐藏丑陋。将函数作为参数传递似乎是实现此目的的 javascript 方式,但是哦。
    • @RoyJ 无需绑定。您所要做的就是:单击:() => alert(id)
    【解决方案2】:

    使用 Vue 2 并扩展上面 @Roy J 的代码,我在子组件 (Post) 中创建了一个方法,该方法调用 prop 函数并将数据对象作为回调的一部分发回。我还把帖子作为道具传入,并在回调中使用了它的 ID 值。

    回到 Posts 组件(父级),我修改了 clicked 函数,通过引用事件并以这种方式获取 ID 属性。

    查看工作的Fiddle here

    这是代码:

    let Post = Vue.extend({
      props: {
        onClicked: Function,
        post: Object
      },
      template: `
          <div>
            <button @click="clicked">Click me</button>
          </div>
        `,
      methods: {
        clicked() {
            this.onClicked({
            id: this.post.id
          });
        }
      }
    });
    
    let PostsFeed = Vue.extend({
      data: function() {
        return {
          posts: [
            {id: 1, title: 'Roadtrip', content: 'Awesome content goes here'},
            {id: 2, title: 'Cool post', content: 'Awesome content goes here'},
            {id: 3, title: 'Motorcycle', content: 'Awesome content goes here'},
          ]
        }
      },
      template: `
          <div>
            <post v-for="post in posts" :post="post" :onClicked="clicked" />
          </div>
        `,
      methods: {
        clicked(event) {
          alert(event.id);
        }
      },
      components: {
        post: Post
      }
    });
    
    new Vue({
      el: '#app',
      components: {
        'post-feed': PostsFeed
      }
    });
    

    这是 HTML

    <div id="app">
        <post-feed></post-feed>
    </div>
    

    【讨论】:

      【解决方案3】:

      这是服务:

      export const getBuilding = () => {
        console.log("service");
        return 0;
      };
      

      在父组件中:

      <Update-Theme :method="parentMethod"/>
      
      import { getBuilding } from "./service";
      methods: {
          parentMethod() {
            console.log("Parent");
            getBuilding();
          },
      }
      

      在子组件中

      <v-btn color="green darken-1" text @click="closeDialog()">
      props: [ "method"],
       methods: {
          closeDialog() {
            this.method();
            //this.$emit("update:dialog", false);
          },
      }
      

      【讨论】:

        猜你喜欢
        • 2020-08-05
        • 2023-03-19
        • 2015-09-16
        • 2021-02-17
        • 2017-08-03
        • 1970-01-01
        • 2019-08-08
        • 1970-01-01
        • 2020-07-16
        相关资源
        最近更新 更多