기존 로직은 이벤트로 받은 object(도형) 의 id를 통해 직접 dom을 조작하는 방식이었다.
const executeAnimation = (objectId, animation) => {
const element = document.getElementById(objectId)
// ... 다른 로직들
}
vue는 가상 dom을 이용해 화면을 렌더링 하는데 직접 dom 조작을 했을 경우 vue가 변화를 인식하지 못하고 변경하지 않을 수 있다.
vue는 가상 dom을 사용해 렌더링 최적화를 시키는데 직접 dom을 조작할 경우 vue의 생명주기와 맞지 않을 수 있다 라는 문제점이 있었다.
ref 상태를 이용해 객체 모양의 상태를 만들어주고, 조작 할 html 태그에 ref 바인딩을 해준다.
바인딩 할 때 element를 인수로 받아서 setRef라는 함수 내에서 element가 있을 때만 objectId를 전달하도록 한다.
ref 상태에는 objectId 별로 각각의 dom을 가지고 있게 된다.
이후에 실제로 dom을 조작해야 할 때는 ref 상태에서 objectId를 통해 각 dom을 참조해 조작하도록 한다.
const elementRefs = ref({}) // dom들을 넣을 상태
// 상태에 element와 objectId를 통해 각 dom을 구분하여 넣어주는 로직.
const setRef = (el, objectId) => {
if (el) {
elementRefs.value[objectId] = el
}
}
// 실제 dom 조작이 필요한 함수에서 사용하는 방법.
const executeAnimation = (objectId, animation) => {
const element = elementRefs.value[objectId]
}
// ref 바인딩
<g
v-for="object in objects"
:key="object.objectData.uuid"
:id="object.objectData.uuid"
:ref="(el) => setRef(el, object.objectData.uuid)"
></g>
// g 태그가 마운트될 때 엘리먼트가 가지는 값
el type: "SVGGElement"
el: <g id="circle-25d46a09-4bc0-4dfc-96f7-21ee3daa522d">...</g>
// g 태그가 언마운트될 때 엘리먼트가 가지는 값
el type: undefined
el: null