Javascript Vue v-on:单击不适用于组件

Javascript Vue v-on:单击不适用于组件,javascript,vue-component,vuejs2,vue.js,Javascript,Vue Component,Vuejs2,Vue.js,我试图在组件中使用on-click指令,但它似乎不起作用。当我点击组件时,当我应该在控制台中点击“测试”时,什么都不会发生。我在控制台中没有看到任何错误,所以我不知道我做错了什么 index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vuetest</title> </head> <body&

我试图在组件中使用on-click指令,但它似乎不起作用。当我点击组件时,当我应该在控制台中点击“测试”时,什么都不会发生。我在控制台中没有看到任何错误,所以我不知道我做错了什么

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>vuetest</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

vuetest
App.vue

<template>
  <div id="app">
    <test v-on:click="testFunction"></test>
  </div>
</template>

<script>
import Test from './components/Test'

export default {
  name: 'app',
  methods: {
    testFunction: function (event) {
      console.log('test clicked')
    }
  },
  components: {
    Test
  }
}
</script>
<blog-post
  @enlarge-text="onEnlargeText"
/>

从“./components/Test”导入测试
导出默认值{
名称:“应用程序”,
方法:{
testFunction:函数(事件){
console.log('已单击测试')
}
},
组成部分:{
试验
}
}
Test.vue(组件)


点击这里
导出默认值{
名称:'测试',
数据(){
返回{
msg:'欢迎使用您的Vue.js应用程序'
}
}
}

如果要侦听组件根元素上的本机事件,必须使用
v-on的修饰符,如下所示:

<template>
  <div id="app">
    <test v-on:click.native="testFunction"></test>
  </div>
</template>

或者简而言之,正如评论中所建议的,您也可以这样做:

<template>
  <div id="app">
    <test @click.native="testFunction"></test>
  </div>
</template>


我认为,
$emit
函数更适合您的要求。它将您的组件与Vue实例分开,以便在许多上下文中可重用

// Child component
<template>
  <div id="app">
    <test @click="$emit('test-click')"></test>
  </div>
</template>
//子组件
在HTML中使用它

// Parent component
<test @test-click="testFunction">
//父组件

组件的本机事件不能直接从父元素访问。相反,您应该尝试
v-on:click.native=“testFunction”
,或者您也可以从
Test
组件发出事件。像
v-on:click=“$emit('click')”
有点冗长,但我就是这样做的:

@click=“$emit('click',$event)”


更新:示例由@sparkyspider添加


div容器中
组件


内分区
这是最重要的,但有细节


注意:如果您不想修改组件或无权访问组件,则更适合


为什么@click不能正常工作? 组件是复杂的。一个组件可以是一个小的花式按钮包装器,另一个组件可以是一个包含大量逻辑的整个表。当绑定
v-model
或使用
v-on
时,Vue不知道您希望得到什么,所以所有这些都应由组件的创建者处理

如何处理点击事件 根据,
$emit
将事件传递给父级。文档中的示例:

主文件

<template>
  <div id="app">
    <test v-on:click="testFunction"></test>
  </div>
</template>

<script>
import Test from './components/Test'

export default {
  name: 'app',
  methods: {
    testFunction: function (event) {
      console.log('test clicked')
    }
  },
  components: {
    Test
  }
}
</script>
<blog-post
  @enlarge-text="onEnlargeText"
/>

正如Chris Fritz(Vue.js)在

如果我们使用Kia enter
.native
,然后基本输入的根元素突然从一个输入更改为一个标签,那么这个组件就被破坏了,而且不明显,事实上,除非您有一个非常好的测试,否则您甚至可能无法立即捕获它。相反,避免使用<代码> .NET< /COD>修饰符>强>,我目前认为反模式将在VUE 3 中删除。您可以明确地定义,父方可能关心添加到……/P>中的元素监听器。 使用Vue 2 使用
$listeners
: 因此,如果您使用的是Vue 2,解决此问题的更好选择是使用完全透明的包装逻辑。为此,Vue提供了一个
$listeners
属性,其中包含组件上使用的侦听器对象。例如:

{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}
然后我们只需要将
v-on=“$listeners”
添加到
test
组件中,如:

Test.vue(子组件)

div.child{边框:5px点橙色;填充:20px;}

来自:

由于JavaScript的限制,Vue无法检测到对数组的以下更改:

  • 直接使用索引设置项时,例如vm.items[indexOfItem]=newValue
  • 修改数组长度时,例如vm.items.length=newLength
  • 在我的例子中,我在从Angular迁移到VUE时偶然发现了这个问题。修复非常简单,但很难找到:

    setValue(index) {
        Vue.set(this.arr, index, !this.arr[index]);
        this.$forceUpdate(); // Needed to force view rerendering
    }
    

    或者速记
    @click.native=“testFunction”
    什么是本机事件,或者它与其他正常事件有何不同?为什么根元素会出现这种特殊情况??@MrClan native修饰符不建议在vue中使用。只有在绝对必要时才使用它。请参阅@jim mcneely以了解实现此目的的正确方法,即从子元素发出事件,然后在父元素中重新激活它。以下是正确的链接,我相信这是正确的答案。在组件内处理事件的链接。不要关心要调用的click事件的“版本”的父组件。实际上,我在组件
    @click=“$emit('click')”
    中实现了它,这样父组件就可以使用常规的
    @click
    ,我有点困惑。$emit部分应该在测试组件模板中吗?@NelsonRodriguez说。使用
    @click=“$emit('click')”
    。与
    .native
    修饰符相比,这无疑是更明确的解决方案,并使父组件更少依赖于子组件的实现细节,这几乎总是一个加号。这是怎么回事?你为什么把它放在那里?请为查看此答案的用户添加更多详细信息?在本例中,这将放置在Test.vue组件中的div标记上。然后,当在App.vueI中使用组件测试时,您可以使用v-on:click=“testFunction”或@click=“testFunction”将其更改为
    $emit
    ,但什么也没有发生。除了
    $emit
    ,我还需要做什么吗@RichardBarraclough您的组件现在发出自定义事件“clickTreeItem”。下一步是处理在使用该组件时如何处理该事件:v-on:myEvent=“myMethod”
    <button v-on:click="$emit('click', $event)">
      Enlarge text
    </button>
    
    {
      focus: function (event) { /* ... */ }
      input: function (value) { /* ... */ },
    }
    
    <template>
      <div v-on="$listeners">
        click here
      </div>
    </template>
    
    setValue(index) {
        Vue.set(this.arr, index, !this.arr[index]);
        this.$forceUpdate(); // Needed to force view rerendering
    }