안녕하세요 상훈입니다.

지난 포스팅에서 부모 -> 자식 v-model 값을 전달할 수 있게 코딩하는 것을 언급하였었는데,
오늘은 여러 개의 v-model 을 props 로 내려주는 내용을 포스팅 하려고 합니다.

2023.06.12 - [FrontEnd/Vue.js] - [ Vue.js ] Component 에 v-model 값 적용하기 1(이전포스팅)

 

[ Vue.js ] Component 에 v-model 값 적용하기 1

안녕하세요 상훈입니다. Vue.js 3 - composition API 에서 특정 컴포넌트에 v-model 값을 내려주는 방법을 포스팅하도록 하겠습니다. 필요요소 : 부모컴포넌트, 자식컴포넌트 소스 확인(링크를 통해 작성

code-hoon.tistory.com

 

필요요소: 부모컴포넌트, 자식컴포넌트

마찬가지로 부모컴포넌트와 자식컴포넌트가 필요합니다.

 

1. 부모컴포넌트

<script setup>
    import CustomInput from './CustomInput.vue'
    import {ref} from 'vue'

    const message = ref('')
    const message2 = ref('')
</script>

<template>
  메시지: {{ message }} <br/>
  메시지2: {{ message2 }} <br />
  <CustomInput v-model:message="message" v-model:message2="message2" />
</template>

자식 컴포넌트에 v-model 로 message, message2 를 각각 내려주었습니다.

 

2. 자식 컴포넌트

<script setup>
  const props = defineProps({
    message: String,
    message2: String
  })
  const emits = defineEmits(['update:message', 'update:message2'])
  
  const updateInputs = (e, type) => {
    emits(`update:${type}`, e.target.value)
  }
</script>

<template>
  <input
    :value="message"
    @input="updateInputs($event,'message')"
    style="margin-top: 20px;"
  /> 
  <textarea
    :value="message2" 
    @input="updateInputs($event,'message2')"
  ></textarea>
  
</template>

defineProps 로 message, message1 을 받아오기
defineEmits 로 emit 을 설정해주기
@input 태그 이벤트updateInputs 메서드를 연동.  값이 변할 때마다 부모 컴포넌트로 값 상신해주기

 


이중에서 핵심은 @input 이벤트 태그라고 생각합니다.

vue.js공식문서

v-model 을 쪼개보면 위 이미지와 같이 쪼개지는 것을 알 수 있습니다.
v-bind -> value
@input -> event (user-custom-event)


결과

결과 화면

 

 

코드 공유 - Vue Playground

 

Vue SFC Playground

 

play.vuejs.org

 

 

Component v-model | Vue.js

 

ko.vuejs.org

 

반응형

안녕하세요 상훈입니다.

Vue.js 3 - composition API 에서 특정 컴포넌트에 v-model 값을 내려주는 방법을 포스팅하도록 하겠습니다.

 

필요요소 : 부모컴포넌트, 자식컴포넌트

소스 확인(링크를 통해 작성한 내용 확인이 가능합니다)

 

Vue SFC Playground

 

play.vuejs.org

1. 부모컴포넌트

<script setup>
    import CustomInput from './CustomInput.vue'
    import {ref} from 'vue'

    const message = ref('')
</script>

<template>
  메시지: {{ message }} <br/>
  <CustomInput v-model:message="message"/>
</template>

ref 로 message 를 선언 후
v-model 과 연동하여 자식 컴포넌트에 값을 내려준다.

 

2. 자식컴포넌트

<script setup>
  const props = defineProps({
    message: String,
  })
  const emits = defineEmits(['update:message'])
  
  const updateInputs = (e, type) => {
    emits(`update:${type}`, e.target.value)
  }
</script>

<template>
  <input
    :value="message"
    @input="updateInputs($event,'message')"
  /> 
</template>

props: defineProps 로 message 값을 받아온다고 선언
emit:  props로 받아온 message키 값으로 update:message상신할 것을 선언

method: updateInputs 에서 받아온 event 를 기준으로 value 를 emit 시켜주는 것을 확인 할 수 있다.

 

 


업무 중에 이전 소스에서 emit('update:input') 이라고 선언되어있길래 처음 보고, 이해가 안되어 공식문서를 찬찬히 살펴보게 되었다.

v-model 관련하여 문서를 찾아보게 되었고, component v-model 이라는 곳에서 확인할 수 있었다.

내용은 제대로 익히기 위해 playground에서 작성하였다.

 

 

 

Component v-model | Vue.js

 

ko.vuejs.org

 

 

[VUE] 컴포넌트에 여러 개 v-model 사용하기 (props 값 바꾸기)

안녕하세요! 프뚜(프로그래머 뚜)입니다! [개발 환경] - OS: windows 10 64bit - git: 2.37.1.windows.1 - nodejs: v16.16.0 - npm: 8.15.0 - yarn: 1.22.19 - @vue/cli(vue3): 5.0.8 컴포넌트에 값을 넘길 때 props를 사용합니다. 여

ssjeong.tistory.com

 

반응형

Vue.js 공식 문서를 보고 작성한 내용입니다.

 

그간 slot 의 존재는 알고 있었지만,
컴포넌트에 대한 이해력 부족으로 + 알아보기 귀찮음으로 학습을 하지 않고 미뤄왔던 내용 중 하나였다.

Slot

 

슬롯 | Vue.js

 

ko.vuejs.org

 

1. 간단하게 생각해서 버튼 내에 작성할 내용을 대체할 수 있다고 생각하면 편하다.
2. 좀 더 나아가서, 특정 태그 내에 특정 컴포넌트 등을 삽입할 수 있다. 

 

 

1. 버튼에 slot 적용해보기

// 1. slot 을 작성한 버튼 컴포넌트
<template>
  <button type="submit">
	<slot>this is replace context</slot>
  </button>
</template>

// 2. 위에서 작성한 컴포넌트를 활용
<template>
  <!-- slot에 작성하였던 내용을 그대로 노출하게 된다. -->
  <SubmitButton />
  
  <!-- 내가 작성한 내용이 있을 경우 slot이 대체된다. -->
  <SubmitButton>저장할겁니다</SubmitButton>
</template>

작성 결과

 

2. 컴포넌트도 slot 내부에 넣을 수 있다.

// 또 다른 컴포넌트 생성
<template>
  <div>
    두 번째 컴포넌트입니다.
  </div>
</template>
// 위에서 생성한 컴포넌트를 상위 컴포넌트에서 slot내에 추가
  <SubmitButton>
    <Comp />
    저장할겁니다
  </SubmitButton>

컴포넌트가 포함된 slot

이렇게 새로운 컴포넌트를 생성하고,
Button 컴포넌트 slot 에 추가한 컴포넌트를 포함시킬 수 있습니다.

 

이상입니다.

 

해당 내용을 공부하다보니, 리액트에서 props로 내려주던 text 부분을 slot으로 교체가 가능하겠다는 생각에 도달하였다.

기존에 사용하던 props의 개수를 줄이고 좀 더 가변적이고 다양한 모습의 코드를 짜도록 노력해야겠다.

 

프로젝트 도중에 custom-emit 관련한 내용을 살펴보던 중 이렇게 slot을 발견하고 이해할 수 있어서 너무 다행이라는 생각이 듭니다.오늘도 하나 배워갑니더.

반응형

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

안녕하세요 상훈입니다. 아주 예전에 이와같은 내용을 작성하긴했었던 것 같은데, 아예 뷰를 안쓰다보니 완전히 까먹어서.. 다시 공부해서 다시 글을 작성하게 되었습니다!

사전지식은 다음과 같습니다.

1. 컴포넌트의 관계를 이해한다.
2. 자식 컴포넌트 → 부모 컴포넌트로 데이터를 전달하고싶다.

 

Vue.js Todolist 를 구현할 때 Add의 한 부분을 담당하고 있습니다.

 

1. 부모 컴포넌트 Parent Component

//부모컴포넌트 : Todo.vue
<template> 
  <div>
    <h3>Greeting!</h3>
    <TodoInput @addNewTodo="checknew" />
  </div>
</template>
<script>
import TodoInput from "./TodoInput.vue";

export default {
  components: {
    TodoInput,
  },
  methods: {
    checknew(newItem) {
      this.newTodo = newItem;
    },
  },
};
</script>

 

2. 자식 컴포넌트 Child Component

//자식 컴포넌트 : TodoInput.vue
<template>
  <div>
    <input
      type="text"
      maxlength="20"
      v-model="newItem"
      @keyup.enter="addTodo"
    />
    <button type="button" @click="addTodo">Add</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      newItem: "",
    };
  },
  methods: {
    addTodo() {
      this.$emit("addNewTodo", this.newItem);
    },
  },
};
</script>

3. 위 코드를 보고서 이해가 잘 안되셨을 때 봐주세요.

핵심은 $emit@이벤트 핸들러입니다.

자식 컴포넌트에서 
1) addTodo 라는 메서드를 실행합니다.
2) $emit을 통해 addNewTodo 라는 Props로 전달합니다.

부모 컴포넌트에서
1) addNewTodo 라는 Props가 있습니다.
2) 그리곤 newTodo 라는 메서드로 값을 받아옵니다.

부모 > 자식의 관계는 전부 Props 입니다.

addNewTodo 의 props 명으로 이벤트를 지정해놓는 것이죠

그런데, 자식에서 이벤트가 발생 → $emit으로 메서드 newTodo 를 콜백함수처럼 받아온다고 생각하면, 이해하시기 수월해집니다. 

 

Vanila Javascript 

//부모 컴포넌트
parent (function (ret) {
    //자식 컴포넌트에서 보낸 값을 ret으로 받아옴
    console.log(ret);
});

물론 parent라는 함수를 선언해주지 않았기 때문에 위 함수는 오류지만, 요점은 콜백함수처럼 생각하면된다는 겁니다.

반응형

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

안녕하세요 상훈입니다.

리액트 네이티브에서 어플리케이션을 구현할 때, 화면의 넓이, 혹은 높이를 자동으로 측정하여 사용할 수 있는 API를 포스팅하려고 합니다.

바로 " Dimesions " 라는 API 인데요, react-native의 기본 컴포넌트 중 하나입니다.

■ 사용방법

import { Dimensions } from "react-native";

// 기본형은 width, height
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get("window");

export default function App() {
  return (
 	<View style={styles.container}>
    	<View style={styles.insideContainer} />
    </View>
  )
};

// STYLES
const styles = StyleSheet.create({
	container: {
    	flex: 1,
    	backgroundColor: 'orange',
    },
    insideContainer: {
    	width: SCREEN_WIDTH,
    }
});

이렇게 사용하시면 됩니다.

자동으로 모바일 기기의 전체 width를 탐지하고 적용. 

console.log로 찍어보면, 

console
꽉찬 가로 사이즈

 

이상입니다.

 

반응형

안녕하세요 상훈입니다.

React.js 를 사용하던 와중 history를 사용하려고하는데 에러가 발생하였습니다.

export 'useHistory' (imported as 'useHistory') was not found in 'react-router-dom' (possible exports:

내용은 'useHistory' 라는 함수가 존재하지 않는다는 내용이었습니다.

 

리액트의 버전이 올라가면서 또 사용되지 않는 내용인데요,

이전 내용

이렇게 사용하던 내용들이 이제는  아래와 같이 사용해주시면 됩니다.

 

더욱 간결한 함수의 등장으로 이제는 useHistory를 사용하지 않습니다!

 

이상입니다.

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

 

참고

 

Attempted import error: 'useHistory' is not exported from 'react-router-dom'

useHistory giving this error: Failed to compile ./src/pages/UserForm/_UserForm.js Attempted import error: 'useHistory' is not exported from 'react-router-dom'. This error occurred during the build...

stackoverflow.com

 

반응형

Vue.js 3 에서 Custom Directives 를 사용하는 방법에 대해 포스팅 하겠다.

 

■ Custom Directive

1. v-model, v-show 디렉티브 같은 기본 디렉티브 이외에도 사용자가 직접 디렉티브를 정의해서 사용할 수 있다.
2. 전역에서 사용할 수 있다. 물론 각각의 컴포넌트에서도 가능하다.
  -> 사용하기에 따라 유용하겠죠?

 

예시) 사용자가 컴포넌트에 접속했을 때,
        입력필드로 자동 포커스 ( === autofocus) 되는 커스텀 디렉티브와
        배경이 노란색의 컴포넌트

 

■ 전역 컴포넌트 사용하기

// Directives.js

// 1.배경색 노란색으로 설정
export const MyHighlightDirective = {
    beforeMount(el){
        el.style.background = 'yellow'
    }
}

// 2. mounted 후에 focus로 해당 항목에 자동으로 focus. === html: autofocus
export const MyFocus = {
    mounted(el) {
        el.focus()
    }
}
// main.js
import { MyHighlightDirective, MyFocus } from './directive/HighlightDirective'

// 보기 편하게 directive를 2개로 분리하였다. 배열로 해도 상관없을까?
createApp(App)
.directive('highlight', MyHighlightDirective)
.directive('focus', MyFocus)
.use(router).mount('#app')

 

main.jsimport 후, 아무 컴포넌트에서 해당 directive를 호출이 가능
-> 전역으로 등록하였기 때문에 별도의 선언·호출 없이 사용이 가능하다.

// Directives.vue
<template>
  <div>
      <h1>Directives</h1>
      <p v-highlight>It will be background yellow by Direction : "v-highlight" by Directions</p>
      <input v-focus type="text">
  </div>
</template>

 

■ 컴포넌트 내부에서 선언하고 사용하기

- 오히려 전역으로 등록하는 것보다 간단하다.

// Directives.vue
<template>
  <div>
      <h1>Directives</h1>
      <p v-highlight>It will be background yellow by Direction : "v-highlight" by Directions</p>
      <input v-focus type="text"><br>
      <p v-backgroundRed>It will be background red</p>

  </div>
</template>

<script>
export default {
    directives: {
        backgroundRed: {
            beforeMount(el) {
                el.style.background = 'red'
                el.style.color = 'white'
            }
        }
    }
}
</script>

 

 

이상입니다.

 

 

 

Custom Directives

v-model, v-show 디렉티브 같은 기본 디렉티브 이외에도 사용자가 직접 디렉티브를 정의해서 사용할 수 있다.

sun-bobolink-b3b.notion.site

 

반응형

Vue.js 에서 Component (컴포넌트)를 3가지 방법으로 선언할 수 있다.

1. Global (전역 선언)
2. Local (지역 선언)
3. 파일 분리

 

1,2번의 방법은 사실 별로라고 생각한다. 그 이유인즉슨, 특정 컴포넌트 내에 또 다른 컴포넌트 작성하여 적용시키는 방법이라 생각하면 되는데, 가독성이 좋지 않다.

물론 컴포넌트를 한 개의 파일에서 관리할 수 있다는 매력이 있지만, 애초에 `template` 속성 내에 전부 때려 넣다보니 편리함보다는 오히려 보기가 너무 불편하다.

Syntax Highlight 지원도 받기 어렵다. (혹시 있나?)

 

■ Global [전역]

예시)

이렇게 ' component 명' 을 먼저 선언하고,
그 뒤에 template 속성을 선언하여  `  ` 속에 html 을 비롯한 모든 태그들을 작성하는 것이다.

 

■ Local [지역]

지역 선언은 전역과 약.간. 다르다.

예시)

차이점은 변수에 할당한다는 점... ( ES6로 넘어오면서 코드의 엄격성을 생각하여 var 사용은 자제하자.)
나머지는 동일하게 template 내에 작성한다.

 

■ 파일분리

가장 선호하는 방식이고, 주로 사용되는 방식이다.

[ Header.vue,  Content.vue ] 가 있다면, Header.vue 내에 Content.vueimport하여 사용하는 것이다.

 

경로는 같은 폴더 내를 기준으로 작성하였습니다.

 

이렇게 넣으면 컴포넌트 간따로 파일을 관리하여 유지보수 하기에 용이하다.

데이터 통신을 하기 위해서는 다른 수고를 넣어야하지만, 가독성이 좋아져서 선호한다.

 

 

 

참고 

 

Components | Cracking Vue.js

뷰 컴포넌트 컴포넌트는 화면의 영역을 구분하여 개발할 수 있는 뷰의 기능입니다. 컴포넌트 기반으로 화면을 개발하게 되면 코드의 재사용성이 올라가고 빠르게 화면을 제작할 수 있습니다.

joshua1988.github.io

 

반응형

+ Recent posts