[Vue]Watch, WatchEffect

chaewonยท2024๋…„ 5์›” 10์ผ
0
post-thumbnail

โœ๐ŸปWatch

  • ์ข…์ข… ๋ฐ˜์‘ํ˜• ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋•Œ๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ๋‹ค๋ฅธ ์ž‘์—…(api, call ๋“ฑ)์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์–ด๋– ํ•œ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋•Œ DOM์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๋น„๋™๊ธฐ ์ž‘์—…์„ํ•ด์„œ ๋‹ค๋ฅธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Watchํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜์‘ํ˜• ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const message = ref("");
		//๋ฐ˜์‘ํ˜•(message)๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  
        //์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š”๋ฐ ๋ณ€ํ™”๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ์˜ ๋ฐ์ดํ„ฐ(newValue)
		//๊ธฐ์กด๊ฐ’(oldValue)
		watch(message, (newValue, oldValue) => {
			console.log("newValue", newValue);
			console.log("oldValue", oldValue);
		});
		return { message };
	},
};
</script>

<style lang="scss" scoped></style>


์ด๋ ‡๊ฒŒ ๊ฐ’(Hello)๋กœ ์ˆ˜์ •ํ•˜๊ฒŒ๋˜๋ฉด

oldValue์˜ ๊ฐ’์€ ์ฒ˜์Œ์— ๋นˆ๊ฐ’('')์„ ๋„ฃ์—ˆ๊ณ  newValue์˜ ๊ฐ’์—๋Š” 'Hello'๋ฅผ ๋„ฃ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธด ๊ฐ’์—๋Š” 'Hello'๊ฐ€ ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค. ๋˜ ๋‹ค์‹œ ์ˆ˜์ •ํ•ด๋ณด์ž.
'Hello'์—์„œ 'Hello ChaeWon'์œผ๋กœ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

๊ธฐ์กด์— ์ˆ˜์ •๋œ ๊ฐ’ 'Hello'๊ฐ€ ๊ธฐ์กด๊ฐ’์ด ๋˜๋ฉด์„œ 'Hello ChaeWon'์ด ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

  • ์ด๋ ‡๊ฒŒ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค์–‘ํ•œ ํƒ€์ž…์ด ๋  ์ˆ˜ ์žˆ๋‹ค. ref, reactive, computed, getter ํ•จ์ˆ˜, arrayํƒ€์ž…์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

getter ํ•จ์ˆ˜

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const x = ref(0);
		const y = ref(0);

		//watch์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ getter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์ˆ˜์˜ ํ•ฉ์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
		watch(
			() => x.value + y.value,
			sum => {
				console.log("sum: ", sum);
			},
		);

		return { x, y };
	},
};
</script>

<style lang="scss" scoped></style>


์ดˆ๊ธฐ๊ฐ’ x์— 1์„ ์˜ฌ๋ ค๋ณด์ž


๋ณ€๊ฒฝ๋œ ๊ฐ’์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ sum์€ ๊ณ„์†ํ•ด์„œ ๋ณ€ํ™”ํ•˜๋Š” ์ƒˆ๋กœ์šด ๊ฐ’์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๊ธฐ์กด๊ฐ’ ๋˜ํ•œ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const x = ref(0);
		const y = ref(0);

		//watch์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ getter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์ˆ˜์˜ ํ•ฉ์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
		watch(
			() => x.value + y.value,
			(sum, oldValue) => {
				console.log("sum: ", sum);
				console.log("oldValue: ", oldValue);
			},
		);

		return { x, y };
	},
};
</script>

<style lang="scss" scoped></style>

Array

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const x = ref(0);
		const y = ref(0);

		//Array
		//์ด๋ ‡๊ฒŒ ๋ฐฐ์—ด๋กœ ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๋ฐ›๋Š” ๊ฐ’ ๋˜ํ•œ ๋ฐฐ์—ด๋กœ ๋ฐ›๋Š”๋‹ค.
		watch([x, y], ([newX, newY]) => {
			console.log(newX, newY);
		});

		return { x, y };
	},
};
</script>

<style lang="scss" scoped></style>

object

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const x = ref(0);
		const y = ref(0);
        const obj = reactive({
        	count: 0,
        });

		//object
		watch(obj, (newObj, oldObj) => {
			console.log("newObj: ", newObj);
		});

		return { x, y, obj };
	},
};
</script>

<style lang="scss" scoped></style>



์ด๋ ‡๊ฒŒ count๋ฅผ 1๋Š˜๋ฆฌ๋ฉด count๊ฐ€ 1์ฆ๊ฐ€ํ•œ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ object์—์„œ ์†์„ฑ ํ•˜๋‚˜๋งˆ ๊ฐ์ง€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ๋ ๊นŒ?

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const x = ref(0);
		const y = ref(0);
        const obj = reactive({
        	count: 0,
        });

		//object
  		//nember๋กœ ํ™•์ธ์ด ๋œ๋‹ค.
  		console.log(typeOf obj.count);
  
		watch(obj.count, (newObj, oldObj) => {
			console.log("newObj: ", newObj);
		});

		return { x, y, obj };
	},
};
</script>

<style lang="scss" scoped></style>

obj.count๋กœ ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ์•ˆ๋œ๋‹ค. ์ด์œ ๋Š” number์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํŠน์ • object์˜ ์†์„ฑ์„ ๊ฐ์ง€ํ•˜๊ณ  ์‹ถ์œผ๋ฉด๋Š” getter ํ•จ์ˆ˜๋ฅผ๋กœ ๋„ฃ์–ด์ค€๋‹ค

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
        const obj = reactive({
        	count: 0,
        });

		//object
		watch(
			() => obj.count,
			(newObj, oldObj) => {
				console.log("newObj: ", newObj);
			},
		);

		return { obj };
	},
};
</script>

<style lang="scss" scoped></style>


๊ทธ๋Ÿผ ์ด๋ ‡๊ฒŒ 1์ด ์ฐํžˆ๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ object ํƒ€์ž…์„ ๊ฐ์ง€ํ• ๋•Œ๋Š” newObj์™€ oldObj๋ฅผ ๊ฐ™์ด ๊ฐ์ง€ํ•œ๋‹ค.

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
        const obj = reactive({
        	count: 0,
        });

		//object
		watch(obj, (newObj, oldObj) => {
			console.log("newObj: ", newObj);
			console.log("oldObj: ", oldObj);
		});

		return { obj };
	},
};
</script>

<style lang="scss" scoped></style>


๊ทธ๋ฆฌ๊ณ  ๋ฐ˜์‘ํ˜• ๊ฐ์ฒด๋ฅผ ์ง์ ‘ watch()ํ•˜๋ฉด ์•”์‹œ์ ์œผ๋กœ ๊นŠ์€ ๊ฐ์‹œ์ž๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. ์ฆ‰, ์†์„ฑ ๋ฟ๋งŒ์•„๋‹ˆ๋ผ ๋ชจ๋“  ์ค‘์ฒฉ๋œ ์†์„ฑ์—๋„ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋œ๋‹ค.

<template>
	<div></div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
       const person = reactive({
			name: "์ด์ฑ„์›",
			age: "33",
			hobby: "์šด๋™",
			obj: {
				count: 0,
			},
		});

		watch(person, newValue => {
			console.log("newValue: ", newValue);
		});

		return { person };
	},
};
</script>

<style lang="scss" scoped></style>


์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝ์„ํ•ด๋„ ๋”ฅํ•˜๊ฒŒ ๊ฐ™์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ์ฒด์•ˆ์˜ ๊ฐ์ฒด๊นŒ์ง€, ๋งŒ์•ฝ getter ํ•จ์ˆ˜๋กœ obj๋ฅผ ๋„˜๊ธฐ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? obj ์ž์ฒด๊ฐ€ ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋•Œ๋งŒ ๊ฐ์ง€๊ฐ€๋œ๋‹ค. ๊ฐ์ฒด ์•ˆ์— ๊ฐ์ฒด์˜ ๊ฐ’์ด ๋ณ€ํ–ˆ์„ ๋•Œ๊ฐ€ ์•„๋‹ˆ๋ผ obj์˜ ์†์„ฑ ๊ฐ’์ด ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋•Œ๋งŒ ๊ฐ์ง€๊ฐ€ ๋œ๋‹ค. getter ํ•จ์ˆ˜๋กœ ๋ฐ›์€ ๊ฐ’์ด ๋ฐ”๊ผˆ๋‚˜ ์•ˆ ๋ฐ”๊ผˆ๋‚˜๋ฅผ ๊ฐ€์ง€๊ณ  ์ฒดํฌํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ watch๋Š” ๋ฐ˜์‘ํ˜• ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋•Œ ๊ฐ์ง€ํ•˜์—ฌ callback ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œ์ผœ์ค€๋‹ค. ์ด๋Ÿฌํ•œ callback ํ•จ์ˆ˜๋ฅผ ์‹œ์ž‘ ์ฆ‰์‹œ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ๋‹ค. ์ด๋Ÿด ๋•Œ immediate๊ฐ€ ์žˆ๋‹ค.

<template>
	<div>
		<p>{{ message }}</p>
		<p>{{ reverseMessage }}</p>
	</div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const message = ref("hello vue3");
		const reverseMessage = ref("");

		watch(
			message,
			newValue => {
				//split๋กœ ์ชผ๊ฐœ๊ณ  reverse๋กœ ๋ฐ˜์ „ ํ›„ join์œผ๋กœ ๋ถ™์—ฌ์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  reverseMessage๋กœ ๋„ฃ์–ด์ค€๋‹ค.
				reverseMessage.value = newValue.split("").reverse().join("");
			}
		);

		return { message, reverseMessage };
	},
};
</script>

์ด๋ ‡๊ฒŒ ๋์„ ๋•Œ ์ตœ์ดˆ๋กœ message๊ฐ€ ์ˆ˜์ •์ด ๋œ ํ›„ reversMessge๊ฐ€ ๊ฐ์ง€๋œ๋‹ค.


์ตœ์ดˆ๋กœ ๋ฐ”๋กœ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”

<template>
	<div>
		<p>{{ message }}</p>
		<p>{{ reverseMessage }}</p>
	</div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const message = ref("hello vue3");
		const reverseMessage = ref("");

		watch(
			message,
			newValue => {
				//split๋กœ ์ชผ๊ฐœ๊ณ  reverse๋กœ ๋ฐ˜์ „ ํ›„ join์œผ๋กœ ๋ถ™์—ฌ์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  reverseMessage๋กœ ๋„ฃ์–ด์ค€๋‹ค.
				reverseMessage.value = newValue.split("").reverse().join("");
			},
			// ์ด๋ ‡๊ฒŒ ์ฆ‰์‹œ ์‹คํ–‰์„ ์›ํ•˜๋ฉด immediate true๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
			{
				immediate: true,
			},
		);

		return { message, reverseMessage };
	},
};
</script>


์ด๋ ‡๊ฒŒ ๋ฐ”๋กœ immediate๋ฅผ ํ†ตํ•ด์„œ ์ฆ‰์‹œ ์‹คํ–‰ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<template>
	<div>
		<p>{{ message }}</p>
		<p>{{ reverseMessage }}</p>
	</div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const message = ref("hello vue3");
		const reverseMessage = ref("");

		watch(
			message,
			newValue => {
				//split๋กœ ์ชผ๊ฐœ๊ณ  reverse๋กœ ๋ฐ˜์ „ ํ›„ join์œผ๋กœ ๋ถ™์—ฌ์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  reverseMessage๋กœ ๋„ฃ์–ด์ค€๋‹ค.
				reverseMessage.value = newValue.split("").reverse().join("");
			},
			// ์ด๋ ‡๊ฒŒ ์ฆ‰์‹œ ์‹คํ–‰์„ ์›ํ•˜๋ฉด immediate true๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
			{
				immediate: true,
			},
		);

		return { message, reverseMessage };
	},
};
</script>

์•„๋ž˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด๋‹ค.

<template>
	<div>
		<p>{{ message }}</p>
		<p>{{ reverseMessage }}</p>
	</div>
</template>

<script>
import { ref, watch } from "vue";

export default {
	setup() {
		const message = ref("hello vue3");
		const reverseMessage = ref("");

		// 1) ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•
		// watch(
		// 	message,
		// 	newValue => {
		// 		//split๋กœ ์ชผ๊ฐœ๊ณ  reverse๋กœ ๋ฐ˜์ „ ํ›„ join์œผ๋กœ ๋ถ™์—ฌ์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  reverseMessage๋กœ ๋„ฃ์–ด์ค€๋‹ค.
		// 		reverseMessage.value = newValue.split("").reverse().join("");
		// 	},
		// 	// ์ด๋ ‡๊ฒŒ ์ฆ‰์‹œ ์‹คํ–‰์„ ์›ํ•˜๋ฉด immediate true๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
		// 	{
		// 		immediate: true,
		// 	},
		// );

		// 2) ๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•
		// const reverseFunction = newValue => {
		// 	reverseMessage.value = newValue.split("").reverse().join("");
		// };
		// watch(message, reverseFunction);
		// //์ตœ์ดˆ ์‹คํ–‰์ผ ๋•Œ watch์˜ newValue์˜ ๊ฐ’์ด ์—†๋‹ค. ๊ทธ๋ ‡๊ธฐ์— message.value๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.
		// reverseFunction(message.value);
		// return { message, reverseMessage };

		// 3) ์„ธ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•
		const reverseFunction = () => {
			reverseMessage.value = message.value.split("").reverse().join("");
		};
		watch(message, reverseFunction);
		reverseFunction();
		return { message, reverseMessage };
	},
};
</script>

computed

  • computed์™€ watch๋Š” ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ๋‹ค.

    computed - Vue ์ธ์Šคํ„ด์Šค์˜ ์ƒํƒœ(ref, reactive ๋ณ€์ˆ˜)์˜ ์ข…์† ๊ด€๊ณ„๋ฅผ ์ž๋™์œผ๋กœ ์„ธํŒ…ํ•˜๊ณ ์ž ํ•  ๋•Œ๋Š” computed๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์œ„ ์˜ˆ์‹œ๋ฅผ ์˜ˆ๋กœ ๋“ค์ž๋ฉด 'reverseMessage'๋Š” 'message' ๊ฐ’์— ๋”ฐ๋ผ ๊ฒฐ์ •๋˜์–ด์ง€๋Š” ์ข…์†๊ด€๊ณ„์— ์žˆ๋‹ค. ์ด ์ข…์†๊ด€๊ณ„ ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง€๋ฉด watch๋กœ ๊ตฌํ˜„ํ•  ๊ฒฝ์šฐ ๋” ๋ณต์žกํ•ด์ง€๊ฑฐ๋‚˜ ์ค‘๋ณต๊ณ„์‚ฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
    watch - Vue ์ธ์Šคํ„ด์Šค์˜ ์ƒํƒœ(ref, reactive ๋ณ€์ˆ˜)์˜ ๋ณ€๊ฒฝ ์‹œ์ ์— ํŠน์ • ์•ก์…˜(call api, push, route ๋“ฑ)์„ ์ทจํ•˜๊ณ ์ž ํ•  ๋•Œ ์ ํ•ฉํ•˜๋‹ค. ๋Œ€๊ฒŒ์˜ ๊ฒฝ์šฐ computed๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด๋ผ๋ฉด watch๊ฐ€ ์•„๋‹ˆ๋ผ computed๋กœ ๊ตฌํ˜„ํ•˜๋Š”๊ฒŒ ๋Œ€๋ถ€๋ถ„ ์˜ณ๋‹ค.


WatchEffect

  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์•ˆ์˜ ๋ฐ˜์‘์„ฑ ๋ฐ์ดํ„ฐ์— ๋ณ€ํ™”๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์ž๋™์œผ๋กœ ๋ฐ˜์‘ํ•˜์—ฌ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  WatchEffect์˜ ์ฝ”๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์ฆ‰์‹œ ์‹คํ–‰๋œ๋‹ค.
<template>
	<div>
		<form action="">
			<!-- ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•ด์„œ v-model ์‚ฌ์šฉ-->
			<input v-model="title" type="text" placeholder="title" />
			<textarea v-model="contents" placeholder="contents"></textarea>
		</form>
	</div>
</template>

<script>
import { ref, watchEffect } from "vue";

export default {
	setup() {
		const title = ref("");
		const contents = ref("");

		watchEffect(() => {
  			console.log("watchEffect");
			console.log("title: ", title.value);
			console.log("contents: ", contents.value);
		});

		return { title, contents };
	},
};
</script>


์ด๋ ‡๊ฒŒ ์ฝœ๋ฐฑํ•จ์ˆ˜ ์•ˆ์— ์„ ์–ธํ•œ ๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ์— ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋ฉด ๊ทธ๊ฒƒ์„ ๊ฐ์ง€ํ•ด์„œ ์ถœ๋ ฅ์ด ๋˜๋Š” ๊ฑธ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ์ด ๋˜์—ˆ์„ ๋•Œ ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  watchEffect๋Š” watch์™€ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜์Œ ์‹คํ–‰ ํ–ˆ์„ ๋•Œ ์ตœ์ดˆ ํ•œ๋ฒˆ ์ฆ‰์‹œ ์‹คํ–‰ํ•œ๋‹ค.



์ €๋ฒˆ์— ๋ฐฐ์šด modifiers๋ฅผ ํ™œ์šฉํ•ด ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

<template>
	<div>
		<!-- 3) button์˜ ๊ธฐ๋ณธ ์†์„ฑ์€ submit์ด๋ฉฐ button์„ ํด๋ฆญ ์‹œ form์— submit์ด ํ˜ธ์ถœ๋œ๋‹ค. -->
		<!-- 4) ์ €์žฅ ํ•˜์˜€์„ ๋•Œ submit์˜ ํ˜ธ์ถœ๋กœ ์ธํ•ด ์ƒˆ๋กœ๊ณ ์นจ์ด ๋ฐœ์ƒํ•˜๋‹ˆ prevent๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.-->
		<form @submit.prevent="save(title, contents)">
			<!-- 1) ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•ด์„œ v-model ์‚ฌ์šฉ-->
			<!-- 2) ๋งค๋ฒˆ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋Š”๊ฒŒ ์•„๋‹Œ focus๊ฐ€ ๋–จ์–ด ์กŒ์„ ๋•Œ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋„๋ก 
				lazy๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.-->
			<input v-model.lazy="title" type="text" placeholder="title" />
			<textarea v-model.lazy="contents" placeholder="contents"></textarea>
			<hr />
			<!-- 5) form์— ์•„๋‹Œ button์— @click="save(title, contents)"๋กœ๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. -->
			<!-- <button @click="save(title, contents)">์ €์žฅ</button> -->
			<button>์ €์žฅ</button>
		</form>
	</div>
</template>

<script>
import { ref, watchEffect } from "vue";

export default {
	setup() {
		const title = ref("");
		const contents = ref("");
		//๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ค€๋‹ค.
		const save = (title, contents) => {
			console.log(`์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. title:${title}, contents:${contents}`);
		};

		watchEffect(() => {
			console.log("watchEffect");
			save(title.value, contents.value);
		});

		return { title, contents, save };
	},
};
</script>

Watch?, WatchEffect?

  • watch์™€ watchEffect๋‘˜ ๋‹ค ๊ด€๋ จ ์ž‘์—…(api call, push, route ๋“ฑ)์„ ๋ฐ˜์‘์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ํ•˜์ง€๋งŒ ์ฃผ์š”ํ•œ ์ฐจ์ด์ ์€ ๊ด€๋ จ๋œ ๋ฐ˜์‘ํ˜• ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

    watch - ๋ช…์‹œ์ ์œผ๋กœ ๊ด€์ฐฐ๋œ ์†Œ์Šค๋งŒ ์ถ”์ ํ•œ๋‹ค. ์ฝœ๋ฐฑ ๋‚ด์—์„œ ์•ก์„ธ์Šคํ•œ ํ•ญ๋ชฉ์€ ์ถ”์ ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋˜ํ•œ ์ฝœ๋ฐฑ์€ ์†Œ์Šค๊ฐ€ ์‹ค์ œ๋กœ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ ํŠธ๋ฆฌ๊ฑฐ๋œ๋‹ค. watch์ข…์†์„ฑ ์ถ”์ ์„ ๋ถ€์ž‘์šฉ๊ณผ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์‹œ๊ธฐ๋ฅผ ๋ณด๋‹ค ์ •ํ™•ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.
    watchEffect - ๋ฐ˜๋ฉด ์ข…์†์„ฑ ์ถ”์ ๊ณผ ๋ถ€์ž‘์šฉ์„ ํ•œ ๋‹จ๊ณ„๋กœ ๊ฒฐํ•ฉํ•œ๋‹ค. ๋™๊ธฐ ์‹คํ–‰ ์ค‘์— ์•ก์„ธ์Šค๋˜๋Š” ๋ชจ๋“  ๋ฐ˜์‘ ์†์„ฑ์„ ์ž๋™์œผ๋กœ ์ถ”์ ํ•œ๋‹ค. ์ด๊ฒƒ์€ ๋” ํŽธ๋ฆฌํ•˜๊ณ  ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ ์ข…์†์„ฑ์„ ๋œ ๋ช…์‹œ์ ์œผ๋กœ ๋งŒ๋“ ๋‹ค.

profile
์˜๋ฌธ์€ '์‚ถ์˜ ์ˆ˜์ค€'์„ ๊ฒฐ์ •ํ•˜๊ณ , ์งˆ๋ฌธ์€ '์‚ถ ์ž์ฒด'๋ฅผ ๋ฐ”๊พผ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€