ã¬ã¤ã
åºæ¬çãªä½¿ãæ¹
- ã¤ã³ã¹ãã¼ã«
- ã¯ããã«
- Vue ã¤ã³ã¹ã¿ã³ã¹
- ãã³ãã¬ã¼ãæ§æ
- ç®åºããããã£ã¨ã¦ã©ããã£
- ã¯ã©ã¹ã¨ã¹ã¿ã¤ã«ã®ãã¤ã³ãã£ã³ã°
- æ¡ä»¶ä»ãã¬ã³ããªã³ã°
- ãªã¹ãã¬ã³ããªã³ã°
- ã¤ãã³ããã³ããªã³ã°
- ãã©ã¼ã å ¥åãã¤ã³ãã£ã³ã°
- ã³ã³ãã¼ãã³ãã®åºæ¬
ã³ã³ãã¼ãã³ãã®è©³ç´°
- ã³ã³ãã¼ãã³ãã®ç»é²
- ããããã£
- ã«ã¹ã¿ã ã¤ãã³ã
- ã¹ããã
- åç & éåæã³ã³ãã¼ãã³ã
- ç¹å¥ãªåé¡ã«å¯¾å¦ãã
ãã©ã³ã¸ã·ã§ã³ã¨ã¢ãã¡ã¼ã·ã§ã³
- Enter/Leave ã¨ãã©ã³ã¸ã·ã§ã³ä¸è¦§
- ç¶æ ã®ãã©ã³ã¸ã·ã§ã³
åå©ç¨ã¨æ§æ
- ããã¯ã¹ã¤ã³
- ã«ã¹ã¿ã ãã£ã¬ã¯ãã£ã
- æç»é¢æ°ã¨JSX
- ãã©ã°ã¤ã³
- ãã£ã«ã¿ã¼
ãã¼ã«
- åä¸ãã¡ã¤ã«ã³ã³ãã¼ãã³ã
- ãã¹ã
- TypeScript ã®ãµãã¼ã
- ãããã¯ã·ã§ã³ç°å¢ã¸ã®é ä¿¡
ã¹ã±ã¼ã«ã¢ãã
- ã«ã¼ãã£ã³ã°
- ç¶æ 管ç
- ãµã¼ããµã¤ãã¬ã³ããªã³ã°
- ã»ãã¥ãªãã£
å é¨
- ãªã¢ã¯ãã£ãã®æ¢æ±
移è¡
- Vue 1.x ããã®ç§»è¡
- Vue Router 0.7.x ããã®ç§»è¡
- Vuex 0.6.x ãã 1.0 ã¸ã®ç§»è¡
ãã®ä»
- ä»ã®ãã¬ã¼ã ã¯ã¼ã¯ã¨ã®æ¯è¼
- Vue.js ã³ãã¥ããã£ã¸åå ãã¾ããã!
- ãã¼ã ã«ä¼ãã
v2.x 以åã®ããã¥ã¡ã³ãã§ãã v3.x ã®ããã¥ã¡ã³ããè¦ããå ´åã¯ãã¡ã
æç»é¢æ°ã¨JSX
æçµæ´æ°æ¥: 2019å¹´7æ6æ¥
åºæ¬
Vue ã§ã¯ã»ã¨ãã©ã®å ´å HTML ããã«ãããããã«ãã³ãã¬ã¼ãã使ããã¨ãæ¨å¥¨ããã¾ããããããJavaScript ã«ããå®å ¨ãªããã°ã©ãã³ã°ãã¯ã¼ãå¿ è¦ã¨ããç¶æ³ãããã¾ããããã§ãã³ãã¬ã¼ãã¸ã®ä»£æ¿ã§ãããã³ã³ãã¤ã©ã«è¿ã æç» (render) é¢æ°ã使ç¨ã§ãã¾ãã
render
é¢æ°ãå®ç¨çã«ãªãããç°¡åãªä¾ãè¦ã¦ã¿ã¾ããããã§ã¯ãã¢ã³ã«ã¼ããããçæãããã¨ãã¾ãã
<h1>
<a name="hello-world" href="#hello-world">
Hello world!
</a>
</h1>
ä¸è¨ã® HTML ã«å¯¾ãã¦ãæã¾ããã³ã³ãã¼ãã³ãã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ã決ãã¾ãããã
<anchored-heading :level="1">Hello world!</anchored-heading>
level
ããããã£ãå
ã«ãã¦ããããçæããã ãã®ã³ã³ãã¼ãã³ãããå§ããæãããã«ä»¥ä¸ã®ä¾ã«ãã©ãçãã§ãããã
<script type="text/x-template" id="anchored-heading-template">
<h1 v-if="level === 1">
<slot></slot>
</h1>
<h2 v-else-if="level === 2">
<slot></slot>
</h2>
<h3 v-else-if="level === 3">
<slot></slot>
</h3>
<h4 v-else-if="level === 4">
<slot></slot>
</h4>
<h5 v-else-if="level === 5">
<slot></slot>
</h5>
<h6 v-else-if="level === 6">
<slot></slot>
</h6>
</script>
Vue.component('anchored-heading', {
template: '#anchored-heading-template',
props: {
level: {
type: Number,
required: true
}
}
})
ãã®ãã³ãã¬ã¼ãã¯è¯ãæ°ããã¾ãããåé·ãªã ãã§ãªããå
¨ã¦ã®ãããã¬ãã«ã§ <slot></slot>
ãéè¤ããã¦ãããã¢ã³ã«ã¼è¦ç´ ã追å ãããæã«åããã¨ãããå¿
è¦ãããã¾ãã
ãã³ãã¬ã¼ãã¯ã»ã¨ãã©ã®ã³ã³ãã¼ãã³ãã§ãã¾ãåä½ãã¾ããããã®ä¾ã¯ããã§ã¯ãªããã¨ãæ確ã§ããã§ã¯ã render
é¢æ°ã使ã£ã¦ãããæ¸ãç´ãã¦ã¿ã¾ãããã
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // ã¿ã°å
this.$slots.default // åã®é
å
)
},
props: {
level: {
type: Number,
required: true
}
}
})
å°ãã·ã³ãã«ã«ãªãã¾ãããï¼ã³ã¼ãã¯çããªãã¾ããããVue ã¤ã³ã¹ã¿ã³ã¹ããããã£ã®è±å¯ãªç¥èãå¿
è¦ã¨ãã¾ãããã®ã±ã¼ã¹ã§ã¯ã v-slot
ãã£ã¬ã¯ãã£ãç¡ãã§ã³ã³ãã¼ãã³ãã«åã渡ããæã« ( anchored-heading
ã®å
å´ã® Hello world!
ã®ãããª) ããããã®åãã³ã³ãã¼ãã³ãã¤ã³ã¹ã¿ã³ã¹ä¸ã® $slots.default
ã«ã¹ãã¢ããã¦ãããã¨ãç¥ã£ã¦ããå¿
è¦ãããã¾ããããã¾ã ç¥ããªããªããrender é¢æ°ã«é²ãåã« ã¤ã³ã¹ã¿ã³ã¹ããããã£API ãèªããã¨ããªã¹ã¹ã¡ãã¾ãã
ãã¼ããããªã¼ãããã³ä»®æ³ DOM
render é¢æ°ã説æããåã«ããã©ã¦ã¶ã®ä»çµã¿ã«ã¤ãã¦å°ãç¥ã£ã¦ãããã¨ãéè¦ã§ããä¾ãã°ã次ã®ããã« HTML ãå ¥åãã¾ãã
<div>
<h1>My title</h1>
Some text content
<!-- TODO: Add tagline -->
</div>
ãã©ã¦ã¶ã¯ãã®ã³ã¼ããèªã¿è¾¼ãã¨ãè¡ç¸é¢ä¿ã追跡ããããã«å®¶ç³»å³ãæ§ç¯ããã®ã¨åãããã«ãå ¨ã¦ã追跡ãã âDOM ãã¼ãâããªã¼ãæ§ç¯ãã¾ãã
ä¸è¨ã® HTML ã® DOM ãã¼ãã®ããªã¼ã¯æ¬¡ã®ããã«ãªãã¾ãã
å ¨ã¦ã®è¦ç´ ã¯ãã¼ãã§ããå ¨ã¦ã®ããã¹ãã¯ãã¼ãã§ããã³ã¡ã³ãããããã¼ãã§ãï¼ãã¼ãã¯ãã¼ã¸ã®ä¸é¨ã«éãã¾ããã ããã¦ã家系å³ã®ããã«ãåãã¼ãã¯åä¾ãæã¤ãã¨ãã§ãã¾ã(ã¤ã¾ããåé¨åã«ã¯ä»ã®é¨åãå«ãããã¨ãã§ãã¾ã)ã
ãããã®ãã¼ããå ¨ã¦å¹ççã«æ´æ°ããã®ã¯é£ããããããã¾ããããããããããã¨ã«ãæåã§è¡ãå¿ è¦ã¯ããã¾ããããã³ãã¬ã¼ãå ã®ã©ã® HTML ããã¼ã¸ã«è¡¨ç¤ºãããã Vue ã«ä¼ããã ãã§ãã
<h1>{{ blogTitle }}</h1>
ã¾ã㯠render é¢æ°ã®å ´å:
render: function (createElement) {
return createElement('h1', this.blogTitle)
}
ã©ã¡ãã®å ´åã§ããblogTitle
ãå¤æ´ãããã¨ãã§ãããVue ã¯ãã¼ã¸ãèªåçã«æ´æ°ãã¾ãã
ä»®æ³ DOM
Vue ã¯ãå®éã® DOM ã«å ããå¿ è¦ãããå¤æ´ã追跡ããä»®æ³ DOM ãæ§ç¯ãããã¨ã§ããããéæãã¾ãã
return createElement('h1', this.blogTitle)
createElement
ã¯å®éã«ä½ãè¿ãã¦ããã®ã§ããããï¼æ£ç¢ºã«ã¯å®éã® DOM è¦ç´ ã§ã¯ããã¾ãããã©ã®ãã¼ããæç»ããããè¨è¿°ããæ
å ±ãåãã¼ãã®è¨è¿°ãå«ã㧠Vue ã«å«ã¾ãã¦ãããããããæ£ç¢ºã«ã¯ createNodeDescription
ã¨ããååã«ãªãã¾ãããã®ãã¼ãè¨è¿°ã¯âä»®æ³ãã¼ãâã¨å¼ã°ããé常㯠VNode ã¨ç¥ããã¾ããâä»®æ³ DOMâ ã¯ãVue ã³ã³ãã¼ãã³ãã®ããªã¼ã§æ§ç¯ããã VNode ã®ããªã¼å
¨ä½ã¨å¼ãã§ãããã®ã§ãã
createElement
å¼æ°
ããªããç²¾éããå¿
è¦ããã次ã®ãã¨ã¯ createElement
é¢æ°ã®ä¸ã§ãã³ãã¬ã¼ãã®æ©è½ãã©ã®ããã«ä½¿ããã«ã¤ãã¦ã§ãããã¡ãã createElement
ã®åãä»ããå¼æ°ã§ãã
// @returns {VNode}
createElement(
// {String | Object | Function}
// HTML ã¿ã°åãã³ã³ãã¼ãã³ããªãã·ã§ã³ããããã¯
// ãã®ã©ã¡ããã解決ããéåæé¢æ°ã§ããå¿
é ã§ãã
'div',
// {Object}
// ãã³ãã¬ã¼ãå
ã§ä½¿ãã§ãããå±æ§ã«å¯¾å¿ãã
// ãã¼ã¿ãªãã¸ã§ã¯ããä»»æã§ãã
{
// (詳細ã¯ä¸ã®æ¬¡ã®ã»ã¯ã·ã§ã³ããåç
§ãã ãã)
},
// {String | Array}
// åã®VNodeã`createElement()` ã使ç¨ãã¦æ§ç¯ãããã
// ããã¹ã VNode ã®å ´åã¯åã«æååã使ç¨ãã¾ããä»»æã§ãã
[
'Some text comes first.',
createElement('h1', 'A headline'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
ãã¼ã¿ãªãã¸ã§ã¯ã詳解
1 ã¤æ³¨æç¹: v-bind:class
㨠v-bind:style
ããã³ãã¬ã¼ãå
ã§ç¹æ®ãªæ±ããããã¦ããã®ã¨åãããã«ãããã㯠VNode ã®ãã¼ã¿ãªãã¸ã§ã¯ãå
ã§èªèº«ã®ãããã¬ãã«ãã£ã¼ã«ããæã¡ã¾ãããã®ãªãã¸ã§ã¯ã㯠innerHTML
ã®ãããªé常㮠HTML å±æ§ã ãã§ãªã DOM ããããã£ããã¤ã³ããããã¨ãã§ãã¾ã(ãã㯠v-html
ãã£ã¬ã¯ãã£ãã«åã£ã¦ä»£ãããã®ã§ã):
{
// `v-bind:class` ã¨åã APIããããããåãä»ãã
// æååããªãã¸ã§ã¯ãã¾ãã¯æååã¨ãªãã¸ã§ã¯ãã®é
å
class: {
foo: true,
bar: false
},
// `v-bind:style` ã¨åã APIããããããåãä»ãã
// æååããªãã¸ã§ã¯ãã¾ãã¯ãªãã¸ã§ã¯ãã®é
å
style: {
color: 'red',
fontSize: '14px'
},
// é常㮠HTML å±æ§
attrs: {
id: 'foo'
},
// ã³ã³ãã¼ãã³ãããããã£
props: {
myProp: 'bar'
},
// DOM ããããã£
domProps: {
innerHTML: 'baz'
},
// ã¤ãã³ããã³ãã©ã¯ `on` ã®é
ä¸ã«ç½®ããã¾ãã
// ãã ãã `v-on:keyup.enter` ãªã©ã®ä¿®é£¾è©ã¯ãµãã¼ãããã¾ããã
// ãã®ä»£ãããæå㧠keyCode ããã³ãã©ã®ä¸ã§
// 確èªããå¿
è¦ãããã¾ãã
on: {
click: this.clickHandler
},
// ã³ã³ãã¼ãã³ãã®å ´åã®ã¿ã
// `vm.$emit` ã使ã£ã¦ã³ã³ãã¼ãã³ããã emit ãããã¤ãã³ãã§ã¯ãªã
// ãã¤ãã£ãã®ã¤ãã³ãã listen ãããã¨ãã§ãã¾ãã
nativeOn: {
click: this.nativeClickHandler
},
 // ã«ã¹ã¿ã ãã£ã¬ã¯ãã£ãã`binding` ã® `oldValue` ã«ã¤ãã¦ã¯
 // ããªãã®ä»£ããã« Vue ãé¢åãè¦ãã®ã§ãè¨å®ãããã¨ã¯ã§ãã¾ããã
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// { name: props => VNode | Array<VNode> }
// ã® å½¢å¼ã§ã®ã¹ã³ã¼ãä»ãã¹ããã
scopedSlots: {
default: props => createElement('span', props.text)
},
// ãã®ã³ã³ãã¼ãã³ããä»ã®ã³ã³ãã¼ãã³ãã®åã®å ´åã¯ããã®ã¹ãããå
slot: 'name-of-slot',
// ä»ã®ç¹æ®ãªãããã¬ãã«ã®ããããã£
key: 'myKey',
ref: 'myRef',
// If you are applying the same ref name to multiple
// elements in the render function. This will make `$refs.myRef` become an
// array
refInFor: true
}
å®å ¨ãªä¾
ãããã®ç¥èã使ãã°ãç§ãã¡ãå§ããã³ã³ãã¼ãã³ããå®äºããããã¨ãã§ããããã«ãªãã¾ããã
var getChildrenTextContent = function (children) {
return children.map(function (node) {
return node.children
? getChildrenTextContent(node.children)
: node.text
}).join('')
}
Vue.component('anchored-heading', {
render: function (createElement) {
// kebab-case id ã®ä½æ
var headingId = getChildrenTextContent(this.$slots.default)
.toLowerCase()
.replace(/\W+/g, '-')
.replace(/(^-|-$)/g, '')
return createElement(
'h' + this.level,
[
createElement('a', {
attrs: {
name: headingId,
href: '#' + headingId
}
}, this.$slots.default)
]
)
},
props: {
level: {
type: Number,
required: true
}
}
})
å¶ç´
VNode ã¯ä¸æã§ãªããã°ãªããªã
ã³ã³ãã¼ãã³ãããªã¼ã®ä¸ã§å ¨ã¦ã® VNode ã¯ä¸æã§ãªããã°ãªãã¾ãããã¤ã¾ãã以ä¸ã® render é¢æ°ã¯ä¸æ£ã§ãã
render: function (createElement) {
var myParagraphVNode = createElement('p', 'hi')
return createElement('div', [
// ãã - éè¤ã® VNodes ï¼
myParagraphVNode, myParagraphVNode
])
}
ããåãè¦ç´ / ã³ã³ãã¼ãã³ããä½åº¦ãéè¤ããããå ´åã«ã¯ãfactory é¢æ°ã使ããã¨ã§å¯¾å¿ã§ãã¾ããä¾ãã°ã次㮠render é¢æ°ã¯ 20 åã®ä¸æã«ç¹å®ã§ãããã©ã°ã©ããæç»ããå®å ¨ã«æ£å½ãªæ¹æ³ã§ãã
render: function (createElement) {
return createElement('div',
Array.apply(null, { length: 20 }).map(function () {
return createElement('p', 'hi')
})
)
}
ç´ ã® JavaScript ã«ãããã³ãã¬ã¼ãã®æ¸ãæã
v-if
㨠v-for
ã©ããªã¨ããã§ãç´ ã® JavaScript ã§ç°¡åã«ç©äºã¯æãéãããã¨ãã§ããã®ã§ãVue ã® render é¢æ°ã¯ç¬èªã®ä»£æ¿æ段ãæä¾ãã¾ãããä¾ãã°ã以ä¸ã® v-if
㨠v-for
ã使ã£ããã³ãã¬ã¼ãï¼
<ul v-if="items.length">
<li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>No items found.</p>
ãã㯠render é¢æ°ã«ããã¦ã¯ JavaScript ã® if
/ else
㨠map
ã使ã£ã¦æ¸ãæãããã¨ãã§ãã¾ãã
props: ['items'],
render: function (createElement) {
if (this.items.length) {
return createElement('ul', this.items.map(function (item) {
return createElement('li', item.name)
}))
} else {
return createElement('p', 'No items found.')
}
}
v-model
æç»é¢æ°ã«ã¯ç´æ¥ç㪠v-model
ã®å¯¾å¿ã¯ããã¾ããã ããªãèªèº«ã§ãã¸ãã¯ãå®è£
ããå¿
è¦ãããã¾ã:
props: ['value'],
render: function (createElement) {
var self = this
return createElement('input', {
domProps: {
value: self.value
},
on: {
input: function (event) {
self.$emit('input', event.target.value)
}
}
})
}
ããã¯ä½ã¬ãã«ã®ã³ã¹ãã§ãããv-model
ã¨æ¯è¼ãã¦ã¤ã³ã¿ã©ã¯ã·ã§ã³ããã詳細ã«å¶å¾¡ãããã¨ãã§ãã¾ãã
ã¤ãã³ãã¨ãã¼ä¿®é£¾å
.passive
ã.capture
㨠.once
ã¤ãã³ã修飾åã«å¯¾ãã¦ãVue 㯠on
ã§ä½¿ç¨ã§ããæ¥é è¾ãæä¾ãã¦ãã¾ã:
修飾å | æ¥é è¾ |
---|---|
.passive |
& |
.capture |
! |
.once |
~ |
.capture.once ã¾ã㯠.once.capture |
~! |
ä¾:
on: {
'!click': this.doThisInCapturingMode,
'~keyup': this.doThisOnce,
'~!mouseover': this.doThisOnceInCapturingMode
}
å ¨ã¦ã®ä»ã®ã¤ãã³ãã¨ãã¼ä¿®é£¾åã«å¯¾ãã¦ã¯ãåã«ãã³ãã©å ã®ã¤ãã³ãã¡ã½ããã使ç¨ã§ãããããç¬èªã®æ¥é è¾ã¯å¿ è¦ããã¾ãã:
修飾å | ãã³ãã©ã«ç¸å½ |
---|---|
.stop |
event.stopPropagation() |
.prevent |
event.preventDefault() |
.self |
if (event.target !== event.currentTarget) return |
ãã¼:.enter , .13 |
if (event.keyCode !== 13) return (ä»ã®ãã¼ä¿®é£¾åã«å¯¾ãã¦ã13 ãå¥ã®ãã¼ã³ã¼ãã«å¤æ´ãã) |
修飾åãã¼:.ctrl , .alt , .shift , .meta |
if (!event.ctrlKey) return (ctrlKey ã altKey ãshiftKey ãã¾ã㯠metaKey ãããããå¤æ´ãã) |
以ä¸ã«ããããã®ä¿®é£¾åããã¹ã¦ä¸ç·ã«ä½¿ç¨ããã¦ããä¾ã示ãã¾ã:
on: {
keyup: function (event) {
// ã¤ãã³ããçºè¡ãã¦ããè¦ç´ ãã
// ã¤ãã³ããæç¸ããã¦ããè¦ç´ ã§ãªãå ´åã¯ä¸æ¢ãã¾ãã
if (event.target !== event.currentTarget) return
// up ãããã¼ã enter ãã¼ (13) ã§ãªãã
// shift ãã¼ãåæã«æ¼ããã¦ããªãå ´åã¯ä¸æ¢ãã¾ãã
if (!event.shiftKey || event.keyCode !== 13) return
// ã¤ãã³ãã®ä¼æãåæ¢ãã¾ãã
event.stopPropagation()
// ãã®è¦ç´ ã«å¯¾ãããããã©ã«ãã® keyup ãã³ãã©ãç¡å¹ã«ãã¾ãã
event.preventDefault()
// ...
}
}
ã¹ããã
this.$slots
ãã VNode ã®é
åã¨ãã¦éçãªã¹ãããã®å
容ã«ã¢ã¯ã»ã¹ã§ãã¾ã:
render: function (createElement) {
// `<div><slot></slot></div>`
return createElement('div', this.$slots.default)
}
ããã¦ãthis.$scopedSlots
ãã VNode ãè¿ãé¢æ°ã¨ãã¦ã¹ã³ã¼ãä»ãã¹ãããã«ã¢ã¯ã»ã¹ã§ãã¾ã:
props: ['message'],
render: function (createElement) {
// `<div><slot :text="message"></slot></div>`
return createElement('div', [
this.$scopedSlots.default({
text: this.message
})
])
}
ã¹ã³ã¼ãä»ãã¹ããããæç»é¢æ°ã使ã£ã¦åã³ã³ãã¼ãã³ãã«æ¸¡ãã«ã¯ãVNode ãã¼ã¿ã® scopedSlots
ãã£ã¼ã«ãã使ãã¾ã:
render: function (createElement) {
// `<div><child v-slot="props"><span>{{ props.text }}</span></child></div>`
return createElement('div', [
createElement('child', {
// { name: props => VNode | Array<VNode> } ã®å½¢å¼ã§
// `scopedSlots` ã ãã¼ã¿ãªãã¸ã§ã¯ãã«æ¸¡ã
scopedSlots: {
default: function (props) {
return createElement('span', props.text)
}
}
})
])
}
JSX
ããããªããå¤ãã® render é¢æ°ãæ¸ãã¦ããå ´åã¯ããã®ãããªæ¸ãæ¹ã¯ã¤ããã¨æããããããã¾ããã
createElement(
'anchored-heading', {
props: {
level: 1
}
}, [
createElement('span', 'Hello'),
' world!'
]
)
ç¹ã«ããã³ãã¬ã¼ããªãããã«ããã¹ã¦ãããªã«ç°¡åã«æ¸ããã¨ããå ´åã¯:
<anchored-heading :level="1">
<span>Hello</span> world!
</anchored-heading>
ãã®ãããªçç±ãã Vue 㧠JSX ã使ãããã® Babel ãã©ã°ã¤ã³ ãããã¾ãããããã³ãã¬ã¼ãã«è¿ãææ³ãæ»ã£ã¦ãã¾ããã
import AnchoredHeading from './AnchoredHeading.vue'
new Vue({
el: '#demo',
render: function (h) {
return (
<AnchoredHeading level={1}>
<span>Hello</span> world!
</AnchoredHeading>
)
}
})
createElement
ã h
ã«ã¨ã¤ãªã¢ã¹ãã¦ãããã¨ã¯ã Vue ã®ã¨ã³ã·ã¹ãã ã®ä¸ã§ããè¦ãããæ
£ç¿ã§ããããã¦ãããã¯å®ã¯ JSX ã«ã¯å¿
é ã§ããVue ã® Babel ãã©ã°ã¤ã³ã® ãã¼ã¸ã§ã³ 3.4.0 以éã§ã¯ãES2015 ã®ã·ã³ã¿ãã¯ã¹ã§å®£è¨ããã JSX ãå«ãã¡ã½ããã getterï¼é¢æ°ãã¢ãã¼é¢æ°ã¯å¯¾è±¡å¤ï¼ã«å¯¾ãã¦ã¯ãèªåçã« const h = this.$createElement
ã注å
¥ãããããã(h)
ãã©ã¡ã¼ã¿ã¼ã¯çç¥ã§ãã¾ãããã以åã®ãã¼ã¸ã§ã³ã§ã¯ããã h
ããã®ã¹ã³ã¼ãå
ã§å©ç¨å¯è½ã§ãªãå ´åãã¢ããªã±ã¼ã·ã§ã³ã¯ã¨ã©ã¼ã throw ããã§ãããã
ãã詳ãã JSX ã® JavaScript ã¸ã®ãããã®ä»æ¹ã«ã¤ãã¦ã¯ãusage ããã¥ã¡ã³ã ããåç §ãã ããã
é¢æ°åã³ã³ãã¼ãã³ã
å ã»ã©ä½æããã¢ã³ã«ã¼ãããã³ã³ãã¼ãã³ãã¯æ¯è¼çã·ã³ãã«ã§ããç¶æ ã®ç®¡çã渡ãããç¶æ ã® watch ããã¦ããããã¾ããä½ãã©ã¤ããµã¤ã¯ã«ã¡ã½ãããæã¡ã¾ãããå®éãããã¯ããã¤ãã®ããããã£ãæã¤ãã ã®é¢æ°ã§ãã
ãã®ãããªã±ã¼ã¹ã«ããã¦ãç§ãã¡ã¯ é¢æ°å
ã¨ãã¦ã³ã³ãã¼ãã³ãããã¼ã¯ãããã¨ãã§ãã¾ããããã¯ç¶æ
ãæããªã (ãªã¢ã¯ãã£ããã¼ã¿ãç¡ã) ã§ã¤ã³ã¹ã¿ã³ã¹ãæããªã ( this
ã®ã³ã³ããã¹ããç¡ã) ãã¨ãæå³ãã¾ããé¢æ°åã³ã³ãã¼ãã³ã ã¯æ¬¡ã®ãããªå½¢å¼ããã¦ãã¾ãã
Vue.component('my-component', {
functional: true,
// ããããã£ã¯ä»»æã§ã
props: {
// ...
},
// ã¤ã³ã¹ã¿ã³ã¹ãç¡ããã¨ãè£ãããã«ã
// 2 ã¤ç®ã® context å¼æ°ãæä¾ããã¾ãã
render: function (createElement, context) {
// ...
}
})
注æ: 2.3.0 以åã®ãã¼ã¸ã§ã³ã§ã¯ã
props
ãªãã·ã§ã³ã¯ãé¢æ°åã³ã³ãã¼ãã³ãã§ããããã£ãåãå ¥ãããå ´åå¿ é ã§ãã2.3.0 以éã§ã¯ãprops
ãªãã·ã§ã³ãçç¥ãããã¨ãã§ããããã¦ã³ã³ãã¼ãã³ãã®ãã¼ãä¸ã«ããå ¨ã¦ã®å±æ§ã¯ãæé»çã«ããããã£ã¨ãã¦æ½åºããã¾ããé¢æ°åã³ã³ãã¼ãã³ãã¯ç¶æ ãæããã¤ã³ã¹ã¿ã³ã¹åãã§ããªãã®ã§ããã®åç §ã¯ HTMLElement ã«ãªãã¾ãã
2.5.0以éã§ã¯ãåä¸ãã¡ã¤ã«ã³ã³ãã¼ãã³ãã使ç¨ãã¦ããå ´åããã³ãã¬ã¼ããã¼ã¹ã®é¢æ°åã³ã³ãã¼ãã³ãã¯æ¬¡ã®ããã«å®£è¨ã§ãã¾ãã
<template functional>
</template>
ã³ã³ãã¼ãã³ããå¿
è¦ã¨ããå
¨ã¦ã®ãã®ã¯ context
ãéãã¦æ¸¡ããã¾ããããã¯æ¬¡ãå«ããªãã¸ã§ã¯ãã§ãã
props
: æä¾ãããããããã£ã®ãªãã¸ã§ã¯ãchildren
: å VNode ã®é åslots
: slots ãªãã¸ã§ã¯ããè¿ãé¢æ°scopedSlots
: (2.6.0 以é) ã¹ã³ã¼ãä»ãã¹ããããå ¬éãããªãã¸ã§ã¯ããé常ã®ã¹ããããé¢æ°ã¨ãã¦å ¬éãã¾ãdata
:createElement
ã®ç¬¬ 2 å¼æ°ã¨ãã¦ã³ã³ãã¼ãã³ãã«æ¸¡ãããå ¨ä½ã®ãã¼ã¿ãªãã¸ã§ã¯ãparent
: 親ã³ã³ãã¼ãã³ãã¸ã®åç §listeners
: (2.3.0 以é) 親ã«ç»é²ãããã¤ãã³ããªã¹ãã¼ãå«ããªãã¸ã§ã¯ããããã¯åç´ã«data.on
ã®ã¨ã¤ãªã¢ã¹ã§ãinjections
: (2.3.0 以é)inject
ãªãã·ã§ã³ã§ä½¿ç¨ããå ´åãããã¯è§£æ±ºãããã¤ã³ã¸ã§ã¯ã·ã§ã³(æ³¨å ¥)ãå«ã¾ãã¾ã
functional: true
ã追å ããå¾ãç§ãã¡ã®ã¢ã³ã«ã¼ãããã³ã³ãã¼ãã³ãã® render é¢æ°ã®æ´æ°ã¨ãã¦åã«å¿
è¦ã«ãªãã®ã¯ãcontext
å¼æ°ã®è¿½å ãthis.$slots.default
ã® context.children
ã¸ã®æ´æ°ãthis.level
ã® context.props.level
ã¸ã®æ´æ°ã§ãããã
é¢æ°åã³ã³ãã¼ãã³ãã¯ãã ã®é¢æ°ãªã®ã§ãæç»ã³ã¹ãã¯å°ãªãã§ãã
ã¾ããã©ããã¼ã³ã³ãã¼ãã³ãã¨ãã¦ãã¨ã¦ã便å©ã§ããä¾ãã°ã以ä¸ãå¿ è¦ãªæã«ã
- ããã¤ãã®ä»ã®ã³ã³ãã¼ãã³ããã 1 ã¤å§è²ããããã®ãã®ãããã°ã©ã ã§é¸ã¶æ
- åãããããã£ãã¾ãã¯ããã¼ã¿ãåã³ã³ãã¼ãã³ãã¸æ¸¡ãåã«æä½ãããæ
ãã¡ããã渡ãããããããã£ã«å¿ãã¦ããå
·ä½çãªã³ã³ãã¼ãã³ãã«å§è²ãã smart-list
ã³ã³ãã¼ãã³ãã®ä¾ã§ãã
var EmptyList = { /* ... */ }
var TableList = { /* ... */ }
var OrderedList = { /* ... */ }
var UnorderedList = { /* ... */ }
Vue.component('smart-list', {
functional: true,
props: {
items: {
type: Array,
required: true
},
isOrdered: Boolean
},
render: function (createElement, context) {
function appropriateListComponent () {
var items = context.props.items
if (items.length === 0) return EmptyList
if (typeof items[0] === 'object') return TableList
if (context.props.isOrdered) return OrderedList
return UnorderedList
}
return createElement(
appropriateListComponent(),
context.data,
context.children
)
}
})
åè¦ç´ /ã³ã³ãã¼ãã³ãã¸ã®å±æ§ããã³ã¤ãã³ãã®åã渡ã
é常ã®ã³ã³ãã¼ãã³ãã§ã¯ãprops ã¨ãã¦å®ç¾©ããã¦ããªãå±æ§ã¯ã³ã³ãã¼ãã³ãã®ã«ã¼ãè¦ç´ ã«èªåçã«è¿½å ãããååã®æ¢åã®å±æ§ã¨ç½®æã¾ãã¯è³¢ããã¼ã¸ããã¾ãã
ã¨ããããé¢æ°åã³ã³ãã¼ãã³ãã§ã¯ããã®åä½ãæ示çã«å®ç¾©ããå¿ è¦ãããã¾ã:
Vue.component('my-functional-button', {
functional: true,
render: function (createElement, context) {
// ä»»æã®å±æ§ãã¤ãã³ããªã¹ããåãªã©ãééçã«æ¸¡ãã¾ãã
return createElement('button', context.data, context.children)
}
})
context.data
ã createElement
ã®ç¬¬2å¼æ°ã¨ãã¦æ¸¡ããã¨ã§ãmy-function-button
ã§ä½¿ç¨ãããå±æ§ãã¤ãã³ããªã¹ãã渡ãã¦ãã¾ããå®éãã¤ãã³ã㯠.native
修飾åãå¿
è¦ã¨ããªããããã¨ã¦ãééçã§ãã
ããããªãããã³ãã¬ã¼ããã¼ã¹ã®é¢æ°åã³ã³ãã¼ãã³ãã使ç¨ãã¦ããå ´åãå±æ§ã¨ãªã¹ãã¼ãæåã§è¿½å ããå¿
è¦ãããã¾ããç§ãã¡ã¯åã
ã®ã³ã³ããã¹ãã®å
容ã«ã¢ã¯ã»ã¹ã§ããã®ã§ãã¤ãã³ããªã¹ãã渡ãããã® listeners
(data.on
ã®ã¨ã¤ãªã¢ã¹) 㨠HTML ã®å±æ§ã渡ãããã® data.attrs
ã使ç¨ãããã¨ãã§ãã¾ãã
<template functional>
<button
class="btn btn-primary"
v-bind="data.attrs"
v-on="listeners"
>
<slot/>
</button>
</template>
slots()
vs children
ãããããã¨ãªã slots()
㨠children
ã®ä¸¡æ¹ãå¿
è¦ãªã®ãä¸æè°ã«æãããããã¾ããã slots().default
㯠children
ã¨åãã§ã¯ãªãã®ã§ããï¼ããã¤ãã®ã±ã¼ã¹ã§ã¯ããã§ããããã以ä¸ã®åãæã¤é¢æ°åã³ã³ãã¼ãã³ãã®å ´åã¯ã©ããªãã§ãããã
<my-functional-component>
<p v-slot:foo>
first
</p>
<p>second</p>
</my-functional-component>
ãã®ã³ã³ãã¼ãã³ãã®å ´åã children
ã¯ä¸¡æ¹ã®ãã©ã°ã©ããä¸ãããã¾ããslots().default
㯠2 ã¤ç®ã®ãã®ã ãä¸ãããã¾ãããã㦠slots().foo
㯠1 ã¤ç®ã®ãã®ã ãã§ãããããã£ã¦ã children
㨠slots()
ã®ä¸¡æ¹ãæã¤ãã¨ã§ ãã®ã³ã³ãã¼ãã³ãã slot ã·ã¹ãã ãç¥ã£ã¦ãããããããã¯ãåç´ã« children
ã渡ãã¦ããããä»ã®ã³ã³ãã¼ãã³ãã¸ãã®è²¬ä»»ãå§è²ãããã©ãããé¸ã¹ãããã«ãªãã¾ãã
ãã³ãã¬ã¼ãã®ã³ã³ãã¤ã«
ããããã㨠Vue ã®ãã³ãã¬ã¼ããå®éã« render é¢æ°ã«ã³ã³ãã¤ã«ããããã¨ãç¥ããã¨ã«èå³ãæã¤ããããã¾ãããããã¯æ®æ®µããªãã¯ç¥ãå¿
è¦ããªãå®è£
ã®è©³ç´°ã§ãããã©ã®ããã«ç¹å®ã®ãã³ãã¬ã¼ãæ©è½ãã³ã³ãã¤ã«ãããããããè¦ãããªãããã«èå³ãæã¤ããããã¾ããã以ä¸ã¯ Vue.compile
ã使ã£ã¦ãã³ãã¬ã¼ãæååããã®å ´ã§ã³ã³ãã¤ã«ãããã¡ãã£ã¨ãããã¢ã§ãã