ãã®èšäºã§ã¯ãçŽ æŽãããããã³ããšã³ããã¬ãŒã ã¯ãŒã¯Vue.jsã«ã€ããŠèª¬æããŸãã ã芧ã®ãšããããã®èšäºã¯ãVue.js for DoubtersããšåŒã°ããŸããå®éã«Vue.jsãè©ŠããŠã¿ãããšãã§ããªãã£ãå Žåã¯ãèªãã§ããå€æããŠãã ããã
ãã¬ãŒã ã¯ãŒã¯ã¯ãç§ãã¡ã®ç掻ãç°¡çŽ åããåãã¿ã€ãã®ã³ãŒããæžãããšãã解æŸãããããã«èšèšãããŠããŸãã ããããäžéšã®ãã¬ãŒã ã¯ãŒã¯ã®ã³ãŒãããŒã¹ãæ¡å€§ããã«ã€ããŠããããžã§ã¯ãã«è€éãã®ã·ã§ã¢ãè¿œå ãå§ããŸãã ãã®ãããéçºãèšç»ãããšãã¯ã次ã®2ã€ã®èŠçŽ ãèæ
®ããå¿
èŠããããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®è€éã
- 䜿çšãããã¬ãŒã ã¯ãŒã¯ã®è€éã
å°ãæœè±¡åããå
éšã®è€éãïŒã€ãŸããéçºäžã«åãé€ãããšãã§ããªãè€éãïŒãšç¹å®ã®ç®æšãéæããããã®ããŒã«ã®è€éããåŒã³ãŸãã åœç¶ãæäœã§ããã®ã¯æ¥œåšã®è€éãã ãã§ãã
äžèšãããããŒã«ãéžæããããã®2ã€ã®ãªãã·ã§ã³ããããŸãã
- 倱æãªãã·ã§ã³ ã ããŒã«ãå
éšã®è€éããã«ããŒããã®ã«ååã§ãªãå Žåã ã¢ããªã±ãŒã·ã§ã³ã®å®è£
ã«å¿
èŠãªæ©èœã¯ãã¬ãŒã ã¯ãŒã¯ã§ã¯å©çšã§ããªããããå¿
èŠãªããŒã«ãæåã§å€æŽããŠè¿œå ããå¿
èŠããããŸãã
- ãªãã·ã§ã³ã®åé·æ§ ã ã¢ããªã±ãŒã·ã§ã³ã«å¿
èŠãªæ©èœãããŒã«ã®ããäžéšã§ãããã¯ãããŠããå Žåã ããŒã«ãããã®æ®ãã®éšåã¯éè·ã§ãããéçºäžã®å¶éãã¢ããªã±ãŒã·ã§ã³ã®èªã¿èŸŒã¿é床ã®äœäžãªã©ãåé¡ãåŒãèµ·ããã ãã§ãã
ããã§ã¯ã©ãããŸããïŒ ããããç§ã¯å°ããã£ããã³ãšããã³ã¹ã«ãªããŸããããç®æšããšã«-ç¬èªã®ããŒã«ããšããååã«åºã¥ããŠè¡åããªããã°ãªããŸããã èšç»ããéã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®è€éãïŒããã³æ©èœïŒãåãã¬ãã«ã«ãªãããã«ã劥åç¹ãæ¢ãå¿
èŠããããŸãã
Vue.jsãšèè
ã«ã€ããŠ
ããã§ã¯ãVueãšãããã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã®éçºã容æã«ããæ¹æ³ãç解ããŸãããã
Vue.jsã®äœæè
ã¯ãGoogleããã³Meteor Dev Groupã®å
åŸæ¥å¡ã§ããEvan Youã§ãã 圌ã¯2013幎ã«ãã¬ãŒã ã¯ãŒã¯ã®éçºãéå§ãã2014幎2æã«æåã®å
¬éãªãªãŒã¹ãè¡ãããŸããã Vueã¯ãããšãã°AlibabaãBaiduãXiaomiãSina Weiboãªã©ã®äžåœäŒæ¥ã§åºã䜿çšãããŠãããLaravelãšPageKitã®ã³ã¢ã®äžéšã§ãã æè¿ãç¡æã®GitLabãªããžããªç®¡çã·ã¹ãã ãVue.jsã«ç§»è¡ããŸããã
2016幎9ææ«ã«Vue.js 2.0ããªãªãŒã¹ãããããã«ã¯ãŒã«ã§ããã©ãŒãã³ã¹ã«éç¹ã眮ãããŸãããçŸåšã¯ä»®æ³DOMã䜿çšãããµãŒããŒã¬ã³ããªã³ã°ãJSXã䜿çšããæ©èœãªã©ããµããŒãããŠããŸãã çŸåšã¯ã³ãã¥ããã£ã«ãã£ãŠã®ã¿ãµããŒããããŠããŸãããGoogleãFacebookïŒAngular2ããã³React 15ïŒãªã©ã®å·šäººã®è£œåã¬ãã«ã§ããã®äŸ¡å€ãç¶æããåŸã
ã«äººæ°ã«è¿œãã€ããŠããŸãã
æãåçŽãªäŸãèããŠã¿ãŸãããã
app.jsvar demo = new Vue({ el: '#demo', data: { message: 'Hello, Singree!' } })
- æ°ãããã¥ãŒã¯æ°ããVueãä»ããŠäœæãããŸã
- ãšã«ã§ã¯ãã©ã®èŠçŽ ãç£èŠãããŠãããã決å®ããŸã
- ããŒã¿ã«ã¯ç¶æ
ãªããžã§ã¯ãããããŸã
app.html <div id="demo"> <p>{{message ? message : "no content"}}</p> <input v-model="message"> </div>
- htmlã§ã¯ããã¡ãããå¿
èŠãªã»ã¬ã¯ã¿ãæã€èŠçŽ ãå¿
èŠã§ã
- å·ããã®ããŒã¿ã¯å£ã²ããçãããïŒçµå±å£ã²ãïŒæ§æã§è¡šç€ºãããŸãã ããã«éåžžã®äžé
åŒããããŸã
- v-modelãã£ã¬ã¯ãã£ãã䜿çšããŠãå
¥åãç¶æ
ãªããžã§ã¯ãã®ã¡ãã»ãŒãžå€ã«é¢é£ä»ããŸã
//codepen.io/Demetrius/embed/KNaJLW/?height=468&theme-id=16150&default-tab=result
Vue.jsã®æŠå¿µ
Vueã®äž»ãªæŠå¿µã¯æ¬¡ã®ãšããã§ãã
- ã³ã³ã¹ãã©ã¯ã¿ãŒ
- ã³ã³ããŒãã³ã
- æ什
- é·ç§»
æåã®ããŒãžã§ã³ã«ã¯ãŸã ãã£ã«ã¿ãŒããããŸããããç§ãç¥ãéããçŸåšã®ããŒãžã§ã³ã§ã¯éæšå¥šãšèŠãªãããŠããŸãã
ã³ã³ã¹ãã©ã¯ã¿ãŒ
app.js new Vue({ el: '<jQueryStyleSelector>', template: '<id || inline template>', data: { props: ' ', first_name: "", last_name: "" }, computed: { full_name: function(){ return this.first_name + this.last_name; // } }, methods: { // beforeCreate: function(){}, created: function(){}, beforeMount: function(){}, mounted: function(){}, beforeUpdate: function(){}, updated: function(){}, beforeDestroy: function(){}, destroyed: function(){}, customMethodsAlso: function(){ // data } } })
Vue.jsã®æäœã¯ãæ°ããVueã®æ°ããã€ã³ã¹ã¿ã³ã¹ãäœæããããšããå§ãŸããŸãã elã«ã¯ãVueããã©ããŒããŠããèŠçŽ ããããŸãã ãã³ãã¬ãŒãã§ã¯ãVueãã¬ã³ããªã³ã°ãããèŠçŽ ãéžæïŒãŸãã¯ã€ã³ã©ã€ã³ã§ç»é²ïŒãããŸãã ã€ã³ã¹ã¿ã³ã¹ã®çŸåšã®ç¶æ
ã¯ããŒã¿ã«ä¿åãããèšç®ã¡ãœããã¯èšç®ããããã£ãæäŸããŸãã
ãã®äŸã§ã¯ãèšç®ãããfull_nameããããã£ã¯ãäŸåé¢ä¿ãšããŠfirst_nameãšlast_nameã远跡ããèªåçã«åæããŸãã
次ã®ã«ã¹ã¿ã ã¡ãœãããšVueã©ã€ããµã€ã¯ã«ã¡ãœããã¯ãã¡ãœããã§åºå¥ã§ããŸãã
- beforeCreate-ããŒã¿ãèŠãŠã€ãã³ããéå§ããŸã
- created-elãŸãã¯ãã³ãã¬ãŒãããããã©ããã確èªããŸãã ãã®å Žåã¯ããããã§ã¬ã³ããªã³ã°ãããŸãã ããã§ãªãå Žåã¯ãrenderã¡ãœãããæ¢ããŸã
- beforeMount-vmã$ elãäœæããelã«çœ®ãæããŸã
- ããŠã³ãæžã¿-ã¬ã³ããªã³ã°ãããèŠçŽ
ç¶æ
ãå€åãããšãïŒ
- beforeUpdate-VDOMãå床ã¬ã³ããªã³ã°ããå®éã®DOMãšæ¯èŒããå€æŽãé©çšããŸã
- æŽæ°-å€æŽãã¬ã³ããªã³ã°ãããŸã
- beforeDestroy-ãŠã©ããã£ãŒãå
éšã³ã³ããŒãã³ããã€ãã³ããªã¹ããŒãå®å
šã«å解ããŸã
- ç Žæ£-æäœãåæ¢ãããšåŒã³åºãããŸã
æ什
ãã£ã¬ã¯ãã£ãã¯ãhtmlèŠçŽ ã«è¿œå æ©èœãè¿œå ããããã®ç¹å¥ãªå±æ§ã§ãã
çµã¿èŸŒã¿ã®ãã£ã¬ã¯ãã£ãã®ããã€ããæ€èšããŠãã ããïŒAngularã§äœæ¥ãã人ã¯èª°ã§ãéåžžã«éŠŽæã¿ããããŸãïŒã
- Vãã€ã³ã-1ã€ä»¥äžã®å±æ§ã«åçã«ãã€ã³ãããŸãã
- V-ãã³ã-ããŒã¿ããã«ã¢ããããããŸã§ãã ã¹ã¿ããªãè¡šçŸãé衚瀺ã«ããŸã
- v-if-èŠçŽ ãã¬ã³ããªã³ã°ããããã®æ¡ä»¶
- V-else-v-ifã®ãelseãããã¯ããæå³ããŸã
- V-for-ãªããžã§ã¯ãã®é
åãã«ãŒãããŸã
- Vã¢ãã«-ç¶æ
ãå
¥åèŠçŽ ã«ãã€ã³ãããŸã
- V-on-ã€ãã³ããªã¹ããŒãèŠçŽ ã«é¢é£ä»ããŸã
- V-once-èŠçŽ ãæåã«ã®ã¿ã¬ã³ããªã³ã°ãããã¯ãç£èŠããŸãã
- V-pre-èŠçŽ ãšãã®åãã³ã³ãã€ã«ããŸãã
- V-show-CSS衚瀺ããããã£ãå€æŽããããšã«ãããèŠçŽ ã®å¯èŠæ§ãåãæ¿ããŸã
- V-text-èŠçŽ ã®textContentãæŽæ°ããŸã
ãã¹ãŠã®Vueãã£ã¬ã¯ãã£ãã«ã¯ããv-ããšãããã¬ãã£ãã¯ã¹ãä»ããŸãã ç¶æ
å€ããã£ã¬ã¯ãã£ãã«æž¡ãããhtmlå±æ§ãŸãã¯ã€ãã³ããåŒæ°ãšããŠäœ¿çšã§ããŸãã
html <div v-my-directive="someValue"></div>
js Vue.directive('my-directive', { bind: function () { // // , // }, update: function (newValue, oldValue) { // - }, unbind: function () { // // , bind() } })
ã³ã³ããŒãã³ã
ã³ã³ããŒãã³ãã¯ãã³ã¢htmlèŠçŽ ãæ¡åŒµããåå©çšå¯èœãªã³ãŒããå®è£
ããã®ã«åœ¹ç«ã¡ãŸãã åºæ¬çã«ãã³ã³ããŒãã³ãã¯UIã®åå©çšå¯èœãªéšåã§ãã èšèšæ®µéã§ã¯ãã¢ããªã±ãŒã·ã§ã³ãç¬ç«ããéšåã«åå²ããã³ã³ããŒãã³ãã®ããªãŒã®ãããªæ§é ãååŸããŸãã
Vue.jsã®ã³ã³ããŒãã³ãåã«ã¯ç¹å¥ãªèŠä»¶ã¯ãããŸããããã«ã¹ã¿ã ã³ã³ããŒãã³ãã®W3Cã«ãŒã«ãã€ãŸãå°æåãšããã·ã¥ã䜿çšããããšããå§ãããŸãã
app.js Vue.component('simple-counter', { template: '<button v-on:click="counter += 1">{{ counter }}</button>', data: function () { return { counter: 0 } } }) new Vue({ el: '#demo' })
æ°ããã³ã³ããŒãã³ãã¯Vue.componentã䜿çšããŠå®£èšãããæåã®åŒæ°ã§æ°ããã¿ã°ã®ååïŒãã®å Žåã¯simple-counterïŒãæž¡ããŸã
//codepen.io/Demetrius/embed/ObgyQP/?height=468&theme-id=16150&default-tab=result
vueã³ã³ããŒãã³ãéã®éä¿¡ã¯ããProps inãEvents outãã®ååã«åºã¥ããŠããŸãã ã€ãŸããæ
å ±ãå°éå
·ãä»ããŠèŠªããåã«éä¿¡ãããã€ãã³ããããªã¬ãŒãããŸãã
ãŸããVue.jsã«ã¯ãããããåäžãã¡ã€ã«ã³ã³ããŒãã³ãããããŸãã æ¡åŒµåã.vueã®ãã¡ã€ã«ãäœæããããã«ã¹ã¿ã€ã«ããã³ãã¬ãŒããããžãã¯ãèšè¿°ããŸãã ããã«ã䟿å©ãªããªããã»ããµïŒSASSãã¹ã¿ã€ã©ã¹ãPostCSSãJadeãªã©ïŒããã³JSã§ã³ã³ãã€ã«ãããèšèªïŒCoffeeScriptãTypeScriptïŒã§èšè¿°ã§ããŸãã
app.js // comment.vue <style lang="sass"> button { border: 1px solid gray; &.blue { border-color: blue; } } </style> <template lang="jade"> avatar(:user='user') input(type='text', v-model='content') button.blue(@click='submitComment') </template> <script> import Comment from '../models' import avatar from './components/avatar.vue' export default { props: ['user'], components: { avatar }, data () { return { content: '' } }, methods: { submitComment (e) { e.preventDefault(); var comment = new Comment(this.content) comment.save().then(() => { alert('o_O') this.content = '' }) } } } </script>
é·ç§»
Vueã¯ãDOMããèŠçŽ ãã¬ã³ããªã³ã°ãæŽæ°ããŸãã¯åé€ããããšãã«ã¢ãã¡ãŒã·ã§ã³å¹æãé©çšããããŸããŸãªæ¹æ³ãæäŸããŸãã 次ã®ããŒã«ãå«ãŸããŸãã
- CSSã®é·ç§»ãšã¢ãã¡ãŒã·ã§ã³ã«èªåçã«ã¯ã©ã¹ãé©çšããŸã
- Animate.cssãªã©ã®CSSã¢ãã¡ãŒã·ã§ã³çšã®ãµãŒãããŒãã£ã©ã€ãã©ãªã®çµ±å
- JavaScriptã䜿çšããŠDOMãæäœãã
- Velocity.jsãªã©ã®ãµãŒãããŒãã£ã®JavaScriptã¢ãã¡ãŒã·ã§ã³ã©ã€ãã©ãªã®çµ±å
ç°¡åãªäŸãèããŠã¿ãŸãããã
html <div id="demo"> <button @click="show = !show">Toggle show</button> <transition name="bounce"> <p v-if="show">Look at me!</p> </transition> </div>
js new Vue({ el: '#demo', data: { show: true } })
//codepen.io/Demetrius/embed/ZByQzx/?height=490&theme-id=16150&default-tab=result
ãã¬ãŒã ã¯ãŒã¯ãšã³ã·ã¹ãã
ã«ãŒãã£ã³ã°
Vue.jsã§ã¯ãåå¥ã®vue-routerããã±ãŒãžãã«ãŒãã£ã³ã°ãæ
åœããŸãã ãã¹ããããã³ã³ããŒãã³ããžã®ãã¹ããããã«ãŒãããµããŒãããããã²ãŒã·ã§ã³ããã¯ãå¶åŸ¡ãããã¹ã¯ããŒã«åäœãé«åºŠãªé·ç§»å¶åŸ¡ã®ããã®ç°¡çŽ åãããAPIãæäŸããŸãã
以äžã«å°ããªäŸã瀺ããŸãã
app.js import Vue from 'vue' import VueRouter from 'vue-router' import App from './app.vue' import ViewA from './view-a.vue' import ViewB from './view-b.vue' Vue.use(VueRouter) const router = new VueRouter() router.map({ '/a': { component: ViewA }, '/b': { component: ViewB } }) router.start(App, '#app')
app.vue <div> <h1> , </h1> <router-view></router-view> </div>
Ajaxãªã¯ãšã¹ã
Ajaxãªã¯ãšã¹ããåŠçããããã«ãvue-resourceãã©ã°ã€ã³ããããŸãã XMLHttpRequestãŸãã¯JSONPã䜿çšããŠWebèŠæ±ãäœæããå¿çãåŠçããæ©èœãæäŸããŸãã ãŸãããã©ã°ã€ã³ã®æ©èœã¯ãPromise APIããã³URIãã³ãã¬ãŒãã®ãµããŒãã§ãã
äŸïŒ
js {
ç¶æ
管ç
Vuex -
Vue.jsäžã®ã¢ããªã±ãŒã·ã§ã³ã®ãã¿ãŒã³ããã³ç¶æ
管çã©ã€ãã©ãªã ã¢ããªã±ãŒã·ã§ã³å
ã®ãã¹ãŠã®ã³ã³ããŒãã³ãã®éäžåãããäžè¬çãªç¶æ
ãšãäºæž¬å¯èœãªç¶æ
å€åãæäŸããã«ãŒã«ãæäŸããŸãã
以äžã®ç»åã¯ãVue + Vuexäžã®ã¢ããªã±ãŒã·ã§ã³ãšæ¬¡ã®éšåã瀺ããŠããŸãã
- ç¶æ
ãã³ã³ããŒãã³ãã®å¯äžã®ããŒã¿ãœãŒã¹ã§ãã
- Vueã³ã³ããŒãã³ãã¯ãæ¬è³ªçã«å®£èšçãªç¶æ
ãããã³ã°ã«ãããŸããã
- çºçããã€ãã³ãããã£ããããã¢ã¯ã·ã§ã³ã¯ãå€éšAPIããããŒã¿ãåéããç®çã®çªç¶å€ç°ãããªã¬ãŒããŸãã
- çªç¶å€ç°ã¯ç¶æ
ãå€æŽã§ããå¯äžã®éšåã§ãããã¢ã¯ã·ã§ã³ããããŒã¿ãåãåã£ãåŸãç¶æ
ã«ããããé©çšããŸãã
ãã«ãã·ã¹ãã ãšéçºè
ããŒã«
ãããã°çšã«ããã©ãŠã¶ãŒã«
Vue-devtoolããããŸãïŒæ®å¿µãªããããããŸã§ã®ãšããChromeã®ã¿ïŒãããã«ãããã¢ããªã±ãŒã·ã§ã³ã«å«ãŸããã³ã³ããŒãã³ããšãã®çŸåšã®ç¶æ
ã確èªã§ããŸãã
ãŸããVuexã§ãããŸãæ©èœããããããã¿ã€ã ãã©ãã«ãããã°ãå®è¡ã§ããŸãããã©ãŠã¶ãŒã§ç¶æ
ã®å±¥æŽã確èªããç¶æ
ãåãæ¿ããããšãã§ããŸãã
ãªãããã䜿ãã¹ããªã®ã
Vueã¯ãããïŒ ãã«ãã·ã¹ãã ãŸãã¯CLIã§ã·ã£ãŒããã€ãºããããšãªããããŒãžã«ãã©ã°ã€ã³ããŠäœæ¥ãéå§ã§ããã®ã¯çŽ æŽãããããšã§ãã JavaScriptãã¬ãŒã ã¯ãŒã¯ã䜿çšããããšããªãå Žåã§ããç°¡åã«äœæ¥ãéå§ã§ããŸãã ããã¯ãå©äŸ¿æ§ãšãã¯ãŒã®å®ç§ãªçµã¿åããã§ãã 圌ã«æå©ãªããã€ãã®è°è«ãæ€èšããŠãã ããã
- ä»ã§ã¯ããã«å°ãããªã£ãŠããŸãã Vue.js 2.0ã®ã©ã³ã¿ã€ã ãã«ãã®éãã¯ããã16kbã§ãããvue-routerããã³vuexãšãšãã«26kbã®éãã§ãïŒæåã®ããŒãžã§ã³ã®ã«ãŒãã«ãšåæ§ïŒã
- 圌ã¯ããã«éãã§ãã Vue.jsã¯åžžã«é床ã«å€§ããªæ³šæãæã£ãŠããŸããã Snabbdomã®ä»®æ³DOMãã©ãŒã¯ã®å®è£
ã容æã«ããããã«ãã¬ã³ããªã³ã°ãæ
åœããã¬ã€ã€ãŒãæžãçŽãããŸãã ã
- Vue 2.0ã¯ãµãŒããŒåŽã®ã¬ã³ããªã³ã°ããµããŒãããŠããŸãã ãããè¡ãããã«ãVueãšã³ã·ã¹ãã ã®ä»ã®ããŒã«ïŒvue-routerããã³vuexïŒããµããŒãããV ue-server-rendererã¢ãžã¥ãŒã«ããããŸãã å圢ã¢ããªã±ãŒã·ã§ã³ã®äœæãã¯ããã«ç°¡åã«ãªããŸããã
- Alibabaã®ã¡ã³ããŒã¯ãã¯ãã¹ãã©ãããã©ãŒã ã®ãã€ãã£ãã¢ãã€ã«UIïŒReactNativeãNativeScriptãªã©ïŒã§ããWeexã«åãçµãã§ããŸãã ä»åŸãVueã³ã³ããŒãã³ãã¯WebãAndroidãiOSã§äœ¿çšã§ããŸãã
Vueã¯å°ããªã¢ããã¥ã¢ãããžã§ã¯ããã倧èŠæš¡ãªã³ãã¥ããã£ã§åºã䜿çšãããŠãããããžã§ã¯ãã«ç§»è¡ããŸããããã®ãã¬ãŒã ã¯ãŒã¯ã䜿çšãããã©ããã«ã€ããŠã®çåãææã§ããããšãé¡ã£ãŠããŸãã
ãæž
èŽããããšãããããŸããïŒ
äœæè
ïŒ
greebn9k ïŒã»ã«ã²ã€ã°ãªããã£ãã¯ïŒã
ããããªãŒã€ãŽã¡ãã ïŒããããªãŒã€ãŽã¡ããïŒã
ã·ã«ããªãªã³ ïŒã¢ã³ãã¬ã€ããã¬ãïŒ