구성 요소 내에서 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>
답변
구성 요소의 루트 요소에서 기본 이벤트를 수신하려면 다음과 같이에 .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>
답변
나는 $emit
당신이 요구하는 것보다 기능이 더 잘 작동한다고 생각합니다. 여러 컨텍스트에서 재사용 할 수 있도록 구성 요소를 Vue 인스턴스와 분리하여 유지합니다.
// Child component
<template>
<div id="app">
<test @click="$emit('test-click')"></test>
</div>
</template>
HTML로 사용
// Parent component
<test @test-click="testFunction">
답변
그것은이다 @Neps ‘대답 하지만 세부 사항.
참고 : @Saurabh의 답변 은 구성 요소를 수정하지 않거나 액세스 할 수없는 경우 더 적합합니다.
@click이 작동하지 않는 이유는 무엇입니까?
구성 요소가 복잡합니다. 하나의 구성 요소는 작은 멋진 버튼 래퍼가 될 수 있고 다른 구성 요소는 내부에 많은 논리가있는 전체 테이블이 될 수 있습니다. Vue는 바인드 v-model
또는 사용할 때 정확히 무엇을 기대하는지 알지 못 v-on
하므로 구성 요소 작성자가 모든 것을 처리해야합니다.
클릭 이벤트를 처리하는 방법
에 따르면 뷰의 문서 , $emit
부모에 이벤트를 전달합니다. 문서의 예 :
메인 파일
<blog-post
@enlarge-text="onEnlargeText"
/>
구성 요소
<button @click="$emit('enlarge-text')">
Enlarge text
</button>
( @
는 IS v-on
속기 )
구성 요소는 기본 click
이벤트를 처리 하고 상위 이벤트를 생성합니다.@enlarge-text="..."
enlarge-text
click
기본 클릭 이벤트를 처리하는 것처럼 보이도록 대체 할 수 있습니다 .
<blog-post
@click="onEnlargeText"
></blog-post>
<button @click="$emit('click')">
Enlarge text
</button>
그러나 이것이 전부는 아닙니다. $emit
이벤트와 함께 특정 값을 전달할 수 있습니다. native의 경우 click
값은 MouseEvent (Vue와 관련이없는 JS 이벤트)입니다.
Vue는 해당 이벤트를 $event
변수 에 저장 합니다. 따라서 $event
기본 이벤트 사용에 대한 인상을주기 위해 이벤트와 함께 내보내는 것이 가장 좋습니다 .
<button v-on:click="$emit('click', $event)">
Enlarge text
</button>
답변
조금 장황하지만 이것이 내가하는 방법입니다.
@click="$emit('click', $event)"
답변
컴포넌트의 기본 이벤트는 상위 요소에서 직접 액세스 할 수 없습니다. 대신을 시도 v-on:click.native="testFunction"
하거나 Test
구성 요소 에서 이벤트를 생성 할 수 있습니다. 처럼 v-on:click="$emit('click')"
.
답변
VueCONF 2019 에서 Chris Fritz (Vue.js 핵심 팀 Emeriti )가 언급 한대로
우리가 Kia를 입력
.native
한 다음 기본 입력의 루트 요소가 입력에서 레이블로 갑자기 변경되면이 구성 요소가 깨져서 분명하지 않으며 실제로 테스트를 잘하지 않으면 바로 잡을 수 없습니다. 대신 Vue 3에서 안티 패턴이 제거 될 것으로 생각되는.native
수정자를 사용하지 않으면 부모가 추가 할 요소 리스너에 대해 부모가 신경 쓸 수 있음을 명시 적으로 정의 할 수 있습니다 …
Vue 2와 함께
사용 $listeners
:
따라서 Vue 2를 사용하는 경우이 문제를 해결하는 더 좋은 옵션은 완전히 투명한 래퍼 논리 를 사용하는 것 입니다. 이를 위해 Vue는 $listeners
컴포넌트에서 사용되는 리스너 객체를 포함하는 속성을 제공합니다 . 예를 들면 다음과 같습니다.
{
focus: function (event) { /* ... */ }
input: function (value) { /* ... */ },
}
그런 다음 구성 요소에 다음과 같이 추가하면 v-on="$listeners"
됩니다 test
.
Test.vue (자식 구성 요소)
<template>
<div v-on="$listeners">
click here
</div>
</template>
이제 <test>
구성 요소는 완전히 투명한 래퍼입니다 . 즉, 일반 <div>
요소 와 똑같이 사용할 수 있습니다 .native
. 수정 자 없이 모든 리스너가 작동합니다 .
데모:
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')
}
}
})
div.child{border:5px dotted orange; padding:20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
<test @click="testFunction"></test>
</div>
$emit
방법을 사용하여 :
우리는 $emit
이 목적을 위해 메소드를 사용할 수 있으며 , 이는 상위 컴포넌트에서 하위 컴포넌트 이벤트를 청취하는 데 도움이됩니다. 이를 위해 먼저 다음과 같은 하위 컴포넌트에서 사용자 정의 이벤트 를 생성 해야합니다 .
Test.vue (자식 구성 요소)
<test @click="$emit('my-event')"></test>
중요 : 이벤트 이름으로 항상 케밥 케이스를 사용하십시오. 이 포인트에 대한 자세한 정보와 데모를 보려면 VueJS가 계산 된 값을 component에서 parent로 전달하십시오 .
이제 다음과 같이 부모 구성 요소에서 생성 된이 사용자 지정 이벤트를 수신하면됩니다.
App.vue
<test @my-event="testFunction"></test>
그래서, 기본적으로 대신 v-on:click
하거나 속기는 @click
우리는 단순히 사용 v-on:my-event
하거나 @my-event
.
데모:
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')
}
}
})
div.child{border:5px dotted orange; padding:20px;}
<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>
Vue 3와 함께
사용 v-bind="$attrs"
:
Vue 3는 다양한 방식으로 우리의 삶을 훨씬 쉽게 만들어 줄 것입니다. 이에 대한 예제 중 하나는을 사용하여 구성이 훨씬 적은 더 간단한 투명 래퍼 를 만드는 데 도움이된다는 것입니다 v-bind="$attrs"
. 자식 컴포넌트에서 이것을 사용함으로써 우리의 리스너는 부모로부터 직접 작동 할뿐만 아니라 다른 어떤 속성도 정상적인 것처럼 작동 <div>
합니다.
따라서이 질문과 관련하여 Vue 3에서 아무것도 업데이트 할 필요가 없으며 <div>
여기의 루트 요소와 마찬가지로 코드가 여전히 잘 작동 하며 모든 자식 이벤트를 자동으로 듣습니다.
데모 # 1 :
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");
div.child{border:5px dotted orange; padding:20px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
<test v-on:click="testFunction"></test>
</div>
그러나 <input />
부모 레이블 대신 기본에 속성과 이벤트를 적용해야하는 중첩 요소가있는 복잡한 구성 요소의 경우 간단히 사용할 수 있습니다.v-bind="$attrs"
데모 # 2 :
const { createApp } = Vue;
const BaseInput = {
props: ['label', 'value'],
template: `
<label>
{{ label }}
<input v-bind="$attrs">
</label>`
};
const App = {
components: { BaseInput },
setup() {
const search = event => {
console.clear();
console.log("Searching...", event.target.value);
};
return { search };
}
};
createApp(App).mount("#myApp");
input{padding:8px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
<base-input
label="Search: "
placeholder="Search"
@keyup="search">
</base-input><br/>
</div>
답변
로부터 문서 :
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
}