Vue v-on: клик не работает на компоненте
Я пытаюсь использовать директиву 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>
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>
Test.vue(компонент)
<template>
<div>
click here
</div>
</template>
<script>
export default {
name: 'test',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
Ответы
Ответ 1
Если вы хотите прослушать родное событие в корневом элементе компонента, вы должны использовать модификатор . native для 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>
Ответ 2
Я думаю, что функция $emit
работает лучше, чем я думаю, о чем вы просите. Он сохраняет ваш компонент отдельно от экземпляра Vue, чтобы он многократно использовался во многих контекстах.
<template>
<div id="app">
<test @click="$emit('test-click')></test>
</div>
</template>
Использовать его в HTML
<test @test-click="testFunction">
Ответ 3
Нативные события компонентов не доступны напрямую из родительских элементов. Вместо этого вы должны попробовать v-on:click.native="testFunction"
, или вы также можете v-on:click.native="testFunction"
событие из компонента Test
. Как v-on:click="$emit('click')"
.
Ответ 4
Немного многословно, но вот как я это делаю:
@click="$emit('click', $event)"
Ответ 5
Это ответ @Neps, но с деталями.
Примечание: ответ @Saurabh больше подходит, если вы не хотите изменять свой компонент или не имеете к нему доступа.
Почему @click просто не работает?
Компоненты сложны. Один компонент может представлять собой небольшую необычную оболочку для кнопок, а другой - целую таблицу с кучей логики внутри. Vue не знает, что именно вы ожидаете, когда связываете v-model
или используете v-on
поэтому все это должно обработать создатель компонента.
Как обрабатывать событие клика
Согласно Vue docs, $emit
передает события родителю. Пример из документов:
Основной файл
<blog-post
@enlarge-text="onEnlargeText"
/>
Составная часть
<button @click="$emit('enlarge-text')">
Enlarge text
</button>
(@
- это сокращение от v-on
)
Компонент обрабатывает собственное событие click
и генерирует parent @enlarge-text="..."
enlarge-text
можно заменить click
чтобы он выглядел так, как будто мы обрабатываем собственное событие щелчка:
<blog-post
@click="onEnlargeText"
></blog-post>
<button @click="$emit('click')">
Enlarge text
</button>
Но это еще не все. $emit
позволяет передавать определенное значение с событием. В случае встроенного click
значением является MouseEvent (событие JS, которое не имеет ничего общего с Vue).
Vue сохраняет это событие в переменной $event
. Таким образом, было бы лучше создать $event
с событием, чтобы создать впечатление использования нативного события:
<button v-on:click="$emit('click', $event)">
Enlarge text
</button>