본문 바로가기
공부/프론트엔드

[PJ] Vue 공부중9

by yeaseul912 2022. 10. 19.
728x90
vue 단축..이모지?

v-bind: = :

v-on: = @

v-slot = #

 

컴포넌트에서 v-model 사용하기

TodoForm 에서 사용하던 Input Box 들을 Input 이라는 component로 따로 빼서 사용해보도록 한다.

 공식 문서에서는 Multiple v-model 이라는 내용으로 찾을수 있다.(고 한다. 못찾음 ㅠ)

이런 폼이있다.

    

TodoForm.vue

...
<div class="row">
  <div class="col-6">
    <div class="form-group">
      <label>Subject</label>
      <input
        v-model="todo.subject"
        type="text"
        class="form-control"
      >
      <div
        v-if="subjectError"
        style="color: red"
      >
        {{ subjectError }}
      </div>
    </div>
  </div>
...

 

Input.vue 로 form 옮기기

바인딩을 통해 데이터를 연결하고, 클릭이벤트도 연결해준다.

 

Input.vue

<template>
  <div class="form-group">
    <label>{{ label }}</label>
    <input
      :value="subject"
      type="text"
      class="form-control"
      @input="onInput"
    >
    <div
      v-if="error"
      style="color: red"
    >
      {{ error }}
    </div>
  </div>
</template>
<script>
export default {
  props: {
    label: {
      type: String,
      required: true,
    },
    error: {
      type: String,
      required: true,
    },
    subject: {
      type: String,
      required: true,
    },
  },
  setup(props, { emit }) {
    const onInput = (e) => {
      console.log(e.target.value);
      emit("update-subject", e.target.value);
    };
    return { onInput };
  },
};
</script>

 

TodoForm.vue

...
<div class="row">
  <div class="col-6">
    <Input
      label="Subject"
      :subject="todo.subject"
      :error="subjectError"
      @update-subject="updateTodoSubject"
    />
  </div>
  ...
<script>
import Input from "@/components/Input.vue";

export default {
  components: { Input },
  setup(props) {
  const updateTodoSubject = (newValue) => {
      todo.value.subject = newValue;
      console.log(todo.value.subject);
    };
  return { updateTodoSubject };
  }
}
</script>

 

v-on 과 v-bind, 그리고 함수를 통해 변경된 값을 적용시켜 보았다.

이것을 v-model 로 간단하게 만들수 있다고 한다.

 

v-bind와 v-on 을 v-model 로 간단하게 만들기

 

Input.vue

const onInput = (e) => {
	// updabe-subject 를 update:subject 로 변경
    // emit을 연동하여 올려주기 위한 약속!
    // update:props이름
      emit("update:subject", e.target.value);
    };

 

TodoForm.vue

<div class="row">
  <div class="col-6">
    <Input
      label="Subject"
      v-model:subject="todo.subject"
      :error="subjectError"
    />
  </div>

 

updateTodoSubject 함수 + Input 안에 :subject + @update-subject = v-model:subject로 해결되었다.

subject 를 binding 한다는 의미로 input.vue에서 emit("update:subject", ) 를 사용하였다.

TodoForm.vue 에서 onUpdated로 todo.value.subject 를 확인하면 실시간으로 변경되는 것을 확인할 수도 있다. 

 

getCurrentInstance()

props 코드를 안쓴다면 적는것은 낭비처럼 느껴질 수 있다.!!

코드를 조금더 간단하게 만들고 싶을 때 다음 함수를 사용해보자.

원래는 useContext 많이 사용했었는데 이제 사용이안되서 대체되는 함수라고 한다.

 

기존 Input.vue

setup(props, { emit }) {
  const onInput = (e) => {
    emit("update:subject", e.target.value);
  };
  return { onInput };
},

 

변경된 Input.vue

import { getCurrentInstance } from "vue";
setup() {
  const { emit } = getCurrentInstance();
  const onInput = (e) => {
    emit("update:subject", e.target.value);
  };
  return { onInput };
},

 

 

toRefs

Composition Function 을 사용해서 재사용하는 파일들이 있는데

reactive 를 return을해서 사용할때 reactivity가 가끔 끊어질때 어뜨케 사용해야 하는지 알아보자.

 

테스트용 파일 생성

count.js => Add btn 작동 안함

import { reactive } from "vue";
export const useCount = () => {
  const state = reactive({
    count: 0,
  });
  // 객체 자체는 reactive하지만 안에있는 count(property)는 reactive하지 않다
  return state;
};

index.vue

<template>
  <div>Home page</div>
  <div>{{ count }}</div>
  <button @click="count++">
    Add
  </button>
</template>

<script>
import { useCount } from "@/composables/count";
export default {
  setup() {
    // 객체를 구조분해해서 가져오믄 반응성을 잃게 된다.
    // 따라서 toRefs 사용
    const { count } = useCount();
    return {
      count,
    };
  },
};
</script>

 

 

count.js => Add btn 작동함

// toRefs를 통해 property에 반응성을 넣어준다.
import { reactive, toRefs } from "vue";
export const useCount = () => {
  const state = reactive({
    count: 0,
  });
  return toRefs(state);
};

 

Toast Component -> App Component로 이동

요구사항:

글 작성 후 목록으로 이동을 하는데..

이때 글 작성이 완료되었다는 Toast를 계속 보이게 하고 싶어요!

 

TodoForm 에 있는 Toast 에서 App 에 있는 Toast 를 실행시킨다...  근데 component가 너무 많아서 막 10번 20번 emit 해야해?! 그럼 너무 불편하다. 그래서 vuex 사용!!!

 

vuex 설치

https://vuex.vuejs.org/installation.html#direct-download-cdn

 

Installation | Vuex

Installation Direct Download / CDN https://unpkg.com/vuex@4 Unpkg.com provides NPM-based CDN links. The above link will always point to the latest release on NPM. You can also use a specific version/tag via URLs like https://unpkg.com/vuex@4.0.0/dist/vuex.

vuex.vuejs.org

npm install vuex@next --save

 

src/store/index.js

import { createStore } from "vuex";

export default createStore({
  state: {},
});

src/main.js

import store from './store'

createApp(App).use(store).use(router).mount("#app");

 

헐! 강의(기간이)가 끝나버렸다!

반응형

'공부 > 프론트엔드' 카테고리의 다른 글

[PJ] Vue 공부중8  (0) 2022.10.05
[PJ] Vue 공부중7  (0) 2022.10.04
[PJ] Vue 공부중6  (0) 2022.10.03
[PJ] Vue 공부중5  (0) 2022.10.02
[PJ] Vue 공부중4  (2) 2022.09.29

댓글