Vue: UI ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ๊ฐœ์„ ๋œ API, ์ „๋‹ฌ ์†์„ฑ ๋ฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ƒ์šฉ๊ตฌ ๊ฐ์†Œ

์— ๋งŒ๋“  2017๋…„ 06์›” 27์ผ  ยท  46์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: vuejs/vue

์ด ๊ธฐ๋Šฅ์€ ์–ด๋–ค ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๊นŒ?

Vue ๊ตฌ์„ฑ ์š”์†Œ์— ์ „๋‹ฌ๋œ ์†์„ฑ์€ ๋ฃจํŠธ ์š”์†Œ๊ฐ€ ์•„๋‹ˆ๋ผ ํ•˜์œ„ ์š”์†Œ์— ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด UI ๊ตฌ์„ฑ ์š”์†Œ ์—์„œ ์†์„ฑ์ด div ๋ž˜ํผ ๋Œ€์‹  input ์š”์†Œ์— ์ถ”๊ฐ€๋˜๋„๋ก ํ•˜๋ ค๋ฉด ์—„์ฒญ๋‚œ ์–‘์˜ ์†Œํ’ˆ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์–‘์‹ ์š”์†Œ์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ƒ์œ„ ์š”์†Œ์— ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์ข…์ข… ๋ฐ”๋žŒ์งํ•˜๋ฉฐ ์š”์†Œ๊ฐ€ ๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ํ˜„์žฌ ๋งŽ์€ ์ƒ์šฉ๊ตฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(์ด ๊ฒฝ์šฐ .native ์ˆ˜์ •์ž๊ฐ€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ).

์ œ์•ˆ๋œ API๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๊นŒ?

ํŽธ์ง‘: ํ† ๋ก ์„ ๋”ฐ๋ผ์žก์œผ๋ ค๋ฉด ์—ฌ๊ธฐ ์—์„œ

ํ˜„์žฌ ๊ธฐ๋ณธ์ ์œผ๋กœ "๋…ธ์ถœ๋œ" ์š”์†Œ(์ž„์˜ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ์š”์†Œ)๋Š” ํ•ญ์ƒ ๋ฃจํŠธ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ์ƒˆ ์ง€์‹œ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๋…ธ์ถœ๋œ ์š”์†Œ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์‹œ๋ฌธ ์ด๋ฆ„์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์•„์ด๋””์–ด:

  • v-expose (์•„๋งˆ๋„ ๊ฐœ์ธ์ ์œผ๋กœ ๊ฐ€์žฅ ์ข‹์•„ํ•˜๋Š” ๊ฒƒ)
  • v-expose-attrs (๋” ๋ช…ํ™•ํ•˜์ง€๋งŒ ๋” ๊น๋‹ˆ๋‹ค)
  • v-main
  • v-primary

v-expose ๊ฐ€ ์š”์†Œ์— ์ถ”๊ฐ€๋˜๋ฉด ๊ตฌ์„ฑ ์š”์†Œ์— ์ „๋‹ฌ๋œ ์†์„ฑ์„ ํ—ˆ์šฉํ•˜๋ฉฐ ์ด๋Ÿฌํ•œ ์†์„ฑ์€ ๋ฃจํŠธ ์š”์†Œ์— __๋” ์ด์ƒ ์ „๋‹ฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค__.

์ข‹์€ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ:

  • ์ง€์‹œ๋ฌธ์ด ์—ฌ๋Ÿฌ ์š”์†Œ์— ์ •์˜๋œ ๊ฒฝ์šฐ ์†์„ฑ์€ ๊ฐ ์š”์†Œ์— ๊ฑธ์ณ ๋ณต์ œ๋ฉ๋‹ˆ๋‹ค.
  • ์†์„ฑ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ด ์š”์†Œ์— ์˜ํ•ด ํ—ˆ์šฉ๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ v-expose ๋Š” ๋ฌธ์ž์—ด ๋˜๋Š” ๋ฌธ์ž์—ด ๋ฐฐ์—ด(์˜ˆ: v-expose="class" ๋˜๋Š” v-expose="['class', 'type', 'placeholder']" )์„ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ์†์„ฑ์€ ๋ฃจํŠธ ์š”์†Œ ๋Œ€์‹  ์š”์†Œ์— ์ถ”๊ฐ€๋˜์ง€๋งŒ ๋‹ค๋ฅธ ๋ชจ๋“  ์†์„ฑ์€ ๋ฃจํŠธ ์š”์†Œ ๋˜๋Š” ๊ฐ’์ด ์—†๋Š” v-expose ์š”์†Œ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. .
discussion feature request

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@chrisvfritz ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋ฃจํŠธ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์†์„ฑ์˜ ์ž๋™ ์ƒ์†์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ์˜ต์…˜ ์ œ๊ณต
  • ์ด๋Ÿฌํ•œ ์†์„ฑ์„ $attributes ๋กœ ๋…ธ์ถœํ•˜์‹ญ์‹œ์˜ค. ์˜ˆ๋ฅผ ๋“ค์–ด (tbd๋กœ ๋ช…๋ช…)
  • $props ์ด๋ฏธ ๋ณด์—ฌ์ค€ ๊ฒƒ์ฒ˜๋Ÿผ v-bind๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ๊ณณ์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.
v-bind="$attributes"

JSX/๋ Œ๋”๋ง ๊ธฐ๋Šฅ์—์„œ ์‹ค์งˆ์ ์œผ๋กœ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ถ”๊ฐ€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  46 ๋Œ“๊ธ€

ํ , ๊ทธ๊ฑด ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๊ทธ๋Ÿฐ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ JSX ๋˜๋Š” createElement ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†Œํ’ˆ์„ ํผ๋œจ๋ฆด ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

https://github.com/doximity/vue-genome

์šฐ๋ฆฌ์—๊ฒŒ ์ด๊ฒƒ์€ ํ›Œ๋ฅญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์Šคํƒ€์ผ ์ง€์ • ๋ฐ ux ๋ชฉ์ ์œผ๋กœ ๋ชจ๋“  ์ž…๋ ฅ์„ ๋ ˆ์ด๋ธ”๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  jsx๋กœ ๋“œ๋กญ๋‹ค์šดํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•˜์ง€๋งŒ ํ…œํ”Œ๋ฆฟ์€ ๋ชจ๋‘๊ฐ€ ๋”ฐ๋ผํ•˜๊ธฐ๊ฐ€ ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค.

@Austio , ๋ถˆํ–‰ํžˆ๋„ ํ…œํ”Œ๋ฆฟ์— ๋Œ€ํ•œ spread ์†Œํ’ˆ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฐœ์ธ์ ์œผ๋กœ ์ด ๊ธฐ๋Šฅ์ด ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋•Œ๋•Œ๋กœ ๋ฃจํŠธ ์š”์†Œ์— ๋Œ€ํ•œ class ์†์„ฑ์„ ๋ฐ”์ธ๋”ฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ v-bind ๋™์ž‘์˜ ์ผ๊ด€์„ฑ์„ ๊นจ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•œ ์Œ์˜ ์ง€์‹œ๋ฌธ์„ getter ๋ฐ setter๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

๊ตฌ์„ฑ ์š”์†Œ ๋‚ด๋ถ€์—์„œ v-expose ์•ต์ปค๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

<input v-expose="foo" />

๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๋•Œ:

<the-component v-define:foo="{propA: '', propB: ''}"></the-component>

<!-- or maybe use v-bind for it directly -->
<the-component :foo="{propA: '', propB: ''}"></the-component>

@jkzing , ๋ฉ‹์žˆ์–ด ๋ณด์ด์ง€๋งŒ ๋‹ค์‹œ ๊ธฐ๋ณธ ์Šคํ”„๋ ˆ๋“œ์ฒ˜๋Ÿผ ๋ณด์ด๊ณ  @keyup.enter.prevent="myAction" ์–ด๋–ป๊ฒŒ ์ •์˜ํ•  ๊ฒƒ์ธ๊ฐ€์™€ ๊ฐ™์€ ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

<the-component :foo="{'@keyup.enter.prevent': myAction}"></the-component> ๋งŒ ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋Ÿฐํƒ€์ž„์— enter ๋ฐ prevent ์™€ ๊ฐ™์€ ๋ชจ๋“  ์ˆ˜์ •์ž๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(vue-template-compiler์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค). ATM)

@nickmessing

๊ธฐ๋ณธ ์Šคํ”„๋ ˆ๋“œ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋Š” ๊ฒƒ์€ ํ…œํ”Œ๋ฆฟ ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ์Šคํ”„๋ ˆ๋“œ์™€ ๊ฐ™์€ ๊ฒƒ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

<the-component :foo="{'@keyup.enter.prevent': myAction}"></the-component>

@ ๋Š” v-on shortland์ด๋ฉฐ prop (v-bind)๋ฅผ ์˜๋ฏธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@jkzing , ์„ค๋ช…์˜ ๋งํฌ์—๋Š” v-on ๋ฐ”์ธ๋”ฉ๋„ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@nickmessing ์Œ... v-on ๋ฐ”์ธ๋”ฉ์€ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง๊ณผ ๊ฐ™์€ ๋˜ ๋‹ค๋ฅธ ์ฃผ์ œ IMO์ž…๋‹ˆ๋‹ค. ๐Ÿค”

@jkzing , ๊ทธ๊ฒƒ์€ v-expose afaik์˜ ์ „์ฒด ๊ฐœ๋…์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์†์„ฑ์„ ๊ตฌ์„ฑ ์š”์†Œ์˜ ํŠน์ • ์š”์†Œ๋กœ "์ด๋™"ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@nickmessing , ์›๋ž˜ ์ œ์•ˆ์— ๋Œ€ํ•ด ํ™•์‹ ํ•  ์ˆ˜ ์—†์ง€๋งŒ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ attribute ๋กœ ๊ฐ„์ฃผ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@jkzing , ์•„๋งˆ ์•„๋‹ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, >9000๊ฐœ์˜ ๋‹ค๋ฅธ ์†Œํ’ˆ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” <my-awesome-text-input /> ์˜ ์ผ๋ฐ˜์ ์ธ ์˜ˆ๋ฅผ ๊ณ ๋ คํ•  ๋•Œ, ๋‹น์‹ ์€ ๊ทธ๊ฒƒ๋“ค์ด ๋ชจ๋‘ <input /> ์— ๋„๋‹ฌํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ์˜.

์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ v-bind="$props" ํ•˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋งํ•˜์—ฌ ์ ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ์†Œํ’ˆ์„ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ž…๋ ฅ์— ์—ฌ๋Ÿฌ ์†Œํ’ˆ์„ ํ•œ ๋ฒˆ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ v-expose๋Š” ์ž…๋ ฅ๊ณผ ๊ฐ™์€ ๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ ๋ชจ๋“  html ์†Œํ’ˆ์„ ์ง€์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ด๊ฑฐ
https://github.com/almino/semantic-ui-vue2/blob/master/src/elements/Input.vue#L9
์ง€ํŒก์ด๋Š” v-bind="$props" ๋˜๋Š” v-bind="filteredProps" ๋กœ ์ถ•์†Œ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ filterProps๋Š” ์ผ๋ถ€ ๊ณ„์‚ฐ๋œ ์†์„ฑ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@cristijora ์šฐ๋ฆฌ๋„ v-bind="someProps" ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์†”๋ฃจ์…˜์˜ ๋ฌธ์ œ๋Š” ๊ณผ๋„ํ•œ ์†์„ฑ์ด HTML ์†์„ฑ์œผ๋กœ ์ถ”๊ฐ€๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. v-bind= ๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ๋ชจ๋“  ์†์„ฑ์„ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋™์  <component> ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณ„์‚ฐ๋œ ์†์„ฑ์—์„œ ์–ด๋–ค props๋ฅผ ํ•„ํ„ฐ๋งํ• ์ง€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ถ”์ถœ options.props ์‚ฌ์šฉํ•  lodash._pick .

์ด๊ฒƒ์ด ๋””๋ ‰ํ‹ฐ๋ธŒ๋กœ ์ •๋ง ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ?

@posva , ๋‚˜๋Š” ์ด๊ฒƒ์ด ๊ทธ ์ž์ฒด๋กœ ์ง€์‹œ๋ฌธ์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ ํ™•์‚ฐ + ์ผ๋ถ€ ์ด๋ฒคํŠธ ์ „ํŒŒ์™€ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” vue ํ…œํ”Œ๋ฆฟ ์—”์ง„์˜ ์ผ๋ถ€๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@posva ์‚ฌ์šฉ์ž๊ฐ€ ๋งŒ๋“  ์ง€์‹œ๋ฌธ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฏ€๋กœ ์ž˜๋ชป๋œ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ ๋‹จ์ง€ "ํŠน์ˆ˜ํ•œ ์†์„ฑ"์ž…๋‹ˆ๋‹ค.

@chrisvfritz API๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์ƒ๊ฐ์ด

๋‚˜๋Š” ์ด๊ฒƒ์ด ๊ฐœ๋…์„ ์ œ๊ณต/์ฃผ์ž…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@Austio ์งˆ๋ฌธ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์›๋ž˜ ๊ฒŒ์‹œ๋ฌผ์—์„œ API์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ƒ๊ฐ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Hey Chris๋Š” ๋ถ€๋ชจ์—์„œ ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์„ ์–ธํ•œ ๋‹ค์Œ ์ž์‹์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ƒ๊ฐ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค.

์•„, ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ •๋ณด๋Š” ์ด๋ฏธ ์†Œํ’ˆ๊ณผ ์Šฌ๋กฏ์„ ํ†ตํ•ด ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ถ€๋ชจ์˜ ๊ฐœ์ธ ์†์„ฑ๋„ this.$parent ๋กœ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

@Austio ์ƒ๊ฐํ•˜๊ณ  ์žˆ๋Š” ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@chrisvfritz ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋ฃจํŠธ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์†์„ฑ์˜ ์ž๋™ ์ƒ์†์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ์˜ต์…˜ ์ œ๊ณต
  • ์ด๋Ÿฌํ•œ ์†์„ฑ์„ $attributes ๋กœ ๋…ธ์ถœํ•˜์‹ญ์‹œ์˜ค. ์˜ˆ๋ฅผ ๋“ค์–ด (tbd๋กœ ๋ช…๋ช…)
  • $props ์ด๋ฏธ ๋ณด์—ฌ์ค€ ๊ฒƒ์ฒ˜๋Ÿผ v-bind๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ๊ณณ์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.
v-bind="$attributes"

JSX/๋ Œ๋”๋ง ๊ธฐ๋Šฅ์—์„œ ์‹ค์งˆ์ ์œผ๋กœ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ถ”๊ฐ€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@LinusBorg ๋‚˜๋Š” ๋‹น์‹ ์ด ์ƒ๊ฐํ•˜๋Š” ๋ฐฉ์‹์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜„ ํ›จ์”ฌ ๋” ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ, ์ด API๊ฐ€ ์žˆ์œผ๋ฉด Vue์˜ ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „์ด ์†์„ฑ ์ž๋™ ์ƒ์†์„ ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜์—ฌ ๊ตฌ์„ฑ ์š”์†Œ ๊ฐ„ ํ†ต์‹ ์ด ์–‘์ชฝ์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ์œ ์ง€๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด ๋™์ž‘์„ ํ‰๊ฐ€์ ˆํ•˜ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์ด ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๋ฉด libs ๋“ฑ์˜ ๋งŽ์€ ๊ตฌ์„ฑ ์š”์†Œ์— ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฒฐ์ •ํ•˜๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ, ํŠนํžˆ UI ์ปฌ๋ ‰์…˜ ์ž‘์„ฑ์ž์™€ ๋…ผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ œ์•ˆ๋œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ A: ์ด ์ •๋ณด๋Š” context.data.attributes ๋ฅผ ํ†ตํ•ด ๊ธฐ๋Šฅ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ด๋ฏธ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด ๊ธฐ๋Šฅ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ธ์Šคํ„ด์Šค ๊ตฌ์„ฑ ์š”์†Œ์— ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋„ค, ๋งž์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์—ผ๋‘์— ๋‘๊ณ  ์žˆ๋Š” ์ฃผ์š” ๋ชฉ์ ์€ UI ๊ตฌ์„ฑ ์š”์†Œ ์ž‘์„ฑ์ž(ํƒ€์‚ฌ ๋ฐ ๋‚ด๋ถ€ ๋ชจ๋‘)๋ฅผ ์œ„ํ•ด ์ž‘์—…์„ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

<input
  v-bind:id="id"
  v-bind:accept="accept"
  v-bind:alt="alt"
  v-bind:autocomplete="autocomplete"
  v-bind:autofocus="autofocus"
  v-bind:checked="checked"
  v-bind:dirname="dirname"
  v-bind:disabled="disabled"
  v-bind:form="form"
  v-bind:formaction="formaction"
  v-bind:formenctype="formenctype"
  v-bind:formmethod="formmethod"
  v-bind:formnovalidate="formnovalidate"
  v-bind:formtarget="formtarget"
  v-bind:list="list"
  v-bind:max="max"
  v-bind:maxlength="maxlength"
  v-bind:min="min"
  v-bind:multiple="multiple"
  v-bind:name="name"
  v-bind:pattern="pattern"
  v-bind:placeholder="placeholder"
  v-bind:readonly="readonly"
  v-bind:required="required"
  v-bind:src="src"
  v-bind:step="step"
  v-bind:type="type"
  v-bind:value="value"
  v-on:keydown="emitKeyDown"
  v-on:keypress="emitKeyPress"
  v-on:keyup="emitKeyUp"
  v-on:mouseenter="emitMouseEnter"
  v-on:mouseover="emitMouseOver"
  v-on:mousemove="emitMouseMove"
  v-on:mousedown="emitMouseDown"
  v-on:mouseup="emitMouseUp"
  v-on:click="emitClick"
  v-on:dblclick="emitDoubleClick"
  v-on:wheel="emitWheel"
  v-on:mouseleave="emitMouseLeave"
  v-on:mouseout="emitMouseOut"
  v-on:pointerlockchange="emitPointerLockChange"
  v-on:pointerlockerror="emitPointerLockError"
  v-on:blur="emitBlur"
  v-on:change="emitChange($event.target.value)"
  v-on:contextmenu="emitContextMenu"
  v-on:focus="emitFocus"
  v-on:input="emitInput($event.target.value)"
  v-on:invalid="emitInvalid"
  v-on:reset="emitReset"
  v-on:search="emitSearch"
  v-on:select="emitSelect"
  v-on:submit="emitSubmit"
>

์ƒˆ๋กœ์šด $attributes ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<input
  v-bind="$attributes"
  v-on:keydown="emitKeyDown"
  v-on:keypress="emitKeyPress"
  v-on:keyup="emitKeyUp"
  v-on:mouseenter="emitMouseEnter"
  v-on:mouseover="emitMouseOver"
  v-on:mousemove="emitMouseMove"
  v-on:mousedown="emitMouseDown"
  v-on:mouseup="emitMouseUp"
  v-on:click="emitClick"
  v-on:dblclick="emitDoubleClick"
  v-on:wheel="emitWheel"
  v-on:mouseleave="emitMouseLeave"
  v-on:mouseout="emitMouseOut"
  v-on:pointerlockchange="emitPointerLockChange"
  v-on:pointerlockerror="emitPointerLockError"
  v-on:blur="emitBlur"
  v-on:change="emitChange($event.target.value)"
  v-on:contextmenu="emitContextMenu"
  v-on:focus="emitFocus"
  v-on:input="emitInput($event.target.value)"
  v-on:invalid="emitInvalid"
  v-on:reset="emitReset"
  v-on:search="emitSearch"
  v-on:select="emitSelect"
  v-on:submit="emitSubmit"
>

๊ทธ๋ž˜๋„ ์ด๋ฒคํŠธ๋ฅผ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋นˆ v-on ์ง€์‹œ๋ฌธ์ด ๋ถ€๋ชจ์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ด ์š”์†Œ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

<input
  v-bind="$attributes"
  v-on
>

๋˜๋Š” ๋ฌถ๊ณ  ์‹ถ์€ ์—ฌ๋Ÿฌ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ v-expose ์™€ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<input v-expose>

์ด๊ฒƒ์€ ํŠน์ • ๊ธฐ๋Šฅ ์š”์ฒญ์ด ์•„๋‹ˆ๋ผ UI ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ตฌ์ถ•์„ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ด‘๋ฒ”์œ„ํ•œ ๋…ผ์˜๋กœ ๋ฐ”๋€Œ์—ˆ์œผ๋ฏ€๋กœ ์ด ๋ฌธ์ œ์˜ ๋ ˆ์ด๋ธ”์„ ๋‹ค์‹œ ์ง€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿ™‚

์ด ์ฃผ์ œ์— ๋Šฆ์—ˆ์ง€๋งŒ ์ €๋„ ๋ช‡ ๊ฐ€์ง€ ์ƒ๊ฐ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

v-bind ํ˜„์žฌ ์†”๋ฃจ์…˜ ๋ฐ ๋‹จ์ 

์šฐ์„ , ์ €๋Š” ์ด๋ฏธ v-bind="propObject" ๊ธฐ๋Šฅ(๋งค์šฐ ๊ฐ•๋ ฅํ•จ)์„ ์‚ฌ์šฉํ•˜๊ณ  ์‚ฌ๋ž‘ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด bootstrap-vue ์—๋Š” ๋ชจ๋“  ๊ณณ(๋ฒ„ํŠผ, ํƒ์ƒ‰, ๋“œ๋กญ๋‹ค์šด ๋ชฉ๋ก ๋“ฑ)์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋‚ด๋ถ€ ๋งํฌ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๊ธฐ๋ณธ ์•ต์ปค๊ฐ€ ๋˜๋Š” ํ”ผ๋ฒ— ๋Œ€ ๋ผ์šฐํ„ฐ ๋งํฌ ๊ธฐ๋ฐ˜ href ๋Œ€ to ๋ฐ vm.$router ์กด์žฌํ•˜๋ฏ€๋กœ ๊ฐ๊ฐ์— ์กฐ๊ฑด๋ถ€๋กœ ์ „๋‹ฌํ•  ์†์„ฑ์ด ์ƒ๋‹นํžˆ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜.

์šฐ๋ฆฌ์˜ ํ•ด๊ฒฐ์ฑ…์€ ์ด๋Ÿฌํ•œ ์†Œํ’ˆ์„ ๋ฏน์Šค์ธ์— ๋„ฃ๊ณ  ๊ณ„์‚ฐ๋œ ๊ฐ์ฒด์™€ ํ•จ๊ป˜ v-bind="linkProps" ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•˜์ง€๋งŒ _๋งํฌ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ์— ํ•ด๋‹น ๋ฏน์Šค์ธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋งŽ์€ ์˜ค๋ฒ„ํ—ค๋“œ์ž…๋‹ˆ๋‹ค.

v-expose v-bind ์‚ฌ์šฉ ๊ฐ€๋Šฅ์„ฑ

๋‚˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ v-expose ์˜ ๊ฐœ๋…์„ ์ข‹์•„ํ•˜๋ฉฐ ๊ธฐ๋ณธ ์Šฌ๋กฏ + ๋ช…๋ช…๋œ ์Šฌ๋กฏ์ฒ˜๋Ÿผ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ˆ˜์ •์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…๋ช…๋œ ์†์„ฑ ์Šฌ๋กฏ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์†์„ฑ _"slot"_์€ ํ•ญ์ƒ ๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด์— ์†์„ฑ์„ ์ „๋‹ฌํ•˜์ง€๋งŒ(๋ณ€๊ฒฝ ์‚ฌํ•ญ ์—†์Œ), ๋‹ค๋ฅธ ๋ช…๋ช…๋œ ๋Œ€์ƒ์€ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

<template>
  <my-component 
    <!-- Nothing new here -->
    v-bind="rootProps"
    <!-- This binds the `linkProps` object to the named attribute slot `link` -->
    v-bind.link="linkProps"
  />
</template>

MyComponent.vue :

<template>
  <div>
    <router-link v-expose="link" />
  </div>
</template>

์ด๋ฒคํŠธ ํ”„๋ก์‹œ

.native ๊ฐ€ ๋†€๋ž๋„๋ก ๊ฐ•๋ ฅํ•œ ์ˆ˜์ •์ž๋ผ๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ํ•  ๋‚ด์šฉ์ด ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋ฅผ ์œ„ํ•ด ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. Vue ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๊ฑฐ์˜ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค(๊ฐœ๋ฐœ์ž๋ฅผ ์ด ๊ธฐ๋Šฅ์— ๋…ธ์ถœ์‹œ์ผœ ํ•ด๊ฒฐ๋˜๋Š” ๋งŽ์€ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฌธ์ œ๋ฅผ ๋ด…๋‹ˆ๋‹ค). ๋‚˜๋Š” ์‚ฌ์ดํŠธ์— ๋” ๋งŽ์€ ๋ฌธ์„œ์™€ ๊ฒ€์ƒ‰ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์›น์‚ฌ์ดํŠธ์— PR์„ ๊ฒŒ์‹œํ–ˆ์œผ๋ฉฐ ์ž ์žฌ์ ์œผ๋กœ Google ๊ฒ€์ƒ‰์— ์ตœ์ ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ฌธ์ œ์—์„œ API ํ‘œ๋ฉด์— ๋Œ€ํ•œ ๋…ผ์Ÿ์—์„œ ๋น„๋กฏ๋œ, ๋‚˜๋Š” v-expose ์•„์ด๋””์–ด์˜ ํŒฌ์ด ์•„๋‹˜์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋˜ ๋‹ค๋ฅธ "์ž‘๋™ ๋ฐฉ์‹"์„ ์†Œ๊ฐœํ•˜๊ณ  ํŠน๋ณ„ํ•œ ๊ฒƒ์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฉด JSX์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ React ์‚ฌ๋žŒ๋“ค์— ๋Œ€ํ•ด ์กด๊ฒฝํ•˜๋Š” ํ•œ ๊ฐ€์ง€๋Š” ์Šฌ๋ฆผํ•œ API์— ๋Œ€ํ•œ ํ—Œ์‹ ๊ณผ ๊ฐ€๋Šฅํ•œ ํ•œ ์–ธ์–ด์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์ ์—์„œ ์†์„ฑ์— ๋Œ€ํ•œ props์— ๋Œ€ํ•ด ์ด๋ฏธ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํŒจํ„ด์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋‹ค๋ฅธ ์ถ”์ƒํ™”๋ฅผ ๋„์ž…ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋‚˜์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<my-input
  type="file"
  mode="dropdown"
>
<template>
  <div>
    <input v-bind="$attributes">
    <dropdown v-bind="{ ...$props, $attributes.type }"/>
  </div>
</template

์•„, ์ง€๊ธˆ ๋ฌด์Šจ ๋ง์”€์„ ํ•˜์‹œ๋Š”์ง€ ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚œ ์ด๊ฑฐ ์ข‹์•„! ํ˜„์žฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ๊ฐ€์š”? vm.$attributes ๊ฐ€ ๋Œ€์‹  ์ถ”๊ฐ€๋ฉ๋‹ˆ๊นŒ?

๊ท€ํ•˜์˜ ์˜๊ฒฌ์„ ๋‹ค์‹œ ์ฝ์œผ์‹ญ์‹œ์˜ค. ์ง€๊ธˆ ์ถ”์  ์ค‘์ž…๋‹ˆ๋‹ค ๐Ÿ‘

์˜ˆ, $attributes ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฃจํŠธ ์š”์†Œ์— ์†์„ฑ์„ ์ ์šฉํ•˜๋Š” ํ˜„์žฌ ๊ธฐ๋ณธ ๋™์ž‘์„ ํ•ด์ œํ•˜๋Š” ์˜ต์…˜์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
```html

๊ทธ๋Ÿฌ๋ฉด Vue 3.0์˜ ๊ธฐ๋ณธ ์„ค์ •์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๋ฉด ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@LinusBorg ์‚ฌ๊ฑด์˜ ์ธก๋ฉด์„ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋‹น์‹ ์˜ ์ƒ๊ฐ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋™์ผํ•œ ์ „๋žต์„ ๋”ฐ๋ฅด๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ $listeners ์†์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

{
  input: function () { /* ... */ },
  focus: function () { /* ... */ },
  // ...
}

๊ทธ๋Ÿฌ๋ฉด v-on ๋Š” v-bind ์™€ ์œ ์‚ฌํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š”:

<input v-bind="$attributes" v-on="$listeners">

๋‚ด๊ฐ€ ์˜ˆ์ƒํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฌธ์ œ๋Š” input / change ์ด๋ฒคํŠธ์™€ ๊ด€๋ จํ•˜์—ฌ v-model ๊ฐ€ ์š”์†Œ์— ๋Œ€ํ•ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ตฌ์„ฑ์š”์†Œ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ ์šฐ๋ฆฌ๊ฐ€ $listeners ์™€ $nativeListeners ๋‘˜ ๋‹ค ์›ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. $listeners ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ .native ์ˆ˜์ •์ž๊ฐ€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ applyComponentAttrsToRoot ์˜ต์…˜๊ณผ ๊ด€๋ จํ•˜์—ฌ exposeRootEl ๊ฐ€ ์ข‹์€ ์ด๋ฆ„์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ false ๋กœ ์„ค์ •ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ ์šฉ๋œ ์†์„ฑ๊ณผ .native ์ด๋ฒคํŠธ๋ฅผ ๋ชจ๋‘ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ „์†ก?

Vue.config ๋ฅผ ํ†ตํ•ด ์ „์ฒด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋‹จ์ผ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ์ด ๊ธฐ๋Šฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ๊ทผ์— $listeners ์— ๋Œ€ํ•ด ๋น„์Šทํ•œ ์ƒ๊ฐ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

context.data.listeners

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” $props , $attributes , $listeners ๋๋‚  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

$attributes ์‚ฌ์šฉํ•œ ๊ฒƒ์ฒ˜๋Ÿผ v-on="{...}" ๊ฐœ์ฒด ๊ตฌ๋ฌธ์„ ์š”์ฒญํ•˜๋Š” #5578 ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ .native ์ˆ˜์ •์ž์— ๋Œ€ํ•ด์„œ๋Š” ํ™•์‹ ์ด ์„œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ์ด๋ฒคํŠธ์™€ ๊ธฐ๋ณธ ์ˆ˜์‹ ๊ธฐ ๋ชจ๋‘์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด API๊ฐ€ ํ›จ์”ฌ ๋” ๋ณต์žกํ•ด์ง€๊ณ  ๋ฃจํŠธ ์š”์†Œ์— ์ ์šฉ๋œ ๊ธฐ๋ณธ ์ด๋ฒคํŠธ ์ˆ˜์‹ ๊ธฐ๊ฐ€ ์›ํ•˜๋Š” ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ๊ณ„์† ์žก์•„๋‚ด๋ฏ€๋กœ ์‚ฌ์šฉ์ด ์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ์˜ ํŠน์ • ์š”์†Œ์— ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ €์ˆ˜์ค€ ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฝ์šฐ ํ…œํ”Œ๋ฆฟ์ด ์ž‘์—…ํ•˜๊ธฐ ๋ถˆํŽธํ•  ๋•Œ ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์ด ์„ ํ˜ธ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

  1. "props์—์„œ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๋ฐ”์ธ๋”ฉ์„ ๋ฃจํŠธ ์š”์†Œ์— ๋Œ€ํ•œ ์†์„ฑ์œผ๋กœ ์ž๋™ ์ ์šฉ"์˜ ๊ธฐ๋ณธ ๋™์ž‘ ๋น„ํ™œ์„ฑํ™”(๊ด€๋ จ ๋ฌธ์ œ: ์ด๊ฒƒ์ด class ๋ฐ style ๋ฐ”์ธ๋”ฉ์—๋„ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๊นŒ?)

  2. ๊ตฌ์„ฑ ์š”์†Œ์˜ ์™ธ๋ถ€ ๋ฐ”์ธ๋”ฉ์„ ๋ฐ˜๋“œ์‹œ ๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ ๋‚ด๋ถ€ ์š”์†Œ์— "์ƒ์†"ํ•˜๋Š” ๋” ์‰ฌ์šด ๋ฐฉ๋ฒ•์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ๊ณผ ๋ Œ๋” ๊ธฐ๋Šฅ ๊ฐ„์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค.

ia kie like vue, ๊ฐ„๋‹จํ•œ ๋„๊ตฌ

v2.4์—์„œ ์ด๊ฒƒ์— ๋Œ€ํ•œ PR์€ ํ›Œ๋ฅญํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค! ๐Ÿ‘

๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ

์ด๋“ค์„ ๊ฒฐํ•ฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<div>
  <input v-bind="$attrs" v-on="$listeners">
</div>

์ข‹์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” v-model๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” v-model์€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ž˜ํ•‘ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ž…๋ ฅ์œผ๋กœ v-model์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์˜ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
๋‚ด๊ฐ€ ์ฐพ์€ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ• :
https://jsfiddle.net/60xdxh0h/2/

ํ…œํ”Œ๋ฆฟ๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” ๊ธฐ๋Šฅ์  ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๊ฐ„๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” v-model๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” v-model์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์™œ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ• ๊นŒ์š”? v-model์€ prop ๋ฐ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์— ๋Œ€ํ•œ ๊ตฌ๋ฌธ ์„คํƒ•์ด๋ฉฐ ๋‘˜ ๋‹ค $attr/$props์— ์žˆ์œผ๋ฏ€๋กœ ์‰ฝ๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž์‹ ์˜ต์…˜์— ๋Œ€ํ•œ ์ง€์‹์ด ํ•„์š”ํ•œ ์œ ์ผํ•œ ๊ฒƒ์€ ์ž์‹์ด model ๊ธฐ๋ณธ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ๋ฟ์ž…๋‹ˆ๋‹ค. ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  ๋ฌธ๋ฒ•์ ์ธ ์„คํƒ•์ด์ง€๋งŒ ์ฝ๊ธฐ์— ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋“ค์„ ๊ฒฐํ•ฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ https://github.com/almino/semantic-ui-vue2/blob/master/src/elements/Input.vue ์˜ˆ์ œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•  ๋•Œ ๋™์ผํ•œ ์ œ์–ด๋ฅผ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (์˜ˆ: v-on:input="emitInput($event.target.value)" ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค)

์–ด์จŒ๋“  ์ด PR์€ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜๊ณ ํ•˜์…จ์Šต๋‹ˆ๋‹ค!

@AlexandreBonaventure v-model ๊ฐ€ ์š”์†Œ์—์„œ์™€ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. DOM ์ด๋ฒคํŠธ๋Š” ์ฝœ๋ฐฑ์— ์ด๋ฒคํŠธ ๊ฐœ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ˜๋ฉด ๊ตฌ์„ฑ ์š”์†Œ ์ด๋ฒคํŠธ๋Š” ๊ฐ’์„ ์ง์ ‘ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” v-model _does_ ์ž‘๋™ํ•˜์ง€๋งŒ ๋ฐ”์ธ๋”ฉ๋œ ๊ฐ’์€ DOM์˜ ์ด๋ฒคํŠธ ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค. ๐Ÿ˜•

v-model ๊ฐ€ ์—ฌ๊ธฐ์—์„œ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•  ๊ฒƒ์ด๋ผ๋Š” ๋ง์”€์ด ์˜ณ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ํ•ด๊ฒฐํ•˜๊ธฐ์— ๊ฐ€์žฅ ์ข‹์€ ๊ณณ์ด ์–ด๋””์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ์•„์ด๋””์–ด:

์—ด๊ฑฐํ•  ์ˆ˜ ์—†๋Š” ์†์„ฑ์„ $listeners ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: __$listeners__: true , v-on ๊ฐ€ v-on="$listeners" ์‚ฌ์šฉ์„ ๊ฐ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ $listeners ๊ฐ์ฒด๊ฐ€ v-on ์ „๋‹ฌ๋˜๊ณ  ๊ฐ ๋ฆฌ์Šค๋„ˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ž˜ํ•‘๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function (event) {
  listener(event.target.value)
}

ํ•œ ๊ฐ€์ง€ ๋‹จ์ ์€ ์ด์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„๋ฆฌ๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ keyCode ์— ์•ก์„ธ์Šคํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์šด์ด ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ v-on ์˜ ๊ฐœ์ฒด ๊ตฌ๋ฌธ์— ์ˆ˜์ •์ž๊ฐ€ ์ง€์›๋˜๋Š” ๊ฒฝ์šฐ .native ์ž๋™ ๋ž˜ํ•‘ ๋™์ž‘์„ ๋น„ํ™œ์„ฑํ™”ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@yyx990803 @LinusBorg ํƒ€๋‹น์„ฑ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”? ๋‚ด๊ฐ€ ๋†“์น˜๊ณ  ์žˆ๋Š” ์—ฃ์ง€ ์ผ€์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ค, ๋‹น์‹ ์€ rral์˜ v-model์„ ์–ธ๊ธ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์–‘์‹ ์š”์†Œ, ๋‚˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด PR์ด ์žˆ๋“  ์—†๋“  ์–ด์จŒ๋“  ์†Œํ’ˆ์— ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ณ ๊ธ‰ ์•ฑ์—์„œ๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋‹ค์†Œ ๋“œ๋ญ…๋‹ˆ๋‹ค(๋‹ฌ์„ฑ ๊ฐ€๋Šฅํ•˜๊ธด ํ•˜์ง€๋งŒ).

@LinusBorg ์šฐ๋ฆฌ๊ฐ€ ๊ฐ™์€ ํŽ˜์ด์ง€์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ํ…œํ”Œ๋ฆฟ์ด ํฌํ•จ๋œ CustomInput ๊ตฌ์„ฑ์š”์†Œ:

<div>
  <input v-bind="$attrs" v-on="$listeners">
<div>

์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ์ž‘๋™ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

<CustomInput v-model="myValue" />

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ž‘๋™ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ–ˆ์ง€๋งŒ, ์•Œ๋ ‰์‚ฐ๋“œ๋ฅด๋ฅผ ์ดํ•ดํ•œ ๋ฐฉ์‹์€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์•„๋‹Œ ์š”์†Œ์˜ v-๋ชจ๋ธ์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฒฐ๊ตญ ๋ณ€๊ฒฝ ๋กœ์ปฌ ์ƒํƒœ์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@chrisvfritz ๊ฐ€ ๊ทธ์˜ ํ›„๊ธฐ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์„ค๋ช…ํ•œ ๋‚ด์šฉ์„ ๋งํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. (๋‚ด ๋ชจ๊ตญ์–ด๊ฐ€ ์•„๋‹Œ ์˜์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค :))

@LinusBorg ์ตœ์‹  ๋ฆด๋ฆฌ์Šค์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ์˜ ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ์•ˆํ‹ฐ ํŒจํ„ด์œผ๋กœ ๊ฐ„์ฃผ๋˜๊ณ  ์ƒํƒœ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

value ์†์„ฑ์ด ๋ฌธ์ž์—ด์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์œ„์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐ€์ ธ์˜จ ์—ด๊ฑฐํ˜•์„ ์„ ํƒ ์˜ต์…˜์˜ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์ฝค๋ณด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<template>
    <select class="combo" v-model="value" v-on="$listeners"> 
      <option v-for="(item, key) in items" :value="item">{{key}}</option>
    </select>
</template>

<script>
export default {
    props: {
        items: {
            type: Object,
            required: true
        },

        value: {}
    }
}
</script>

๋‹ค์Œ์€ ์ƒ์œ„ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ชฉ๋ก ์ค‘ ํ•˜๋‚˜์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

            execList: {
                "None": ACT_EXEC_TYPES.NONE,
                "Function": ACT_EXEC_TYPES.FUNCTION,
                "Code": ACT_EXEC_TYPES.CODE
            }

์ฝค๋ณด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•:

<combo :items="execList" v-model="selectedAction.execType"/>

๋‚˜๋Š” ์ง€๊ธˆ 2 ์ผ ๋™์•ˆ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๊ณ ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ์ •๋ง ์ขŒ์ ˆํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” $event.target.value ๊ฐ€ ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด๊ณ  :value ์žˆ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ‰๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@LinusBorg @AlexandreBonaventure @RobertBColton ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ–ฅํ›„ ํ† ๋ก ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ๊ธˆ

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰