Javascript 如何在Vue.js中的组件之间共享方法?

Javascript 如何在Vue.js中的组件之间共享方法?,javascript,vue.js,Javascript,Vue.js,查看这个简单的购物车演示: 用户可以选择一个蔬菜和一个水果,它将被添加到购物车数组中。添加水果/蔬菜的函数非常相似,我想将其组合成一个可以在两个组件之间共享的函数 selectFruit: function(product){ var cart = this.cart for(p in cart){ if (cart[p]["type"] == "fruit"){ console.log("We already got a

查看这个简单的购物车演示:

用户可以选择一个蔬菜和一个水果,它将被添加到购物车数组中。添加水果/蔬菜的函数非常相似,我想将其组合成一个可以在两个组件之间共享的函数

    selectFruit: function(product){
       var cart = this.cart
       for(p in cart){
       if (cart[p]["type"] == "fruit"){
           console.log("We already got a fruit!, Let's remove " + cart[p]["name"] + " and add in " + product["name"]);
              this.cart.$remove(cart[p])
             }
            }
            console.log("Adding " + product.name + " to cart.");
            var productName = product.name
            var cartFruit = {name: product.name, type: 'fruit'}
            this.cart.push(cartFruit)
}

selectVeggie: function(product){
    var cart = this.cart
    for(p in cart){
        if (cart[p]["type"] == "veggie"){
           console.log("We already got a veggie!, Let's remove " + cart[p]["name"] + " and add in " + product["name"]);
           this.cart.$remove(cart[p])
        }
    }
    console.log("Adding " + product.name + " to cart.");
    var productName = product.name
    var cartVeggie = {name: product.name, type: 'veggie'}
    this.cart.push(cartVeggie)
}

我怎样才能改变这种方法并使其在全球范围内使用?我正在使用这个项目的Vue路由器顺便说一句,感谢任何帮助

您可以将该方法放在根Vue实例中,然后在选择veggie或水果时从子实例发送事件。事件在其父组件上查找处理程序,如果找不到事件处理程序,则继续沿着链向上搜索,直到找到为止。因此,在您的根实例上:

events: {
    'choose-fruit':function(fruit){

        //handle the choosing of fruit

    }
}
然后在子实例上:

selectFruit: function(product){

    this.$dispatch('choose-fruit', product);

}

选项1

跨组件共享方法的一种方法是使用mixin。下面是一个包含
selectProduct
方法的
cartMixin

var cartMixin = {
  methods: {
    selectProduct: function (product) {
      var cart = this.cart
      for(p in cart){
          if (cart[p]["type"] == product.type){
             console.log("We already got a "+ product.type +"!, Let's remove " + cart[p]["name"] + " and add in " + product["name"]);
             this.cart.$remove(cart[p])
          }
      }
      console.log("Adding " + product.name + " to cart.");
      var productName = product.name
      var cartProduct = {name: product.name, type: product.type}
      this.cart.push(cartProduct)
    }
  }
};
您可以在每个组件中引用它,如下所示:

var Vegetable = Vue.extend({
    template: '#vegetable',
    mixins: [cartMixin],
    data: function(){
        return sourceOfTruth
    }
})
<li v-for="product in food | showOnly 'fruit'" @click="selectProduct(product)">
  {{product.name}}
</li>
。。。然后在模板中使用它,如下所示:

var Vegetable = Vue.extend({
    template: '#vegetable',
    mixins: [cartMixin],
    data: function(){
        return sourceOfTruth
    }
})
<li v-for="product in food | showOnly 'fruit'" @click="selectProduct(product)">
  {{product.name}}
</li>


鉴于您的水果和蔬菜模板非常相似,您可能可以进一步利用这个想法,并使用基本组件中的通用模板。

我发现这种技术更简单/令人满意,因为我更喜欢组合而不是继承:

var Product = Vue.extend({
  data: function(){
      return sourceOfTruth
  },
  methods: {
    selectProduct: function (product) {
      var cart = this.cart
      for(p in cart){
          if (cart[p]["type"] == product.type){
             console.log("We already got a "+ product.type +"!, Let's remove " + cart[p]["name"] + " and add in " + product["name"]);
             this.cart.$remove(cart[p])
          }
      }
      console.log("Adding " + product.name + " to cart.");
      var productName = product.name
      var cartProduct = {name: product.name, type: product.type}
      this.cart.push(cartProduct)
    }
  }
})

var Vegetable = Product.extend({
  template: '#vegetable',
});
var Fruit = Product.extend({
  template: '#fruit',
});
src/shared.js src/yourcomponent.vue
。。。
从“./shared”导入共享
导出默认值{
已创建(){
this.foo=shared.foo//现在可以调用this.foo()(在函数/模板中)
}
}
这还允许您编写Vue不可知测试

注意:如果需要在Vue作用域中运行foo,请将
this.foo=shared.foo
替换为
this.foo=shared.foo.bind(this)


如果您试图在多个vue模板和布局之间或沿着多个vue模板和布局共享相同的组件逻辑,您只需尝试以下方法:

之前:

a、 vue
我认为它应该是
import shared from./shared'
而不使用shared周围的引号。为了在模板中使用它,您可以向您的方法添加函数,例如
export default{name:'componentName',methods:{shared,}
@GiorgioTempesta您可以添加更多方法吗?是的,您可以,假设您导入它们并用逗号分隔每个方法。另外,如果需要使用不同的名称调用该方法,则必须声明如下:
方法:{'new_method_name':shared,'other_method_name':shared2}
您好,如何与此方法异步,请问语法是什么?是否导出默认值{async foo:function(){alert(“foo!”)}请注意,
$dispatch
在Vue 2.0中已被删除,尽管您可以使用
$emit
$on
$off
来替换它:我认为选项1是Vue中最“正确”的答案。。。不幸的是,mixin的名字不太清楚,可能应该称为addin、addon、Extenders、ShareMes等等。
<template>
  <div>
     <h1>{{title}}</h1>
     <small>{{datetime}}</small>
  </div>
</template>

<script>
export default {
  props: {
    title: String
  },
  data() {
    return {
      datetime: new Date()
    }
  }
}
</script>
<template>
  <div>
     <h3>{{title}}</h3>
     <h6>{{datetime}}</h6>
  </div>
</template>

<script>
export default {
  props: {
    title: String
  },
  data() {
    return {
      datetime: new Date()
    }
  }
}
</script>

<template>
  <div>
     <h1>{{title}}</h1>
     <small>{{datetime}}</small>
  </div>
</template>

<script>
import shared from "./shared.js";
export default Object.assign({}, shared);
</script>
<template>
  <div>
     <h3>{{title}}</h3>
     <h6>{{datetime}}</h6>
  </div>
</template>

<script>
import shared from "./shared.js";
export default Object.assign({}, shared);
</script>
export default {
  props: {
    title: String
  },
  data() {
    return {
      datetime: new Date()
    }
  }
}