惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
The Register - Security
The Register - Security
Hugging Face - Blog
Hugging Face - Blog
博客园 - 聂微东
GbyAI
GbyAI
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园_首页
D
Docker
S
Security @ Cisco Blogs
K
Kaspersky official blog
爱范儿
爱范儿
Simon Willison's Weblog
Simon Willison's Weblog
TaoSecurity Blog
TaoSecurity Blog
V
V2EX
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Troy Hunt's Blog
Cloudbric
Cloudbric
博客园 - 三生石上(FineUI控件)
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Hacker News
The Hacker News
美团技术团队
S
SegmentFault 最新的问题
L
Lohrmann on Cybersecurity
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
宝玉的分享
宝玉的分享
The Last Watchdog
The Last Watchdog
Y
Y Combinator Blog
M
MIT News - Artificial intelligence
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Martin Fowler
Martin Fowler
Google Online Security Blog
Google Online Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tor Project blog
Vercel News
Vercel News
The Cloudflare Blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
AI
AI
Stack Overflow Blog
Stack Overflow Blog
I
InfoQ
Scott Helme
Scott Helme
S
Schneier on Security
大猫的无限游戏
大猫的无限游戏
The GitHub Blog
The GitHub Blog
S
Securelist
IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog

The Tracks of mulder21c

고정된 참조 위치 정보 선형 이미지의 최소 명도 대비 요구사항은 몇 대~ 몇? 단일 문자 단축키 (Character Key Shortcuts) 입력 방식(Input Modalities) 적응성(Adaptable) KWCAG 2.2 변경 사항 개요 Git hook으로 브랜치 이름 규칙 강제하기 댓글 시스템 remark42로 변경기 새 테마로 갈아입힘 Atomic Design + Storybook 적용 후기 json-server에 사용자 인증 구현하기 개발환경 WSL2 + zsh로 갈아타기 2020년 회고 colum flexbox에서 padding bottom 문제 해결 Nuxt를 통해 보는 프론트엔드 개발자가 하는 일 Nuxt Router kebab-case 처리 JS to SCSS 변환 Nuxt + Storybook 통합 하기 2020 이직 이야기 2020 이직 이야기 2020 이직 이야기 2020 이직 이야기 Windows에서 PM2 실행 오류 해결 오픈톡 정지에 대한 카카오톡 고객센터 후기 배려에 대한 단상 학습이 잘 되지 않는 이유 웹팩 4 마이그레이션 삽질기 babel 7 업데이트 후 node_modules 패키지가 변환되지 않는다면? white space는 4px이다? 정말? 2020년 시간 관리를 위해서 도입 한 툴들 Codility Lesson 5 — PassingCars 2019년 회고 Codility Lesson 4 — MissingInteger Codility Lesson 4 — MaxCounters Codility Lesson 4 — FrogRiverOne Codility Lesson — PermCheck 착각은 자유가 아닌각 세미나 진행 후기 Codility Lesson 3 — tapeEquilibrium Codility Lesson 3 — PermMissingElm Codility Lesson 3 — FrogJump 알고리즘 연습을 다시 시작했다. Codility Lesson 2 — CyclicRotation Codility Lesson 2 — OddOccurrencesInArray Codility Lesson 1 — BinaryGap 아이패드 구매 하고 3주 써 본 기록 세미나 어떻게 준비해야 할까? HTML은 웹이다 접근성 향상을 위한 이름 짓기 접근성 교육에서 자주 나오는 상위 5가지 질문
Pass function as props in vue
멀더끙 · 2021-01-24 · via The Tracks of mulder21c

Event handling and Atomic Design System

Atomic Design System을 컴포넌트 설계 방법론으로 가져가면서, 각 컴포넌트에 독립적으로 고립(?)된 데이터 구조를 만들게 되면서 (이게 맞는 방식인지는 잘 모르겠지만) 불편함이 점점 발생되었던 것 중 하나가 유저 인터랙션에 의해 발생되는 데이터 변경을 위해 쌓여진 컴포넌트 구조를 따라 계속 이벤트를 전달하고 이벤트 리스너를 통해 처리하는 방식이었다.

예를 들자면

유저 인터랙션으로 하위 컴포넌트로부터 상위 컴포넌트로의 이벤트 발생 과정

이런 흐름 말이다.

Vue 공식 문서도 그렇고, 지금까지 보아온 대다수의 강의에서도 유저 인터랙션에 대한 데이터를 처리할 때 해당 데이터가 상위 컴포넌트에 존재할 경우, $emit을 이용하여 payload와 함께 하위 컴포넌트로부터 상위 컴포넌트로 차례로 올리고, 상위 컴포넌트에서 v-on으로 처리하는 방식을 사용하도록 안내하는 듯 하다.

Atomic Design Sytem을 적용하기 전에는 이러한 고민이 없었는데, 적용 이후로는 atom으로부터 실제 데이터가 바인딩 되는 page까지 5개 단계(?)를 거치게 되니 하위 컴포넌트에서 발생한 이벤트와 데이터를 다시 상위 컴포넌트로 by-pass 하기 위한 이벤트 처리가 뭐랄까… 조금 거슬린다고 할까?
심지어 Vue 개발자 도구로 데이터 흐름을 확인하려고 하면 한 번의 인터랙션에 여러 개의 emit이 로그로 출력되니 정신이 사납기까지 한 느낌이다

그래서 props로 이벤트 핸들러를 내려주고, 가장 기저에 있는 atom에 해당하는 컴포넌트가 이 핸들러를 실행시키기만 하면 어떨까 하는 생각에 prop로 함수를 내려주는 방식을 생각해보게 됐다.

Is it an anti-pattern?

일단 생각을 해 봤으니 이게 가한 것은 맞는지 확인 해 볼 필요가 있었다. (처음 생각해 본 방법이고 Vue 관련 문서나 강의에서도 한 번도 이런 케이스를 본 적이 없으니까…)

구글링 결과 공교롭게도(?) 가장 먼저 눈에 띈 내용은 이 방식이 안티 패턴이라는 내용이었다.
(혹 관련 내용이 궁금하다면 How to Pass a Function as a Prop in Vue를 읽어보시길… 아, 중간에 구독하라고 전체 팝업창이 뜨기는 하는데 개발자라면 뭐… 다 쉽게 걷어내… 쿨럭… )

하지만 왜 인지 모르겠으나… 해당 글에서는 안티 패턴임을 설명하는데 하위 컴포넌트의 mounted 훅에서 props로 받은 함수를 실행하는 코드를 보여주고 있었다.
무튼 그러면서 잘못된 것은 아니지만, Vue의 컨셉에 맞게 이벤트를 활용하거나 슬롯을 사용하라는 결론을 내주는게 영…

또 다른 아티클 들에서는 단순하게 props로 함수를 내리는게 가능하다 라는 짤막한 소개 정도가 있었다.

하여 안티 패턴이라 소개하는 글을 잠시 무시하기로 하고(?) props로 함수를 내리는 방식을 사용해봤다.
아, 안티 패턴이라 소개하는 글을 무시하기로 한 것은 안티 패턴을 굳이 사용하겠다는 것이 아니라, 안티 패턴인 이유에 대한 명확한 근거를 찾을 수 없어서다. 차후에라도 이것이 안티 패턴이라는 명확한 근거를 찾게 된다면 당연히 과감히 버릴거다.

Try it

<template>
  <SignUpTemplate :handle-sign-up="signUp" />
</template>
<script>
export default {methods: {signUp({ email, password }) {
      users
        .postSignUp({ email, password })
        .then()
        .catch()
    }
  }
};
</script>

Page에서 이렇게 signUp 함수를 props로 내려주고

<template><SignUpForm :handle-submit="handleSignUp" /></template>

<script>
export default {props: {handleSignUp: {
      type: Function,
      required: true,
      default: () => {}
    }
  },};
</script>

템플릿에서 props로 받은 함수를 다시 하위 컴포넌트로 내려주고,

<template>
  <form-container><DefaultButton
      @click.native.prevent="handleClickSubmit"
    /></form-container>
</template>

<script>
import DefaultButton from "@atoms/Button/Default";
export default {
  components: {
  props: {
    handleSubmit: {
      type: Function,
      required: true,
      default: () => {}
    }
  },
  methods: {
    handleClickSubmit() {
      const { handleSubmit, email, password, passwordConfirm } = this;
      …
      handleSubmit && handleSubmit({ email, password });
    }
  }
};
</script>

유저 인터랙션이 발생하는 하위 컴포넌트에서 해당 함수를 전달받아 실행하게 했다.
적용 결과는 당연히(?) 원하는 동작을 올바르게 수행해주었다.

이것보다는 modal 창을 포함하는 organism 컴포넌트에서 modal 창에 대한 제어와 modal 내부에 slot으로 끼워진 컴포넌트에 적용되는 부분이 이 방식을 더 잘 설명할 수 있을 것 같지만 너무 많은 코드가 삽입 되어야 해서 포스팅에는 간단한 위 코드로 적었다.

사실 event emit 방식으로도 충분히 대체도 가능하고 그것이 난이도나 복잡도가 더 높지는 않은 것 같기는 하다. 하지만, 뭐랄까 이 방식이 좀 더 dry한 느낌이 든달까? (기분탓이려나?)

무엇보다 개발자 도구에 여러 번에 걸친 이벤트 발생 로그를 보지 않아도 되니 한결 눈이 가벼워졌다.