如何找出从组件内部单击的组件

时间:2018-05-07 20:00:44

标签: javascript vue.js

考虑我有一种类型的多个组件,如下所示:

<settings type="first">1</settings>
<settings type="second">2</settings>
<settings type="third">3</settings>
<settings type="fourth">4</settings>
<settings type="fifth">5</settings>

每个组件都是“组”的一部分,称为设置,但每个组件的工作略有不同 - 常见的是它是设置元素。 现在,因为每个人都做不同的工作,我在“设置”组件定义中有多个方法,但每个方法的行为都有所不同,具体取决于点击的组件:

Vue.component('settings',
    {
        template:  '<div class="setting" @click="selectIt">',
        props: ['type'],
        methods: {
            selectIt() {
               switch ( this.type ) {
                  case 'first':
                  console.log("first")
                  break;
                  case 'second':
                  console.log("second")
                  break;
               }
       }
   }
})

这里有问题:

  • 这是解决这类问题的好方法吗?也许每个设置应该是不同类型的组件?

  • 如何 - 以其他方式 - 找出从组件内部点击的设置?

2 个答案:

答案 0 :(得分:1)

如果您需要,每个组件都有自己的ID:

Vue.component('my-component', {
  template: '#my-component',
  data() {
    return {
      selected: false
    }
  },
  methods: {
    selectMe() {
      this.selected = !this.selected
      console.log(this._uid)
    }
  }
})

new Vue({
  el: '#app',
})
.card {
  background-color: #F5F5F5;
  border-radius: 8px;
  margin: 5px;
  padding: 5px 10px;
}
.selected {
  background-color: #B1B1B1;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>

<div id="app">
  <my-component>1</my-component>
  <my-component>2</my-component>
  <my-component>3</my-component>
  <my-component>4</my-component>
  <my-component>5</my-component>
</div>

<template id="my-component">
  <div class="card" :class="{'selected': selected }" @click="selectMe">
    <slot />
  </div>
</template>

答案 1 :(得分:0)

可能以下解决方案将满足您的要求。

我的意见:

  1. 添加一个prop =处理程序,然后为每个类型定义默认处理程序

  2. 如果父组件想要执行某些特殊逻辑,则将其自己的处理程序传递给settings组件。对于您的情况,似乎父组件知道需要做什么,但子组件不知道。所以父母将一个处理程序传递给孩子会更好(孩子不关心它在哪里,只需要做它的工作)。

  3. &#13;
    &#13;
    Vue.config.productionTip = false
    Vue.component('settings', {
            template:  '<div class="setting" @click="selectIt">{{type}}</div>',
            props: {
              'type':{
                type: String,
                default:'first'
              },
              'handlers':{
                type: Object,
                default: ()=>{ return {} }
              }
            },
            data() {
              return {
                defaultHandlers: { // define your handlers for each type at here
                  'first': ()=> {
                    console.log('first')
                  },
                  'second': ()=> {
                    console.log('second')
                  },
                  'third': ()=> {
                    console.log('third')
                  }
                },
                mergedHandlers: {}
              }
            },
            methods: {
                selectIt() {
                   if(this.type in this.mergedHandlers) {
                    this.mergedHandlers[this.type]()
                   } else { // if handler not found, do something
                    console.warn('handler not found')
                   }
                }
           },
           mounted: function(){
            // merge customize option with default handlers
            Object.assign(this.mergedHandlers,this.defaultHandlers,this.handlers)
           }
       }
    )
    app = new Vue({
      el: "#app",
      data: {
        message: "Puss In Boots"
      },
      methods: {
        customHandlerForSecond: function () { // pass customized handler to child component
          console.log('parent customized second for ' + this.message)
        }
      }
    })
    &#13;
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <div id="app">
      <settings type="first"></settings>
      <settings type="second" :handlers="{'second':customHandlerForSecond}"></settings>
      <settings type="third"></settings>
      <settings type="fourth"></settings>
      <settings type="fifth"></settings>
    </div>
    &#13;
    &#13;
    &#13;