Method는 뷰 컴포넌트 안에 기능을 정의해놓은 것 이다.
method에 객체를 만들고 사용할 함수를 정의하면 된다.
export default {
methods: {
함수명: function () {
// 함수 내용
}
}
}
name 이라는 데이터를 만들어 버튼을 누르면 alert에 name을 띄우게 해보자.
<template>
<Header />
<Main />
<Sidebar />
<br>
이름 : {{name}} <br>
<button @click="test_click">test button</button><br>
</template>
<script>
import Header from "./components/Header.vue";
import Main from "./components/Main.vue";
import Sidebar from "./components/Sidebar.vue";
export default {
components: { Header, Main, Sidebar },
data() {
return {
name: "홍길동",
}
},
methods: {
test_click: function () {
// 함수 내용
alert(this.name + " 입니다!!");
}
}
};
</script>
data 에 있던 값은 template과 methods에서 접근이 가능하다.
함수를 좀 더 간단하게 표현하려고 function() {} 대신 화살표 함수(()=>{}) 를 사용한다면 this로 이 함수에 접근할 수 없되어 지양한다.
그래서 다음과 같이 클래스 메소드 선언하듯이 해주는 것을 추천한다.
methods: {
test_click() { // test_click: function () {
alert(this.name + " 입니다!!");
}
}
method에서 값을 바꾼 뒤 템플릿의 값을 바로 읽으면 반영이 되어있지 않다.
method 내에서 값을 변화시키고 DOM에 반영하고 싶다면 비동기 함수 nextTick을 이용해야한다.
<template>
<Header />
<Main />
<Sidebar />
<br>
<p> 이름 : {{name}} </p> <br>
<p id="age"> 나이 : {{age}} </p> <br>
<button @click="age_inc">age inc button</button><br>
<button @click="test_click">test button</button><br>
</template>
제
<script>
import Header from "./components/Header.vue";
import Main from "./components/Main.vue";
import Sidebar from "./components/Sidebar.vue";
import {nextTick} from "vue";
export default {
components: { Header, Main, Sidebar },
data() {
return {
name: "홍길동",
age: 29,
}
},
methods: {
test_click() {
// 함수 내용
alert(this.name + " 입니다!!");
},
async age_inc() {
this.age++;
// DOM not yet updated
console.log("nextTick 전 : " + document.getElementById("age").textContent);
// DOM is now updated
nextTick().then(
function () {
console.log("nextTick 후 : " + document.getElementById("age").textContent);
}.bind(this)
);
}제
}
};
</script>
버튼을 눌러 age값을 변경한 직후에 DOM 있는 값을 가져오면 반영이 되지 않고 textTick을 써야 반영되는것을 알 수 있다.
(하지만 DOM에 있는 값을 보는게 아니라 this.age를 통해 바로 접근을 하면 상관없이 바로 변경된다.)
버튼을 클릭 후 특정 시간 뒤에 동작하는 함수가 있다고 해보자.
<template>
<Header />
<Main />
<Sidebar />
<br>
<p> 이름 : {{name}} </p> <br>
<p id="age"> 나이 : {{age}} </p> <br>
<button @click="age_inc">age inc button</button><br>
<button @click="test_click">test button</button><br>
<button @click="debounce_click">debounce button</button><br>
</template>
제
<script>
import Header from "./components/Header.vue";
import Main from "./components/Main.vue";
import Sidebar from "./components/Sidebar.vue";
import { nextTick } from "vue";
import { debounce } from 'lodash-es';
export default {
components: { Header, Main, Sidebar },
data() {
return {
name: "홍길동",
age: 29,
}
},
methods: {
test_click() {
// 함수 내용
alert(this.name + " 입니다!!");
},
age_inc() {
this.age++;
// DOM not yet updated
console.log("nextTick 전 : " + document.getElementById("age").textContent);
// DOM is now updated
nextTick().then(
function () {
console.log("nextTick 후 : " + document.getElementById("age").textContent);
}.bind(this)
);
},
debounce_click: debounce(function () {
alert("debounce 함수 동작!!");
}, 1000),
}
};
</script>
버튼을 눌러보면 1초 뒤 함수가 동작하면서 alert이 뜬다.
하지만 버튼을 누른 뒤 1초가 지나기 전에 다시 누르면 타이머가 리셋이 되어버린다.
버튼을 누른 액션별로 비동기로 처리가 되야하는 경우는 컴포넌트를 아래와같이 모듈화해서 사용하면 된다.
<template>
<button @click="debouncedClick">debounce button</button><br>
</template>
<script>
import * as _ from "lodash-es";
export default {
name: "debouncedButton",
created() {
// 각 컴포넌트 인스턴스 click 함수는 고유한 타이머를 가집니다
this.debouncedClick = _.debounce(this.debounce_click, 1000)
},
methods: {
debounce_click() {
console.log("debounce 함수 동작!!");
},
debouncedClick() {
}
}
}
</script>
<template>
<Header />
<Main />
<Sidebar />
<br>
<p> 이름 : {{name}} </p> <br>
<p id="age"> 나이 : {{age}} </p> <br>
<button @click="age_inc">age inc button</button><br>
<button @click="test_click">test button</button><br>
<DebouncedButton/>
<DebouncedButton/>
</template>
<script>
import Header from "./components/Header.vue";
import Main from "./components/Main.vue";
import Sidebar from "./components/Sidebar.vue";
import DebouncedButton from "./components/DebouncedButton.vue";
import { nextTick } from "vue";
import { debounce } from 'lodash-es';
import * as _ from "lodash-es";
export default {
components: {Header, Main, Sidebar, DebouncedButton},
data() {
return {
name: "홍길동",
age: 29,
}
},
created() {
// 각 컴포넌트 인스턴스 click 함수는 고유한 타이머를 가집니다
this.debouncedClick = _.debounce(this.debounce_click, 1000)
},
methods: {
test_click() {
// 함수 내용
alert(this.name + " 입니다!!");
},
age_inc() {
this.age++;
// DOM not yet updated
console.log("nextTick 전 : " + document.getElementById("age").textContent);
// DOM is now updated
nextTick().then(
function () {
console.log("nextTick 후 : " + document.getElementById("age").textContent);
}.bind(this)
);
},
debounce_click() {
console.log("debounce 함수 동작!!");
},
debouncedClick() {
}
}
}
</script>
이렇게 하면 두개의 import한 버튼이 별개의 타이머로 동작하게 된다.