BeNI 2022. 12. 14. 22:14
728x90

 


1. slot

: 부모 컴포넌트에서 자식 컴포넌트의 엘리먼트를 지정할때 사용

 

1) 기본 형식

- 부모 컴포넌트

<ChildComponent>
    <h1>Hello Vue</h1>
</ChildComponent>

- 자식 컴포넌트

<template>
  <div>
    <!-- 부모에서 정의한 'Hello Vue'가 위치 -->
    <slot></slot>
  </div>
</template>

 

2) slot 이름 지정

v-slot 디렉티브를 이용하여 slot 요소가 여러 개일때 이름을 붙여 지정해 줄 수 있다. (축약 #)

<Hello>
   <h2 v-slot:abc>ABC</h2>
   <h2 #xyz>ABC</h2> 
</Hello>
<template>
  <slot name="abc"></slot>
  <slot name="xyz"></slot>
</template>

 

3) slot의 props 

- v-slot:default를 이용하여 하위 컴포넌트의 데이터를 가져와 출력할 수 있다.

- #['이름'] 형태로 동적으로 이름을 지정해 줄 수 있다.

<Hello>
  <template #default="slotProps">
    {{ slotProps.hello }}
  </template>
  <template #[slotName]="{ hello }">  // slotProps.hello 
    {{ hello }}
  </template>
</Hello>

...
data(){
  return {
    slotName: 'xyz'
  }
}
<template>
  <slot :hello="123" name="xyz"></slot>
</template>

 

2. 동적 컴포넌트

: 화면에 보여질 컴포넌트를 동적으로 제어할 수 있다 

<component :is="컴포넌트이름" />

 

- 컴포넌트가 전환될 때마다 페이지가 재랜더링 되는 것을 피하고 싶을 때, 

  keep-alive을 이용하여 렌더링 비용을 최소화 할 수 있다.

<template>
  <button @click="currentComponent = 'Hello'">Hello!</button>
  <button @click="currentComponent = 'World'">World!</button>
  <div>{{ msg }}</div>
  <keep-alive>
    <component :is="currentComponent" />
  </keep-alive>
</template>

위 경우에는 컴포넌트가 바뀌어도 Hello, World 컴포넌트가 재 랜더링 되지 않는다.

 

 

3. refs

: 컴포넌트나 Dom에 접근할 때 효율적으로 접근할 수 있게 하는 속성

 

1) 사용 방법

- 참조하려는 요소에 ref 속성 부여

<input ref="input">

- script 내에서 this.$refs로 접근 가능하다. (mounted 이상에서 사용 가능)

<script>
export default {
  mounted() {
    this.$refs.input.focus()
  }
}
</script>

✅ 참조 하려는 요소가 컴포넌트 일 때

- 컴포넌트 내부 요소가 한 개라면, this.$refs.[ref이름].$el 로 접근할 수 있다.

- 내부 요소가 여러 개면, 내부 요소에 개별적으로 ref 속성을 부여해줘야 한다.

 

<!-- 하위 컴포넌트 -->
<template>
  <h1 ref="world">World</h1>
</template>

 

<Hello ref="hello" />

상위 컴포넌트에서 this.$refs.hello.$refs.world 로 접근 할 수 있다.

 

📌주의사항

- refs로 참조한 요소는 렌더링을 바로 보장하지 않는다.

- 그 요소에 대한 메서드를 추가하고 싶으면, $nextTick 메서드를 이용해야 한다.

onEdit() {
  this.isEdit = true;
  // 렌더링을 바로 보장하진 않는다.
  this.$nextTick(() => {
    this.$refs.editor.focus();
  }, 0);
},

위 경우 처럼 어떠한 input 요소에 focus를 하고 싶을 때, nextTick을 이용해야한다. (아니면 setTimeout)

 

 

4. 플러그인

: 자주 사용하는 커스텀 메서드에 대해 전역적으로 사용할 수 있게 해주는 도구

 

1) 사용 방법

export default {
  install(app, options) {
    app.config.globalProperties$함수이름 = (arg) => {
    };
  },
};

export default {
  install(app, options) {
    app.config.globalProperties[options.pluginName] = (arg) => {
    };
  },
};

- main.js에서 불러와 전역적으로 사용할 수 있다.

app.sue(불러온이름)
app.use(불러온이름, {
  // pluginName: '$myName'
});

- 개별 컴포넌트에서는 this.$함수이름 으로 사용할 수있다.

 

 

5. 믹스인

: Vue 컴포넌트에 재사용 가능한 컴포넌트 옵션을 가져와 기존 옵션들과 혼합하여 사용할 수 있다.

 

1) 사용 방법

- mixin 객체를 정의한다. (따로 파일로 뺄 수 있음)

const myMixin = {
  created() {
    this.hello()
  },
  methods: {
    hello () {
      console.log('hello from mixin!')
    }
  }
}

- 사용할 컴포넌트에 불러온다.

export default {
  mixins: [myMixin],
  data() {
    return {};
  },
  methods: {},
};

📌 같은 이름의 메서드는 덮어써지는게 아니라 mixin이 먼저, 컴포넌트의 메서드가 그 후 호출된다.

      다른 것들은 컴포넌트가 mixin을 덮어쓴다.

 

 

6. Teleport

: 원하는 요소를 외부에 있는 Dom 노드로 텔레포트 할 수있는 기능

<Teleport to="body">
  <div v-if="open" class="modal">
    <p>Hello from the modal!</p>
    <button @click="open = false">Close</button>
  </div>
</Teleport>

- to로 원하는 요소의 선택자를 넣는다. 

- 텔레포트를 여러개 하면 먼저 작성한 코드 먼저 텔레포트 된다..

 

 

 

7. Provide/inject

: 부모 컴포넌트가 하위 컴포넌트들에 데이터를 내려줄 때 한번에 데이터를 전달 할 수 있는 기능

 

1) 사용 방법

- 부모 컴포넌트에 provide 메서드 생성

  provide() {
    return {
      msg: 'hello!',
    };
  },

- 부모의 하위 요소에서 inject 메서드로 데이터를 가져온다.

export default {
  inject: ["msg"],
};

 

⚠️ inject로 가져온 데이터는 반응성을 가지지 않는다.

해결방법은 부모 요소에서 해당 데이터를 computed로 감싸주면 된다.

 

8. Vuex

: Vue의 데이터를 전역으로 관리할 수 있게 해주는 모듈

 

1) 설치 방법

npm i vuex

2) 기본 형태

import { createStore } from "vuex";

export default createStore({
  state() {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {},
});
  • state : 상태의 집합
  • getters : state를 변경시킬 때 사용(전달인자 x, computed에 등록)
  • mutations: state 변경시킬 때 사용(전달인자 o, methods에 등록)
  • actions : 비동기적 변이를 다루는 속
  • modules: vuex의 상태를 모듈화 했을 때 불러온 모듈 작성

* 모듈화 된 파일은 namespaced: true 속성을 제일 앞에 적어둬야 된다.

 

3) 사용 방법

① state

state() {
  return {
    message: "Hello Store Vue?!",
  };
},

 return문 안에 객체 형태로 데이터를 선언한다.

 

전역적으로 불러온 store에 대해 컴포넌트에서 아래와 같이 데이터를 불러와 사용할 수 있다.

<template>
  <h2>{{this.$store.state.message}}</h2>
</template>

 

* 지역적으로 store를 불러왔다면, state 이름만 작성해도 된다.

 

getters 

  getters: {
    reversedMessage(state) {
      return state.message.split("").reverse().join("");
    },
  },

인자로 자신의 내부 state를 받아온다. state를 이용하여 값을 변경할 수 있다.

* 두번째 인수로 다른 getter를 받아올 수 있다.

 

컴포넌트에서 사용하는 방법은 아래와 같다. computed에 등록하여 사용한다.

export default {
  computed: {
    reversedMsg() {
      return this.$store.getters.reversedMsg;
    },
  },
};

 

✅ mapGetters 

- 여러 getter 요소들을 간편하게 불러올 수 있게 하는 메서드

export default {
  computed: {
    ...mapGetters([
      '게터이름1',
      '게터이름2',
    ])
  }
}

 

③ mutations

mutations: {
  updateMsg(state, newMsg) {
    state.msg = newMsg;
  },
},

첫번째 인자로 state를 받아온다. 두번째 인자로 payload를 받아와 함수 내에서 활용할 수 있다.

 

컴포넌트에서 사용하는 방법은 아래와 같다. 첫번째 인자로 muatation 이름,  두번째 인자로 데이터를 넘긴다.

this.$store.commit('updateMsg', '새로운 메시지');

 

✅mapMutation

: 여러 mutations를 불러와 간편하게 쓸 수 있는 메서드

  methods: {
    ...mapMutations(["뮤테이션이름1", "뮤테이션이름2"]),
    ...mapMutations("모듈이름", ["뮤테이션이름1", "뮤테이션이름2"]),
  },

 

④ actions

actions: {
  async fetchTodo(context) {
    const todo = await fetch(
      "https://jsonplaceholder.typicode.com/todos/1"
    ).then((res) => res.json());
    context.commit("updateMessage", todo.title);
  },
},

context는 { state, getters, commit, dispatch } 객체이다. 

 

사용할 때는 methods안에 정의하고, dispatch라는 메서드를 이용한다.

this.$store.dispatch('fetchTodo');

 

✅ mapActions

: 마찬가지로 actions도 아래와 같이 불러올 수 있다.

methods: {
  ...mapActions(["액션이름1"]),
  ...mapActions("모듈이름", ["액션이름1"]),
},

 

⑤ 모듈 이용하기

개별 모듈은 namespace: true 속성을 제일 첫번째로 가진다.

전역으로 store를 선언하고, 개별 컴포넌트에서 사용할 때에는 아래 형태로 사용한다.

  • state: this.$store.state.모듈이름.상태이름
  • getters : this.$store.getters['모듈이름/게터이름']
  • mutations : this.$store.commit('모듈이름/뮤테이션이름')
  • actions : this.$store.dispatch('모듈이름/액션이름')

 

 

728x90