【问题标题】:vuejs target all anchor tag onclickvuejs针对所有锚标记onclick
【发布时间】:2019-03-13 03:51:47
【问题描述】:

我想在点击任何锚标记时调用一个方法。不可能在所有元素上定义@clickv-on

<a href="#">link1<a>
<a href="#">link2<a>
<a href="#">link3<a>
<a href="#">link4<a>
<a href="#">link5<a>

在 jquery 上我可以做到这一点

$('a').click(function(){
   //........
});

如何在 vuejs 中实现

注意:我的应用中有 10 多个组件,a 标记散布在组件的各个位置。

【问题讨论】:

  • jquery 将与 vuejs 一起运行,因此您也可以在 vuejs 中使用它
  • 你想调用什么"method"?是 Vue 实例/组件method?需要向它传递什么数据?
  • @Phil 当任何a 在任何组件中单击时,我将添加转换 (transitPage()) 页面
  • transitPage() 存在于哪里?它需要什么数据?
  • 等一下……所有这些“链接”都是应用程序内部的吗?如果是这样,他们不是通过 Vue 的router 吗?如果是这样,您将在此处创建过渡。

标签: vue.js


【解决方案1】:

您可以在父/容器元素上附加点击处理程序,并通过event.target检测目标/子元素被点击:

new Vue({
  el: '#app',

  methods: {
    clicked(e) {
      const container = e.currentTarget; // FYI
      const anchor = e.target;
      
      console.log(`${anchor.innerHTML} was clicked!`);
    }
  }
})

Vue.config.devtools = false;
Vue.config.productionTip = false;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div class="container" @click="clicked">
    <a href="#">Link #1</a>
    <a href="#">Link #2</a>
    <a href="#">Link #3</a>

    <!-- more anchor elements here -->
  </div>
</div>

【讨论】:

  • 仍然是同样的问题,因为我有 10 多个组件和 a 标签散布在每个地方
【解决方案2】:

这似乎不是一个好主意,但您可以“观察”变化。在这种情况下到链接的集合,然后附加一个事件处理程序...

注意:我没有对此进行测试,但它应该能让你朝着正确的方向前进

var vm = new Vue({
      el: '#example',
      data: {
        linkList
      },
      // update the items in linkList when the DOM is ready
      mounted(){
        this.linkList = document.getElementsByTagName('a');
      },
      // watch for changes to linkList and do something
      watch: {
        linkList: function(){
          for( var i=0; i < linkList.length; i ++ ){
          LinkList[i].onclick = linkAction;
          }
        }
      },
      methods: {
        linkAction: function (event) {
          alert(event.target.tagName)
        }
      },
    })

编辑:阅读有关目标的 cmets 后,您应该让 vue-router 处理部分之间的转换。我假设您不想编辑每个组件,因此请查看路由器内部的Dynamic Transitions

在这种情况下,您将“监视”$route 数据的更改并在那里执行您的操作:

watch: {
  '$route' (to, from) {
    // to & from are data in the route object telling you which components are being shown
    const toPath = to.path;
    function(){
      // do some action
      }
    }
  }

无论用于触发路由的标签如何,这都会起作用...

【讨论】:

  • 您的答案很接近,但仍在寻找更有效的解决方案
  • 嗯,这并不是低效的,因为链接列表应该只是在任何给定时间在 DOM 中的内容。但是,这种结构与 Vue 的使用方式背道而驰(Vue 期望响应数据变化)。
【解决方案3】:

嗯,你可以通过在data下定义链接并循环通过v-for指令来实现

第一道

new Vue({
  el: "#app",
  data: {
    links: [
      { link: "first Link" },
      { link: "second Link" },
      { link: "Third Link" },
      { link: "Fourth Link" }
    ]
  },
  methods: {
  	onAnchor: function(e){
    	console.log("Clicked on", e.target.innerHTML);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <h2>Todos:</h2>
    <p v-for="link in links">
    <a href="#" @click="onAnchor">{{link.link}}</a>
    </p>
</div>

第二种方式

为 a 创建一个包装器组件并在整个应用程序中使用它。

Vue.component('An', {
  template: '#anchor',
  props: ['link']
})

new Vue({
  el: "#app",
  data: function() {
  	return {
    	links: [
      { link: "first Link", text:'first Link' },
      { link: "second Link", text:'second Link' },
      { link: "Third Link", text:'third Link' },
      { link: "Fourth Link", text:'Fourth Link' }
    ]
    }
  },
  methods: {
  	changeText(event) {
    	console.log(event)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h2>Anchor</h2>
  <p v-for="link in links">
    <An :link="link" v-on:on-click="changeText($event)"></An>
  </p>
</div>

<script type="text/x-template" id="anchor">
  <p>
    <a href="#" v-on:click="$emit('on-click', link.text)"> {{link.link}}</a>
  </p>
</script>

希望这会有所帮助!

【讨论】:

  • 感谢您的回答,它不会满足我的要求,因为我想在任何a 点击触发方法。我的应用中有很多页面(组件)和数百个a
  • 如果你想从多个组件触发同一个事件,你可以借助 Vuex 状态管理。我可以补充答案。
猜你喜欢
  • 2015-06-11
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 2019-10-06
  • 1970-01-01
  • 2017-12-22
相关资源
最近更新 更多