v-on单击,仅在满足条件的情况下添加处理程序

将会

经过研究,发现了Evan You先生的以下建议:https : //github.com/vuejs/vue/issues/7349#issuecomment-354937350

因此,我毫不犹豫地尝试了一下:

组件模板

<template>
  <div v-on='{ click: dataType === `section` ? toggleSectionElements : null }'>
    ... magic 
  </div>
<template>

JS逻辑

<script>
export default {
  name: `product-section`,
  props: [`section`, `sectionName`, `depth`],
  methods: {
    toggleSectionElements() {
      ... magic 
    }
  },
  computed: {
    dataType() {
      if (this.$props.section.sections || this.$props.depth === 0) {
        return `section`
      } else {
        return `element`
      }
    }
  }
}
</script>

但是对于所描述的情况,在渲染过程中会导致错误:

[Vue warn]: Invalid handler for event "click": got null

有人可以建议做错了什么吗?:思维:

更新
方式Data Model如下:

DataModel: {
  mainSectionA: {
    sections: {
      sectionA: {
        sections: {
          elementA: { values: { ... } },     
          elementB: { values: { ... } }
        }
        values: { ... }
      }
      sectionB: {
        elementA: { values: { ... } },
        elementB: { values: { ... } }
      }
    },
    values: { ... }
  },
  mainSectionB: {
    sections: {
      elementA: { values: { ... } },
      elementB: { values: { ... } },  
      elementC: { values: { ... } },
      ... elements
    },
    values: { ... }
  }
}
特里

而不是使用三元逻辑来污染模板,您实际上应该在点击处理程序中执行检查。这不仅使您的模板更具可读性,而且由于所有逻辑都已抽象并委托给事件处理程序的回调,因此使代码维护更加容易。

快速解决方案

因此,快速的解决方案是实际上确保toggleSectionElements()仅当存在正确的条件时,它们才会起作用dataType这可以通过使用guard子句来实现:

toggleSectionElements() {
  // Guard clause to prevent further code execution
  if (this.dataType() !== 'section')
    return;

  // Magic here
}

更好的是,如果应该为每个处理程序分配单独的处理程序,则dataType可以为此目的创建一个工厂函数:

methods: {
  // This is just a factory function
  toggleElements() {
    switch (this.dataType()) {
      case 'section':
        return this.toggleSectionElements;
      case 'element':
        // Something else...
    }
  },
  toggleSectionElements() {
    // Magic for section element
  }
}

意见建议:使用原子成分

由于将单击事件处理程序绑定到最终无能为力的元素可能会很昂贵,因此您也可以分解组件以使其更具原子性。集合元素将负责接收“部分”或“元素”的数组,并且每个“部分” /“元素”将具有其自己的组件,如下所示:

  • 您有一个collection组件,例如<my-collection>,其中包含所有“ section”和“ element”组件
  • “部分”组件将使用该<my-section>组件
  • “元素”组件将使用该<my-element>组件

这是VueJS真正强大的时候:您可以在内部使用动态组件<my-collection>来确定要使用的组件,具体取决于dataType遇到的情况。

这是v-for通过在整个集合中运行,然后使用v-bind:is="..."来确定特定的集合项应使用“节”还是“元素”来完成的。我知道这可能超出了您最初提出的问题的范围,但这是一个值得考虑的设计:

const collectionComponent = Vue.component('my-collection', {
  template: '#my-collection-component',
  data: function() {
    return {
      collection: [{
        dataType: 'section',
        description: 'Hello I am section 1'
      }, {
        dataType: 'element',
        description: 'Hello I am element 1'
      }, {
        dataType: 'section',
        description: 'Hello I am section 2'
      }, {
        dataType: 'element',
        description: 'Hello I am element 2'
      }]
    }
  },
  methods: {
    componentToUse(dataType) {
      return 'my-' + dataType;
    }
  }
});

const sectionComponent = Vue.component('my-section', {
  template: '#my-section-component',
  props: ['itemData'],
  methods: {
    toggle() {
      console.log('Doing some magic.');
    }
  }
});

const elementComponent = Vue.component('my-element', {
  template: '#my-element-component',
  props: ['itemData']
});

new Vue({
  el: '#app'
});
.box {
  border: 1px solid #999;
  cursor: pointer;
  margin: 10px;
  padding: 10px;
}

.box:hover {
  background-color: #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <my-collection />
</div>

<script type="text/x-template" id="my-collection-component">
  <div>
    <component
      v-for="(item, i) in collection"
      v-bind:key="i"
      v-bind:is="componentToUse(item.dataType)"
      v-bind:itemData="item" />
  </div>
</script>

<script type="text/x-template" id="my-section-component">
  <div @click="toggle" class="box">
    <h1>{{ itemData.dataType }}</h1>
    <p>{{ itemData.description }}</p>
    <p>Clicking on me will invoke a section-specific logic</p>
  </div>
</script>

<script type="text/x-template" id="my-element-component">
  <div class="box">
    <h1>{{ itemData.dataType }}</h1>
    <p>{{ itemData.description }}</p>
    <p>Clicking on me will do nothing</p>
  </div>
</script>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

仅在满足条件的情况下添加到dict

仅在满足特定条件的情况下如何使菜单可单击?

仅在满足某些条件的情况下添加单元格

仅在满足条件的情况下运行SQL查询

仅在满足条件的情况下更新行

仅在满足条件的情况下如何更新文档?

仅在满足条件的情况下才执行CHECK语句

仅在满足条件的情况下如何开始活动

仅在满足条件的情况下进行Rails模型计算

XML XPath-仅在满足子条件的情况下选择父文本

&& 运算符是否仅在满足前一个条件的情况下评估右侧?

仅在满足一个条件的情况下,ON DUPLICATE KEY UPDATE的Terser语法?

MySQL:仅在满足某些条件的情况下更新项目

仅在满足某些条件的情况下才尝试投射列

如何仅在满足特定条件的情况下运行后台任务?

仅在“详细信息”表满足条件的情况下,才如何获取“主行”表?

仅在满足条件的情况下,如何使用块创建link_to_if?

仅在满足条件的情况下如何执行rxjs转换运算符

如果仅在不满足条件的情况下进行一次循环,则循环停止

仅在满足某些前提条件的情况下,才可以触发转换器?

MongoDB:仅在满足条件的情况下才应用$ filter阶段?

默认情况下,如何排序v-data-table?

在v-navigation-drawer关闭的情况下加载网站

我只想在AngularJS满足条件的情况下添加JSON信息

zsh:在满足特定条件的情况下,向提示添加警告

如何使 v2 凭据提供程序在没有“ICredentialProviderUser”对象的情况下初始化其凭据?

v-for循环中的单个单击处理程序

在v-for的情况下如何从v-model输入更新Vuex存储

仅在满足某些条件时才使用 v-btn 更改路由