[Vue3] Method

김관응·2023년 4월 4일
0

Vue

목록 보기
4/14

Method는 뷰 컴포넌트 안에 기능을 정의해놓은 것 이다.

Method 문법

method에 객체를 만들고 사용할 함수를 정의하면 된다.

export default {
	methods: {
		함수명: function () {
			// 함수 내용
		}
	}
}

data 활용

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 + " 입니다!!");
	}
}

nextTick

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한 버튼이 별개의 타이머로 동작하게 된다.

profile
엔지니어였던 개발자

0개의 댓글