- 전체
- 명
- 오늘 찾아주신 분
- 명
A 와 B 컴포넌트가 있고 B 컴포넌트는 A 컴포넌트에 속해있을 때, A 에서 B 의 기본값을 정의해 줄 때가 있다.
그럴 때에는 보통 다음의 프로세스를 따라 정의를 하게 된다.
1. B 컴포넌트에 props 를 정의한다.
2. A 컴포넌트에서 B 컴포넌트에 정의한 props 의 name 값으로 데이터를 전달한다.
이 프로세스를 소스로 옮기게 된다면,
<A>
<B></B>
</A>
인 경우에 B 컴포넌트에
// B.vue
<template>
</template>
<script>
export default {
name: "B",
props: [ "value" ],
}
</script>
props 에 value 라는 이름으로 property 를 추가했으며 A 에서는,
<A>
<B value="test"></B>
</A>
value 이름을 가지고 데이터를 넣어주게 된다. 만약, 일반 값이 아닌 변수를 넘겨주게 된다면 그냥 value 가 아니라 :value 를 사용하게 될 것이다.
여기까지는 기본적인 Vue 의 props 에 대한 정의 였다. 하지만, 이 내용은 최상위 컴포넌트 에서는 이뤄지지 않는다.
최상위 컴포넌트 는 Vue 의 시작점 이라고 이야기할 수 있다. 최상위 컴포넌트의 역할은 기본적으로는 Vue 를 생성하고 HTML 어느 부분에 렌더 해줄 지 정해준다. 그 외에 vue-router 나 기타 플러그인을 configure 하는 용도로 사용되는데, 파일도 *.vue 파일이 아닌 일반 *.js 파일로 되어있다.
여기서, "최상위 컴포넌트에 값을 넘겨줄 필요가 있을까?" 생각할 수도 있을 것 같은데, 개발하다보면 초가 설정값에 맞게 데이터를 뿌려줘야 할 때가 생기기 떄문에 그럴 경우에는 최상위 컴포넌트에다가 값을 미리 던져줘서 해당 값에 맞게 적절하게 보여주도록 구현해야한다. 그러나 일반적인 방법으로는 념겨주지 못하고 있다.
최상위 컴포넌트에 값을 넘겨주는게 외않되냐... 하면, 가장 큰 이유는 "Vue 밖" 이다. 보통, <div id="app"></div> 이고 여기에다가 Vue 의 컴포넌트를 구현해주는데, Vue el 을 통해 위치를 지정해서 해당 위치에 Vue 를 적용하는 것이지 겉의 <div> 레이어를 감싸주는 것이 아니다. 그래서 최상위 컴포넌트에 props 를 정의한다 해도 Vue 에서는 해당 값을 가져올 수 없다 (아마 undefined 만 뜰 것이다).
그래도 넘겨주는 방법이 있나니, 방법은 바로 DOM 의 dataset 을 이용하는 방법이다. 그럼 구현에 대해 알아보도록 하자.
먼저, HTML 의 <div> 레이어를 다음처럼 바꿔보도록 하자.
<div id="app" data-value="test"></div>
추가된 것은 'data-' Prefix 가 있는 속성이다. 'data' 가 붙은 속성은 일반적으로 사용하는 속성은 아니고 태그 속성에 직접적인 영향을 끼치진 않지만, 해당 태그에 의미있는 값이 필요한 경우에는 사용되는데 자세한 정의는 다음의 링크에서 확인해보도록 한다.
'data' 가 붙은 속성은 JS 를 통해서 해당 태그에 접근하게 되면 dataset 이라는 것을 통해서 접근을 할 수 있다. 그래서 방금 전에 바꿨던 값을 JS 에서 확인하게 된다면,
const el = document.getElementById('app');
console.log(el.dataset.value);
// => test
dataset 에서 뒤에 속성 이름만 작성 하면 바로 접근을 할 수 있게된다. 그냥 '.'만 찍어서 접근할 수 있는 걸로 느끼는 사람도 있겠지만 dataset 은 단순하게 Key-Value 형태로 되어 있다고 생각할 수도 있다.
그 다음으로는, 최상단 컴포넌트가 정의된 파일을 열어본다. 나의 경우에는 app.js 라는 파일이 파일의 최상단을 담당하고 있다.
import AComponent from './AComponent'
const el = document.getElementById('app')
new Vue({
el: el, // CSS Selector 가 아니어도 객체로 타겟을 줄 수 있다.
props: [ "value" ],
propsData: { ...el.dataset },
render: (h) => h(AComponent)
})
보통 el 값에는 CSS Selector 를 주긴 하지만, 이 경우에는 ID 가 app 으로 지정되어있는 태그의 데이터도 함께 쓸 것이기 때문에 JS 를 통해 태그 객체를 가져와서 최상위 컴포넌트에 전달을 시켜주었다. 그리고 props 에 <div> 레이어에 정의해 놓은 것과 같이 value 의 Property 를 추가해주었다. 여기서 가장 중요한 부분인 propsData 에 dataset 값을 넣어주는데, 여기서 el.dataset 앞에 붙어있는 3개의 점이 포인트이다.물론 저 기법을 쓰지 않고 propsData: el.dataset 로 써도 상관은 없지만 { ...el.dataset } 과는 사용상의 큰 차이가 있기 때문에 { ...el.dataset } 을 사용하기로 한다. '...'에 대한 설명은 Spread 라고 이야기 하는데, 자세한 것은 다음 링크를 확인하도록 한다.
이제 mounted 를 추가하여 제대로 불러오는 지 확인을 해보도록 한다.
import AComponent from './AComponent'
const el = document.getElementById('app')
new Vue({
el: el, // CSS Selector 가 아니어도 객체로 타겟을 줄 수 있다.
props: [ "value" ],
propsData: { ...el.dataset },
render: (h) => h(AComponent),
mounted(){
console.log(this.value)
}
})
제대로 작성했다면 태그에다가 썼던 'test' 라는 글자가 브라우저 콘솔에 출력이 될 것이다.
만약, 바로 AComponent 에 props 를 전달하고자 한다면, render 의 값을 조금 바꾸면 된다.
import AComponent from './AComponent'
const el = document.getElementById('app')
new Vue({
el: el, // CSS Selector 가 아니어도 객체로 타겟을 줄 수 있다.
props: [ "value" ],
propsData: { ...el.dataset },
render: (h) => h(AComponent, {
props: this.$props
})
/** 만약 최상단에서는 쓸일이 없고 컴포넌트로 바로 패스한다면,
render: (h) => h(AComponent, {
props: el.dataset
})
*/
})
해당 방법은 최상단 컴포넌트에 정의된 props 데이터들을 전부 AComponent 에 패스하도록 작성한 것이다.
[Laravel/Vue.js] Laravel Valet 환경에서 BrowserSync 초간단 설정하기 (1) | 2022.04.22 |
---|---|
[Node.js] SSL 적용된 Websocket 통신 (wss://) (0) | 2022.04.21 |
[Node.js] 파일 비교하여 같은 파일인 지 확인하기 (0) | 2022.04.06 |
[Linux] Node.js 다른 방식으로 설치하기(무설치) (0) | 2022.03.14 |
[Vue.js] 커스텀 RadioButton 만들어 보기 (0) | 2022.02.23 |