1.入门
<div id="example">
<my-component></my-component>
</div>
// register 全局
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
// create a root instance
new Vue({
el: '#example'
})
结果
<div id="example">
<div>A custom component!</div>
</div>
局部组件
var Child = {
template: '<div>A custom component!</div>'
}
new Vue({
// ...
components: {
// <my-component> will only be available in parent's template
'my-component': Child
}
})
2.陷阱
<ul>, <ol>, <table> and <select>
会有问题,会报错。应该用is
<table>
<tr is="my-row"></tr>
</table>
以下三种不起作用
(1)<script type="text/x-template">
(2)JavaScript inline template strings
(3).vue components
3.data必须是function
<div id="example-2">
<simple-counter></simple-counter>
<simple-counter></simple-counter>
<simple-counter></simple-counter>
</div>
var data = { counter: 0 }
Vue.component('simple-counter', {
template: '<button v-on:click="counter += 1">{{ counter }}</button>',
// data is technically a function, so Vue won't
// complain, but we return the same object
// reference for each component instance
data: function () {
return {
counter: 0
}
}
})
new Vue({
el: '#example-2'
})
Paste_Image.png
4.父子组件 props
props down, events up. 父组件传递 data down to the child 通过 props, child sends messages to the parent via events.
Paste_Image.png(1)props传值
Vue.component('child', {
// declare the props
props: ['message'],
// just like data, the prop can be used inside templates
// and is also made available in the vm as this.message
template: '<span>{{ message }}</span>'
})
<child message="hello!"></child>
(2)动态 props
<div>
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
//简写形式
<child :my-message="parentMsg"></child>
<comp v-bind:some-prop="1"></comp>
传递的是数字1,非字符串
(3)Prop Validation
Vue.component('example', {
props: {
// basic type check (`null` means accept any type)
propA: Number,
// multiple possible types
propB: [String, Number],
// a required string
propC: {
type: String,
required: true
},
// a number with default value
propD: {
type: Number,
default: 100
},
// object/array defaults should be returned from a
// factory function
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// custom validator function
propF: {
validator: function (value) {
return value > 10
}
}
}
})
当检查失败,会给个warining,type选项
String
Number
Boolean
Function
Object
Array
4.父子组件 event
父组件可以监听子组件的事件
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
Vue.component('button-counter', {
template: '<button v-on:click="increment">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
increment: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
Paste_Image.png
如果是原生事件+.native
<my-component v-on:click.native="doTheThing"></my-component>
**5.v-model 用于组件
<input v-model="something">
等价于
<input v-bind:value="something" v-on:input="something = $event.target.value">
//条件
accept a value prop
emit an input event with the new value
<div id="v-model-example">
<p>{{ message }}</p>
<my-input
label="Message"
v-model="message"
></my-input>
</div>
Vue.component('my-input', {
template: '\
<div class="form-group">\
<label v-bind:for="randomId">{{ label }}:</label>\
<input v-bind:id="randomId" v-bind:value="value" v-on:input="onInput">\
</div>\
',
//1.必须有value
props: ['value', 'label'],
data: function () {
return {
randomId: 'input-' + Math.random()
}
},
methods: {
onInput: function (event) {
//2.必须触发input
this.$emit('input', event.target.value)
}
},
})
new Vue({
el: '#v-model-example',
data: {
message: 'hello'
}
})
Paste_Image.png
6.不是父子组件的交流
创建空的Vue对象
var bus = new Vue()
// in component A's method
bus.$emit('id-selected', 1)
// in component B's created hook
bus.$on('id-selected', function (id) {
// ...
})
7.Single slot
父组件的内容会被删除,除非子组件中有多余一个的slot标签
Suppose we have a component called my-component with the following template:
<div>
<h2>I'm the child title</h2>
<slot>
This will only be displayed if there is no content
to be distributed.
</slot>
</div>
And a parent that uses the component:
<div>
<h1>I'm the parent title</h1>
<my-component>
<p>This is some original content</p>
<p>This is some more original content</p>
</my-component>
</div>
The rendered result will be:
<div>
<h1>I'm the parent title</h1>
<div>
<h2>I'm the child title</h2>
<p>This is some original content</p>
<p>This is some more original content</p>
</div>
</div>
8.Name slot
For example, suppose we have an app-layout component with the following template:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
Parent markup:
<app-layout>
<h1 slot="header">Here might be a page title</h1>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<p slot="footer">Here's some contact info</p>
</app-layout>
The rendered result will be:
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
9.动态组件
<component>元素绑定is属性
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
<component v-bind:is="currentView">
<!-- component changes when vm.currentView changes! -->
</component>
If you prefer, you can also bind directly to component objects:
var Home = {
template: '<p>Welcome home!</p>'
}
var vm = new Vue({
el: '#example',
data: {
currentView: Home
}
})
如果要缓存所有组件
<keep-alive>
<component :is="currentView">
<!-- inactive components will be cached! -->
</component>
</keep-alive>
10.简写形式
<my-component
:foo="baz" //v-bind
:bar="qux"
@event-a="doThis" //v-on
@event-b="doThat"
>
<img slot="icon" src="...">
<p slot="main-text">Hello!</p>
</my-component>
11.获取子组件的引用ref
<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({ el: '#parent' })
// access child component instance
var child = parent.$refs.profile
12.X-template
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})
网友评论