vue 자주사용하는 것
2023-03-07
다른건 아니고 조금 개발하면서 자주 사용하는데, 머리가 바보라서 매번 찾아보게 되는 것과,
잘 몰랐었던것들을 정리해 보았습니다.
양방향 다중 바인딩
양방항 바인딩이 예전에는 하나 밖에 안됐었다고 하는데, 지금은 두개 이상도 가능한 것 같습니다. 다만 양방향 바인딩은 쓰지 않는 것이 컴포넌트 설계 상 좋다고 하네요.
<NameComponent
v-model:fornames="forname"
v-model:surname="surname"
/>
Suspense
컴포넌트 내에 async 구문이 완료되지 않았을 경우, 로딩 같은걸 뿌려줘야 하는데, 이때 사용할 수 있는것이 Suspense 인 것 같습니다.
이런게 있는지 몰랐었기에 적어 보았습니다.
<Suspense>
<template #default>
<UserProfile />
<FunnyCats />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
두개의 개인 컴포넌트
Fragment
이걸 사용하면 컴포넌트를 root에 두개 선언 가능하다고 함.
써보지는 못했습니다.
<Fragment>
<td>Hello</td>
<td>World</td>
</Fragment>
nextTick
data가 업데이트 되고 난 직후, dom 을 잘 못가져 오는 경우가 있습니다. 이때 사용하면 된다고 합니다.
import { nextTick } from 'vue';
onMounted(async () => {
await nextTick();
});
onMounted
라이프 사이클에서 렌더링 초기때 실행해야 하는 것들을 여기에 담으면 됩니다. 보통 event 선언같은거 할때나 사용하고, 딱지 잘 사용은 안하게 되더군요.
import { onMounted } from 'vue';
onMounted(async () => {
await nextTick();
let el = document.getElementById(`graph-paper-${props.graphId}`);
service = new GraphService(el as HTMLElement, {
defaultRouter: {
name: 'normal',
},
defaultConnector: {
name: 'rounded',
},
});
init();
});
동적 인자
props 인자를 변수처럼 쓸수 있는건데, 흠 잘 쓰일까? 어디에다 쓰지 싶긴 합니다.
이게 필요 했었던적이 있는거 같기도 하구요.
:[att]="arg"
ref
리엑트에서 돔 다룰때 써야하는데, .value 로 접근해야 됩니다.
그런데 세팅을 잘못했는지, _rawValue 이렇게 접근해야 되는 경우도 있더군요.
import { ref } from "vue";
<template>
<div ref="dropdown_menu">
</template>
<script>
const dropdown_menu = ref(null);
</script>
변수 ref
.value 를 붙일거면 붙이고 안붙일거면 안붙였으면 좋겠는데, 암튼 변수는 저렇게 선언합니다.
const show_menu = ref(false);
실제 사용
<template>
<div></div>
</template>
<script>
show_menu.value
</script>
emit
import { defineEmits } from "vue";
// 부모가 접근 가능하다.
const emit = defineEmits(["onFilterClick", "onResourceMenuItemClick"]);
emit("onFilterClick", {
filter_name: filter_name,
nav_type: props.navType,
});
중간 다리 역할하는 경우 아래와 같이 event를 바로 전달함
<todo-item @remove="$emit('remove', $event)"></todo-item>
props
import { defineProps } from "vue";
const props = defineProps<{
filter_name: string;
navType: 'infra' | 'resourceGroup' | 'namespace' | 'pod';
selected_filter: string;
selected_nav_type: string;
resources: {
infra: string;
resourceGroup: any;
namespace: any;
pod: string;
};
checked_filter: {
resourceGroups: Array<string>;
namespaces: Array<string>;
};
filterValues: any;
}>();
watch
import { watch } from "vue";
watch(
() => props.selected_nav_type,
(newVal: string) => {
// 해당 필터가 선택되지 않았을 경우
if (props.navType != props.selected_nav_type) {
show_menu.value = false;
}
}
);
watch(() => props.filterValues, () => {
onSelectedFilterString();
})
computed
호출 때 마다 달라진다면, methods 를 쓰도록 하자.
import { computed } from "vue";
const coordinatesStyle = computed(() => {
return {
"--top": `${props.coordinates.clientY ? props.coordinates.clientY : 0}px`,
"--left": `${props.coordinates.clientX ? props.coordinates.clientX : 0}px`,
};
});
:style="coordinatesStyle"
v-if vs v-show
v-if 는 토글 비용이 높음 v-show 는 초기 렌더링 비용이 높고
그래서 토글하는건 show 잘 안바뀌는건 if
바인드 축약 가능
<!-- 축약 문법 -->
<app-title v-bind="appInfo"></app-title>
<!-- 실제로는 아래와 같이 동작 - 기존 문법 -->
<app-title v-bind:title="appInfo.title" v-bind:version="appInfo.version"></app-title>
디렉티브 이벤트 제어자
<!-- 클릭 이벤트 전파 중단 -->
<a @click.stop="doThis"></a>
<!-- 제출 이벤트는 더 이상 페이지를 다시 로드하지 않습니다 -->
<form @submit.prevent="onSubmit"></form>
<!-- 수식어를 연결할 수 있습니다 -->
<a @click.stop.prevent="doThat"></a>
<!-- 수정자만 -->
<form @submit.prevent></form>
<!-- event.target이 요소 자체인 경우에만 핸들러 트리거 -->
<!-- 즉, 자식 요소가 아님 -->
<div @click.self="doThat">...</div>
slot
안에 아무것도 없으면 Submit 이 적힘
<slot>
Submit <!-- fallback content -->
</slot>