Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

옛날 웹 개발자가 잠깐 맛본 Vue.js 소개

6,091 views

Published on

Vue.js를 선택한 이유와 간단한 SPA을 만들면서 사용한 Vue.js의 기본적인 특징을 소개한다.

Published in: Technology
  • Login to see the comments

옛날 웹 개발자가 잠깐 맛본 Vue.js 소개

  1. 1. 옛날 웹 개발자가 잠깐 @ 본 Vue.js 소개 최범균, 2,d90r8s@2,d90r8s.n.t, @OKKY 20180419 자료: /tt4s: :::.s10d.s/,r..n.t 2,d90r8s
  2. 2. 나 = 옛J 웹 (서S) 개R자 • 요즘 h론트 모름 • b신 언어 • ).6 ~ • TEpe.cript • g키a, 모L, T더 M • npm, Earn, De2pack, parcel, 2a2el, ReqCireJ., A,(, .. • C.. • .aAA, +eAA, … • b신 h레임워c • React, AngClar 2 , VCe.jA • eV트 • ,=ca6, JaAmine, … 2
  3. 3. C = M날 웹 (서버) 개발P • 아는 A • S론트 • 3q=ery • 약간의 Ang=lar 1 B험 • C++ 초J Bootstrap • 서버 • +pring ),C • (+P, t1ymeleaf 3
  4. 4. 주어진 업무 • 폰에서 사용할 간단한 업무용 웹 4
  5. 5. 주어진 업무 • 폰에서 사용할 간단한 업무용 웹 5
  6. 6. 요건 • 빨리(2주 안P) • 일단 빨리 A들어 시범 운영 시작 • 동적인 요소 • 조건P 따라 보이고 안 보이6 구성 요소 • 폼 등록후 목록P 결2 반영 • SPA(S)n(le Pa(e A,,) • 개발자 S심 고객 요구6 아님 • 나름 요즘 기술 • 개발자 S심 고객 요구6 아님 6
  7. 7. Reac. vs Angula, vs Vue.js 주안점: 구식 개발:, 학7 속도, 복잡도
  8. 8. 결정에 영향을 준 h 가지 자d • 개j자 조o • httEH://Htat:of?H.8oB/201(/front-:nd/r:HuAtH/ • 3u:.?H가 ,nguAar 재낌 • 앞으c k우겠다는 개j자 n율도 높음 • 다e 프b임워크와의 n교 • httEH://kr.Ku:?H.org/K2/guid:/8oBEariHon.htBA • ,nguAar 2에p 3u:.?Hc 넘yN 이유 (2:a8tf q택하지 v은 이유) • httE://7it.Ay/2/B133a (원i) httE://7it.Ay/2.ygZAf (l역) • 학t Rq 공u ip V현 r도 단s함 • 과연 3u:.?H가 앵귤aZ g엑트m다 좋을X? • httE://7it.Ay/2uXq:fu (원i) httE://7it.Ay/2K0-X0: (l역) )
  9. 9. 몇 가지 Vue..s jb • 템플릿 이용 선V적 렌더링 • 모델 뷰 양방향 바인딩(2 2(y )-nd-ng) 지원 • d포넌i • 라우g(SPA) • 이벤i버S • 단일 파일 d포넌i • 글A벌 Pe 관리 • 점a적으A 기9 채택 가9 • P대적으A 빠른 n습 • 한글 문서 9
  10. 10. 간단 샘[ '0 ;ttpD://=D:<dd>e.net/madv<CuD/y');vC;=/ ,d<v <d="app". ,;(.T델,/;(. 이름: ,<nput type="text" v-model="name" /. 암호: ,<nput type="paDDwACd" v-model="password" /. ,;(.바인딩,/;(. 이름: ,<nput type="text" v-bind:value="name" /. 암호: ,<nput type="paDDwACd" :value="password" /. ,;(.값,/;(. ,u>. ,><.이름 : {{ name }},/><. ,><.암호 : {{ password }},/><. ,/u>. ,<nput type="buttAn" v-on:click="init()" va>ue="초기]" /. ,/d<v. ,DcC<pt type="text/=avaDcC<pt" DCc=";ttpD://.../vue.=D".,/DcC<pt. ,DcC<pt type="text/=avaDcC<pt".//,!301/T/3 vaC app = new Vue!{ el: #app , data: { name: "", password: "" }, methods: { init: :unct<An!" { t;<D.name = "<n<t"; t;<D.paDDwACd = ""; } } }" //44. ,/DcC<pt.
  11. 11. +, 기본 구성: 모델 + 뷰 + 뷰모델 뷰 템플릿 뷰모델뷰 데이터, 모델
  12. 12. 앱의 2본 1성 요소: data, comp,ted • data • 모델, :인딩 대상 • 양방향 :인딩 • 모델의 변경을 뷰에 반영 • --model로 뷰 폼의 변경을 모델에 반영 • comp,ted • 계산 속성 • 연관된 data 속성이 변경하면 comp,ted 속성 변경 2
  13. 13. ]제 +, v:r :pp 3 n>w 6u>#{ >l0 " :pp"& data0 { name0 ""& birthyear0 LhisY>:r ' +.& parentCheck0 f:ls> }& computed0 { years0 fun<Lion#) { v:r r>L 3 []1 for#v:r v 3 LhisY>:r ' ,0 1 v <3 LhisY>:r 1 v++) r>L(push#v)1 r>Lurn r>L1 }& isUnderage0 fun<Lion#) { r>Lurn LhisY>:r ' this.birthyear < +-1 } }& m>Lho=s0 { r>g0 fun<Lion#) { if #this.isUnderage !! !this.parentCheck) … } } }) hLLps0))jsfi==l>(n>L)m:=virus)ujor5=yx) hLLps0))jsfi==l>(n>L)m:=virus)w+:,/mLm) 0 <ompuL>= g>L)s>L ] <=iv i=3":pp"4 <form4 <=iv4 <l:;>l for3"n:m>"4이Y<)l:;>l4 <inpuL Lyp>3"L>xL" i=3"n:m>" v-model="name" )4 <)=iv4 <=iv4 <l:;>l for3";irLhy>:r"4[년<)l:;>l4 <s>l><L i=3";irLhy>:r" v-model="birthyear"4 <opLion v'for3"y>:r in years" 0v:lu>3"y>:r"4 {{ y>:r }}년 <)opLion4 <)s>l><L4 <)=iv4 <=iv v-if="isUnderage"4 <inpuL Lyp>3"<h><k;ox" i=3"p<hk" v-model="parentCheck" )4 <l:;>l for3"p<hk"4미성년 V의<)l:;>l4 <)=iv4 <)form4 <inpuL Lyp>3";uLLon" v'on0<li<k3"r>g#)" v:lu>3"등록" )4 <)=iv4
  14. 14. 뷰 템플릿 • 콧bi(1ust(ch, 표현d : {{ d }} • 뷰 모델o a성n 해당 l{에 삽s • 디렉티브 : 태그에 u용 • v-t,;t : 특b 문t 처리(예, < à &lt& • v-ht1l : 특b 문t 미처리 • v-)ind : 태그 a성에 모델 단방향 바인딩 • v-1od,l : 모델과 f방향 바인딩 • v-sho: : 보hwy h부(dis4l(< c}r a성 사용 • v-i-, v-,ls,, v-,ls,-i- : v건에 따라 보hx(v건에 e 맞m면 렌더링 e함 • v--or : 반복 • v-on : p벤트 • … 14
  15. 15. 뷰 템플릿 예 "5 <d/v> <1abe1 -or="name">이름<!1abe1> </n5ut t<5e="text" /d="name" v-model="name" !> <!d/v> <d/v> <1abe1 -or="b/rth<ear">생=<!1abe1> <se1ect /d="b/rth<ear" v-model="birthyear"> <o5t/on v-for="year in years" v-bind:value="year"> {{ year }}= <!o5t/on> <!se1ect> <!d/v> <d/v v-if="isUnderage"> <! v-if="new Date().getFullYear() - birthyear < 14" > </n5ut t<5e="checkbox" /d="5arentCheck" v-model="parentCheck" !> <1abe1 -or="5arentCheck">{{ birthyear }}=생은 C성= >의 필요<!1abe1> <!d/v> </n5ut t<5e="button" v-on:click="reg()" va1ue="등록" !>
  16. 16. 자바 스aN트 식 S용 가능 • 콧수Y, 디렉d브 식에서 자바 스aN트 S용 가능 • 남발하지 O 것 '( EE =u<b6r " ' }} EE >: - 'Y.1' ) '/O' }} à eb가 나을 수 있음 EE <6ssag6.s?lit '').r6v6rs6 ).j>i= '') }} à eb가 나을 수 있음 <div v-bi=d)id+"'list-' " id",</div,
  17. 17. 앱c 기본 구Y a소: met;A7s • 앱c 기능 e공 • f수염 hi식, 디렉gV에서 사b 가능 (7 vaC app . new Vue"{ e>: ! app!, 7ata: { name: "", 5<Ct;yeaC: t;<sYeaC - (), paCent1;ec=: fa>se, s;AwA:e: tCue }, methods: { reg: funct<An"# {…}, agem: funct<An"# { CetuCn t;<sYeaC - t;<s.5<Ct;yeaC, }, showToggle: funct<An"# { t;<s.s;AwA:e . !t;<s.s;AwA:e } } }# -7<v v-<f."s;AwA:e" v-on:click="showToggle"/ {{ agem() }} -'7<v/ -7<v v-<f."!s;AwA:e" v-on:click="showToggle"/ 나dh시 -'7<v/
  18. 18. 이벤트 처리 • 다양한 구성 요소에서 이벤트 처리 가능 • v-on 디렉티브 • 예: v-on:cl.ck, v-on:key8p, v-on:68b1.t, v-on:c-an,e … • 수식어 • 이벤트 • 6top, p5event, capt85e, once, … • key8p 이벤트용 • 키코드: 키코드 • 별칭: ente5, tab, e6c, delete, 6pace, 8p, do:n, left, 5.,-t, ct5l, alt, 6-.ft, 1eta • 조합: ct5l65 18
  19. 19. 이벤트 예 '9 .=Bv B=/":pp"> .: hI>f/"#" v-on:click.prevent="help">도움Y./:> .foIE> .=Bv> .D:;>D foI/"F:E>">이름./D:;>D> .BFput typ>/"t>xt" B=/"F:E>" v-Eo=>D/"F:E>" v-on:keyup.enter="goTo('birthyear')" /> ./=Bv> .=Bv> .D:;>D foI/";BIthy>:I">생T./D:;>D> .BFput typ>/"t>xt" B=/";BIthy>:I" v-Eo=>D/";BIthy>:I" v-on:keyup.enter="goNext" =:t:-F>xt/"I>g"/> ./=Bv> ./foIE> .BFput B=/"I>g" typ>/";uttoF" v-on:click="reg" v:Du>/"V록" /> ./=Bv> v:I thBs9>:I / F>N D:t>(".g>t4uDD9>:I("- v:I :pp / F>N 8u>({ >D, #:pp # =:t:, { … }# E>tho=s, { h>Dp, fuF<tBoF(" { … }# goTo, fuF<tBoF(id" { =o<uE>Ft.g>tED>E>Ft1yI=(B=".fo<us("- }# go6>xt, fuF<tBoF(event" { v:I F>xtI= / >v>Ft.t:Ig>t.=:t:s>t.F>xt- v:I >D> / =o<uE>Ft.g>tED>E>Ft1yI=(F>xtI="- Bf (>D>" >D>.fo<us("- }# I>g, fuF<tBoF(" { :D>It("V록""- } } }" https,//jsfB==D>.F>t/E:=vBIus/;f<)(ph8/
  20. 20. 20 htt.0://v2ej0.o/g/v2/g2ide/in0tance.html 인스:스 라이프사이클
  21. 21. 컴포+트 • UI 구성 요소 • 템플릿 + 앱 • 조립 • 부모 자식 관계 • 부모 à 자식: 속성 • 자식 à 부모: 이2트 • 일부 공통 UI 구성 요소 재사용 • :: 1튼, 그-I, 모,창 21
  22. 22. 컴포넌트 예 22 (>empl/>e i2)"user-info-template"> (2iv cl/==)"c/<2"> (2iv cl/==)"c/<2-b:2y"> (2iv> (=p/n cl/==)"b/2ge b/2ge-p<im/<y">주H(/=p/n> (=p/n>{{ info./22<e== }}(/=p/n> (/2iv> (2iv> (=p/n cl/==)"b/2ge b/2ge-p<im/<y">H,(/=p/n> (=p/n>{{ info.hp }}(/=p/n> (/2iv> (2iv> (=p/n cl/==)"b/2ge b/2ge-p<im/<y">계약(/=p/n> (=p/n>{{ info.c:n></c> }}(/=p/n> (/2iv> (2iv> (=p/n cl/==)"b/2ge b/2ge-p<im/<y">미납(/=p/n> (=p/n>{{ info.unp/y }}(/=p/n> (/2iv> (/2iv> (/2iv> (/>empl/>e> Vue.component 'user-info'" { template' '#user-info-template'" props' -'info'. })
  23. 23. 컴포넌트 사N '( <d;v ;d,"3pp" c<3ss,"co>t3;>er"- <user-info v-bind:info="infoData"></user-info> <3ct;v;ty-<;st v-b;>d)3ct;v;t;es,"3ct;v;t;es"-</3ct;v;ty-<;st- <3ct;v;ty-for= v-o>)3dded,"3dd/ew"-</3ct;v;ty-for=- </d;v- v3r 3pp , >ew VDe({ e<) "#3pp"# d3t3) { infoData) {}# activities) [2 }# cre3ted) fD>ct;o>(" { t:;s.<o3d("; }# =et:ods) { <o3d) fD>ct;o>(" { 3x;os.get(/so=ed3t3/" .t:e>((respo>se" ,- { t:;s.;>fo.3t3 , respo>se.d3t3.;>fo; t:;s.3ct;v;t;es , respo>se.d3t3.3ct;v;t;es; }".c3tc:((error" ,- { co>so<e.<og(error"; }"; }# … } }"; VDe.co=po>e>t( user-info # { te=p<3te) #Dser-;>fo-te=p<3te # props) [ info 2 }"
  24. 24. 컴V넌트 이벤트 발생 () 4ue.7ompoAeAt( a7t=v=ty-:oDm # { template, #a7t=v=ty-:oDm-template # data, :uA7t=oA(" { DetuDA { type, ""# Desult, ""# N }- }# met<ods, { De;, :uA7t=oA(" { vaD Aew17t / { "date", :oDmat2ate(Aew 2ate(""# "Desult", t<=s.Desult# "type", t<=s.type}- this.$emit("added", newAct)- } } }" .d=v =d/"app" 7lass/"7oAta=AeD"> .d=v v-s<ow/"loaded"> .useD-=A:o v-6=Ad,=A:o/"=A:o">./useD-=A:o> .a7t=v=ty-l=st ,a7t=v=t=es/"a7t=v=t=es">./a7t=v=ty-l=st> .a7t=v=ty-:oDm v-on:added="addNew">./a7t=v=ty-:oDm> ./d=v> ./d=v> vaD app / Aew 4ue({ el, "#app"# ... met<ods, { addNew, :uA7t=oA(Aew17t" { t<=s.a7t=v=t=es.pus<(Aew17t"- }# ... } }"- <ttps,//>s:=ddle.Aet/madv=Dus/(D;'zs76/
  25. 25. 컴포넌트 분리 • 동적 요소가 많5수록 영25 구분해서 컴포넌트로 분리 25 무지 긴 자바스크립트 무지 긴 템플릿 격한 휠 소리
  26. 26. vu,-2out,2를 이용한 )PA • )PA()in- P+-, App) • U(I( 쿼리문자A 등)에 컴포6트 매핑 • 히스I리 모드, 해시 모드 지원 26
  27. 27. vu7-rout7r 간단 예제 ') -d:v :d."3pp" c<3ss."co>t3:>7r"/ -d:v/ <router-link to="/contracts">목록</router-link> <router-link to="/help">도움말</router-link> -/d:v/ <router-view></router-view> -/d:v/ -t7=p<3t7 :d."co>tr3cts-t7=p<3t7"/ -d:v/ -h(/목록-/h(/ … -/d:v/ -/t7=p<3t7/ -t7=p<3t7 :d."h7<p-t7=p<3t7"/ -d:v/ -h(/도움말-/h(/ -/d:v/ -/t7=p<3t7/ v3r contractsComp . { t7=p<3t7: #co>tr3cts-t7=p<3t7# d3t3: 8u>ct:o>(" { r7tur> { co>tr3cts: [2 }, }# cr73t7d: 8u>ct:o>(" { … } }, v3r helpComp . { t7=p<3t7: #h7<p-t7=p<3t7 }, v3r rout7r . new VueRouter({ routes: [ { path: "/contracts", name: "contracts", component: contractsComp }, { path: "/help", name: "help", component: helpComp } ] }), v3r v= . >7w Vu7({ 7<: "#3pp"# router: router }", https://;s8:dd<7.>7t/=3dv:rus/hp8(r;db/
  28. 28. 동V 라우팅 사용 (8 ;ttCs://=s:<88le.net/ma8v<rus/xno=a'uC/ -temClate <8."contracts-temClate"/ -8<v/ -;)/R록-/;)/ -table class."table"/ … -tbo8y/ -tr v-:or."cont <n contracts"/ -t8/ -router-l<n> :to."'/contracts/' + cont.num"/ {{ cont.num }} -/router-l<n>/ -/t8/ -t8/{{ cont.a88ress }}-/t8/ -t8/{{ cont.name }}-/t8/ -/tr/ -/tbo8y/ -/table/ -/8<v/ -/temClate/ var router . new 2ueRouter({ routes: 3 … { path: "/contracts/:num", name: "8eta<l"# comConent: 8eta<l0omC }# … ] }", var vm . new 2ue({ el: "#aCC"# router: router }", var 8eta<l0omC . { temClate: #8eta<l-temClate# 8ata: :unct<on(" { return { <n:o: {} }, }# create8: :unct<on(" { var num . this.$route.params.num, t;<s.loa8(num", }# met;o8s: { loa8: :unct<on(num" { ... } } },
  29. 29. 경로 변수 변경 감지 21 v:r <=t:il7omp 5 { t=mpl:t=2 '#<=t:il-t=mpl:t='$ <:t:2 >un;tion"# { r=turn { in>o2 {} }3 }$ ;r=:t=<2 >un;tion"# { v:r num 5 this. rout=.p:r:ms.num3 this.lo:<"num#3 }$ beforeRouteUpdate2 >un;tion"to$ >rom$ n=xt# { this.lo:<"to.params.num#3 n=xt"#3 }$ 4t=mpl:t= i<5"<=t:il-t=mpl:t="6 4<iv6 4h36상세2 4strong6{{ in>o.num }}4'strong6 4'h36 4<iv6 {{ in>o.:<<r=ss }} 4'<iv6 4<iv6 4rout=r-linC to5"/contracts/13579"6 8이[ )3-/19 4'rout=r-linC6 4rout=r-linC to5"/contracts/24680"6 8다음 2,.0(9 4'rout=r-linC6 4'<iv6 4'<iv6 4't=mpl:t=6 https2''js>i<<l=.n=t'm:<virus'xnoj:(up'
  30. 30. l]s [d • 글로벌 l]s 발생# cf • 부모/ne 관계가 g닌 m의 구a h소L rf • o당u 사it면 pj# 격t게 사it면 코V가 꼬m (' https://;s7:ddle.net/=3dv:ADs/v/D/'7)v/ v3A eventBus , new 0De("; 0De.co=ponent(3ct:v:ty-7oA=# { te=pl3te: #3ct:v:ty-7oA=-te=pl3te# d3t3: 7Dnct:on(" { AetDAn { type: ""# AesDlt: ""# …}; }# =ethods: { Aeg: 7Dnct:on(" { v3A new-ct , { "d3te": 7oA=3t.3te(new .3te(""# "AesDlt": th:s.AesDlt# "type": th:s.type }; eventBus.$emit( 'activityAdded', newAct); } } }"; 0De.co=ponent(3ct:v:ty-l:st# { te=pl3te: #3ct:v:ty-l:st-te=pl3te# d3t3: 7Dnct:on(" { AetDAn { 3ct:v:t:es: [] }; }# cAe3ted: 7Dnct:on(" { eventBus.$on( 'activityAdded', this.activityAdded); th:s.lo3d("; }# =ethods: { 3ct:v:ty-dded: 7Dnct:on(new-ct" { … }# lo3d: 7Dnct:on(" { ... } } }";
  31. 31. fc2 값 e맷d a리 +) Vue.filter( Ls>rno , fLn<tion(v:lL>" { '' 글로벌 fc r>tLrn v:lL>.sL;string((, -" # "-" # v:lL>.sL;string(-"3 }" v:r :pp 5 n>w 9L>({ >l2 #:pp , =:t:2 { no2 ")2+,-./01(", n:m>2 "이상은", <o=>2 "7" }, filt>rs2 { '' 로b fc gr:=>2 fLn<tion(v:lL>" { if (v:lL> 55 7 " r>tLrn 정h원 3 r>tLrn 준h원 3 } } }"3 4=iv i=5":pp"6 4A+6h원4'A+6 번g2 {{ no | userno }} 4;r'6 이V2 {{ n:m> }}4;r'6 등급2 {{ <o=> | grade }} 4'=iv6 Attps2''jsfi==l>.n>t'm:=virLs'o8:w:n:+'
  32. 32. 사c한 lh 사r • ]e 데io 변X • mn 데io j근'pd 32 SAO ANN 1 Lew =ue"V eJ. ! ANN!, CAtA. V NeOsoL. V LAme. !i[! }, Bities. [ VLAme. !서g!, BoCe. !;E:!}, VLAme. !부a!, BoCe. !4<;3N!}, VLAme. !제l!, BoCe. !JEJ<!} ] }, methoCs. V uNCAte). EuLBtioL"# V '' 반f > this.cities[0] = VLAme. !서g(!, BoCe. !;E:<L(!}/ }, uNCAte2. EuLBtioL"# V '' 반f : this.cities[0].code = !;E:<L!!/ }, uNCAte3. EuLBtioL"# V '' 반f : Vue.set"this.Bities, (, VLAme. !서g!, BoCe. !;E:<L!}#/ } } }# 0h32VV NeOsoL.LAme }} 0'h32 VV NeOsoL.address.code1 }} 0!-- 5ALLot OeAC NOoNeOtU !BoCe)! oE uLCeEiLeC --2 0uJ2 0Ji S-EoO1"B iL Bities"2VVB.LAme}}-VVB.BoCe}} 0'Ji2 0'uJ2 httNs.''jsEiCCJe.Let'mACSiOus'g-LNLN3,'
  33. 33. Lz 특s • wat/h : c성 변H vn • 트랜ra : dP메ja 효J • https://jsfiddl1:1t//hrisAfritz/sLrhk".// • 단k 파k w포넌트 : 템플릿 + J+ + C++ • w포넌트 단h 관리 • Au1C : og "상태 + L능 + 변H" • w포넌트 간 데j터/j벤트 주고 받는 xT p거로 복mS 감b • lu HTTP 클라je트 fi • ACios vt: https://3ithu./om/aCios/aCios 33
  34. 34. 좋았던 점 • 4대적으로 낮은 학습 시간 • 단순한 구성 요소 • 기존 자바스크립트 지식만으로 충분 • 간단하게 시작할 수 있음 • 최신 3드 도구가 없어도 됨 • 컴포넌트 단위 관리 34
  35. 35. 35 끝

×