Jav*_*nas 136 javascript vue.js vue-component vuejs2
我正在尝试在组件中使用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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
Test.vue(组件)
<template>
<div>
click here
</div>
</template>
<script>
export default {
name: 'test',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
Sau*_*abh 252
如果要在组件的根元素上侦听本机事件,则必须使用.native修饰符v-on,如下所示:
<template>
<div id="app">
<test v-on:click.native="testFunction"></test>
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
或者简而言之,正如评论中所建议的,您也可以这样做:
<template>
<div id="app">
<test @click.native="testFunction"></test>
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
pal*_*aѕн 21
正如 Chris Fritz(Vue.js Core Team Emeriti)在VueCONF US 2019中提到的
如果我们让 Kia 进入
.native,然后基本输入的根元素突然从输入更改为标签,则此组件已损坏并且并不明显,事实上,除非您有一个非常好的测试,否则您甚至可能不会立即捕获它。相反,通过避免使用我目前认为将在 Vue 3 中删除的反模式.native修饰符,您将能够明确定义父级可能关心将哪些元素侦听器添加到...
$listeners:因此,如果您使用 Vue 2,解决此问题的更好选择是使用完全透明的包装器逻辑。为此,Vue 提供了一个$listeners属性,其中包含在组件上使用的侦听器对象。例如:
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
Run Code Online (Sandbox Code Playgroud)
然后我们只需要添加v-on="$listeners"到test组件中,例如:
Test.vue(子组件)
<template>
<div v-on="$listeners">
click here
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
现在该<test>组件是一个完全透明的包装器,这意味着它可以像普通<div>元素一样使用:所有侦听器都可以工作,无需.native修饰符。
演示:
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
Run Code Online (Sandbox Code Playgroud)
<template>
<div v-on="$listeners">
click here
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
Vue.component('test', {
template: `
<div class="child" v-on="$listeners">
Click here
</div>`
})
new Vue({
el: "#myApp",
data: {},
methods: {
testFunction: function(event) {
console.log('test clicked')
}
}
})Run Code Online (Sandbox Code Playgroud)
$emit方法:我们也可以$emit为此使用方法,这有助于我们监听父组件中的子组件事件。为此,我们首先需要从子组件发出一个自定义事件,例如:
Test.vue(子组件)
<test @click="$emit('my-event')"></test>
Run Code Online (Sandbox Code Playgroud)
重要提示:事件名称始终使用 kebab-case。有关这一点的更多信息和演示,请查看这个答案:VueJS将计算值从组件传递到父级。
现在,我们只需要在父组件中监听这个发出的自定义事件,例如:
应用程序
<test @my-event="testFunction"></test>
Run Code Online (Sandbox Code Playgroud)
因此,基本上我们将简单地使用或代替v-on:click或 简写。@clickv-on:my-event@my-event
演示:
div.child{border:5px dotted orange; padding:20px;}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
<test @click="testFunction"></test>
</div>Run Code Online (Sandbox Code Playgroud)
<test @click="$emit('my-event')"></test>
Run Code Online (Sandbox Code Playgroud)
v-bind="$attrs":Vue 3 将在很多方面让我们的生活变得更轻松。它的一个例子是,它将帮助我们创建一个更简单的透明包装器,只需使用v-bind="$attrs". 通过在子组件上使用它,我们的侦听器不仅可以直接从父组件工作,而且任何其他属性也可以像正常一样工作<div>。
所以,关于这个问题,我们不需要在 Vue 3 中更新任何东西,你的代码仍然可以正常工作,就像<div>这里的根元素一样,它会自动监听所有子事件。
演示 #1:
<test @my-event="testFunction"></test>
Run Code Online (Sandbox Code Playgroud)
Vue.component('test', {
template: `
<div class="child" @click="$emit('my-event')">
Click here
</div>`
})
new Vue({
el: "#myApp",
data: {},
methods: {
testFunction: function(event) {
console.log('test clicked')
}
}
})Run Code Online (Sandbox Code Playgroud)
div.child{border:5px dotted orange; padding:20px;}Run Code Online (Sandbox Code Playgroud)
但是对于具有嵌套元素的复杂组件,我们需要将属性和事件应用于 main<input />而不是父标签,我们可以简单地使用v-bind="$attrs"
演示#2:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
<test @my-event="testFunction"></test>
</div>Run Code Online (Sandbox Code Playgroud)
const { createApp } = Vue;
const Test = {
template: `
<div class="child">
Click here
</div>`
};
const App = {
components: { Test },
setup() {
const testFunction = event => {
console.log("test clicked");
};
return { testFunction };
}
};
createApp(App).mount("#myApp");Run Code Online (Sandbox Code Playgroud)
div.child{border:5px dotted orange; padding:20px;}Run Code Online (Sandbox Code Playgroud)
小智 20
我认为这个$emit功能对我认为你要求的更好.它使您的组件与Vue实例分离,以便在许多上下文中可以重用.
// Child component
<template>
<div id="app">
<test @click="$emit('test-click')"></test>
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
在HTML中使用它
// Parent component
<test @test-click="testFunction">
Run Code Online (Sandbox Code Playgroud)
小智 12
这是@Neps的答案,但有详细信息。
注意:如果您不想修改组件或无法访问组件,则@Saurabh的答案更合适。
组件很复杂。一个组件可以是一个小巧的按钮包装器,另一个组件可以是内部包含一堆逻辑的整个表。Vue不知道绑定v-model或使用时的确切期望,v-on因此所有这些都应由组件的创建者处理。
根据Vue docs,$emit将事件传递给父对象。来自文档的示例:
主文件
<blog-post
@enlarge-text="onEnlargeText"
/>
Run Code Online (Sandbox Code Playgroud)
零件
<button @click="$emit('enlarge-text')">
Enlarge text
</button>
Run Code Online (Sandbox Code Playgroud)
(@是v-on 简写)
组件处理本机click事件并发出父级事件@enlarge-text="..."
enlarge-text可以替换为click以使其看起来像我们正在处理本地点击事件:
<blog-post
@click="onEnlargeText"
></blog-post>
Run Code Online (Sandbox Code Playgroud)
<button @click="$emit('click')">
Enlarge text
</button>
Run Code Online (Sandbox Code Playgroud)
但这还不是全部。$emit允许通过事件传递特定值。如果是native click,则值为MouseEvent(与Vue无关的JS事件)。
Vue将该事件存储在$event变量中。因此,最好$event随事件一起发出,以产生本机事件用法的印象:
<button v-on:click="$emit('click', $event)">
Enlarge text
</button>
Run Code Online (Sandbox Code Playgroud)
小智 5
组件的本地事件不能直接从父元素访问。相反,您应该尝试v-on:click.native="testFunction",或者也可以从Test组件发出事件。喜欢v-on:click="$emit('click')"。
有点冗长,但这是我的方法:
@click="$emit('click', $event)"
| 归档时间: |
|
| 查看次数: |
86256 次 |
| 最近记录: |