本文参考自官方文档,并加入自己的理解和例子
两种组件的注册类型:全局注册和局部注册。
全局注册基本示例
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: ''
})
组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 ``。我们可以在一个通过 new Vue
创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
<div id="app">
<button-counter>button-counter>
div>
new Vue({ el: '#app' })
因为组件是可复用的 Vue 实例,所以它们与 new Vue
接收相同的选项,例如 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。
data
必须是一个函数
局部注册定义在components属性内,在父组件的template使用
components: {
navBarChild:{
template:'Child!!
'
}
}
通过 Prop 向子组件传递数据
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。能够在组件实例中访问这个值,就像访问 data
中的值一样。
Vue.component('blog-post', {
props: ['title'],
template: '{
{ title }}
'
})
一个 prop 被注册之后,你就可以像这样把数据作为一个自定义 attribute 传递进来:
<blog-post title="My journey with Vue">blog-post>
可以使用 v-bind
来动态传递 prop
<blog-post :title="某定义在data中的变量">blog-post>
每个组件必须只有一个根元素
监听子组件事件
父级组件可以像处理 native DOM 事件一样通过 v-on
监听子组件实例的任意事件
<blog-post
...
@enlarge-text="postFontSize += 0.1"
>blog-post>
同时子组件可以通过调用内建的 $emit
方法并传入事件名称来触发一个事件enlarge-text
<button @click="$emit('enlarge-text')">
Enlarge text
button>
使用事件抛出一个值
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
button>
然后当在父级组件监听这个事件的时候,我们可以通过 $event
访问到被抛出的这个值:
<blog-post
...
v-on:enlarge-text="postFontSize += $event"
>blog-post>
或者,如果这个事件处理函数是一个方法:
<blog-post
...
v-on:enlarge-text="onEnlargeText"
>blog-post>
那么这个值将会作为第一个参数传入这个方法:
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
父子相互传参案例,画图加深理解

props属性验证:
Number,String,Boolean,Array,Object,Function,null(不限制)
html
<div id="app" :style="{
fontSize:postFontSize+'em'}">
<button-counter :title="a">button-counter>
文章内容
<button-enlarge @enlarge-text='enlargeFun'>button-enlarge>
div>
js
Vue.component('button-counter', {
props: {
title:String,},
data: function () {
return {
count: 0
}
},
template:''})
Vue.component('button-enlarge',{
data:function(){
return {
size:0
}
},
template:``
})
new Vue({
el: '#app',
data: {
a:1,
postFontSize:1
},
methods:{
enlargeFun:function(size){
this.postFontSize +=size
}
}
})
v-model
的内在奥秘
<input v-model="myText">{
{myText}}
上下效果相同
<input :value="myText" @input="myText = $event.target.value">{
{myText}}
<input v-model.lazy="myTextLazy">{
{myTextLazy}}
上下效果相同
<input :value="myTextLazy" @change="myTextLazy = $event.target.value">{
{myTextLazy}}
当用在组件上时,v-model
则会这样:
Vue.component('model-input',{
props:['value'],
template:`{
{value}}
`
})
父组件调用
<model-input :value="myText" @input="myText=$event">model-input>{
{myText}}
一个组件上的 v-model
默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:
model: {
prop: 'checked',
event: 'change'
},
slot插槽
通过插槽分发内容,和 HTML 元素一样,我们经常需要向一个组件传递内容,像这样:
<nav-bar>
<button slot="btn">触发button>
<div slot="div">aaaadiv>
nav-bar>
可以利用Vue 自定义的 <slot> 元素,进行插入内容
Vue.component('navBar', {
template: `
navBar
`
})

可以指定slot的名字,进行指定插槽
例如:
<nav-bar>
<button slot="btn">触发button>
<div slot="div">aaaadiv>
nav-bar>
Vue.component('navBar', {
template: `
navBar
`
})

## 动态组件
在不同组件之间进行动态切换是非常有用的
上述内容可以通过 Vue 的` `元素加一个特殊的 is attribute 来实现:
```html
在上述示例中,currentTabComponent 可以包括
请留意,这个 attribute 可以用于常规 HTML 元素,但这些元素将被视为组件,这意味着所有的 attribute 都会作为 DOM attribute 被绑定。对于像 value 这样的 property,若想让其如预期般工作,你需要使用 .prop 修饰器。
下面例子,参考自:https://www.cnblogs.com/xiaohuochai/p/7395694.html
让多个组件使用同一个挂载点,并动态切换,这就是动态组件。
两种写法:
- 通过使用保留的
元素,动态地绑定到它的 is 特性,可以实现动态组件
<div id="example">
<button @click="change">切换页面button>
<component :is="currentView">component>
div>
<script>
var home = {
template:'我是主页
'};
var post = {
template:'我是提交页
'};
var archive = {
template:'我是存档页
'};
new Vue({
el: '#example',
components: {
home,
post,
archive,
},
data:{
index:0,
arr:['home','post','archive'],
},
computed:{
currentView(){
return this.arr[this.index];
}
},
methods:{
change(){
this.index = (++this.index)%3;
}
}
})
script>
- 也可以直接绑定到组件对象上
<div id="example">
<button @click="change">切换页面button>
<component :is="currentView">component>
div>
<script>
new Vue({
el: '#example',
data:{
index:0,
arr:[
{
template:`我是主页
`},
{
template:`我是提交页
`},
{
template:`我是存档页
`}
],
},
computed:{
currentView(){
return this.arr[this.index];
}
},
methods:{
change(){
this.index = (++this.index)%3;
}
}
})
script>
注意:动态组件,切换的时候是删掉原来组件,而不是隐藏,要保持原来的状态,避免重新渲染,用keep-alive包裹
<keep-alive>
<component :is="who">component>
keep-alive>
解析 DOM 模板时的注意事项
有些 HTML 元素,诸如 、、 和