component创建的组件可以当作自定义元素使用,并且有组件的相应功能
- 因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,
例如 data、computed、watch、methods 以及生命周期钩子等。
仅有的例外是像 el 这样根实例特有的选项。 - 组件的data必须是一个函数,这样写。所有组件都是互不影响的
</div>
<div id="id1">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script>
Vue.component('button-counter',{
data:function () {
return {
count:0
}
},
template:'<button v-on:click="count++">{{count}}</button>'
});
new Vue({
el:'#id1',
});
</script>
<!--如果是这样写的话,所有组件的count都是一样的-->
<div id="id2">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script>
var returnData = {
count:0
};
Vue.component('button-counter',{
data:function () {
return returnData;
},
template:'<button v-on:click="count++">{{count}}</button>'
});
new Vue({
el:'#id2',
});
</script>
通过 Prop 向子组件传递数据
<!--方式1:直接在组件中。这样页面会将组件对应值替换
结果:<h3 id="id3">My journey with Vue</h3>
-->
<blog-post id="id3" title="My journey with Vue"></blog-post>
<script>
Vue.component('blog-post',{
props:['title'],
template:'<h3 >{{title}}</h3>'
});
new Vue({
el:'#id3',
});
</script>
<!--方式二:通过Vue对象中传值,注意key这个属性不会在页面源码上显示出来
结果:
<div id="id4">
<h3 id="1">My journey with Vue</h3>
<h3 id="2">Blogging with Vue</h3>
<h3 id="3">Why Vue is so fun</h3>
</div>
-->
<div id="id4">
<blog-post2 v-for="post in posts" v-bind:id="post.id" v-bind:key="post.id" v-bind:title="post.title"></blog-post2>
</div>
<script>
Vue.component('blog-post2',{
props:['title'],
template:'<h3>{{title}}</h3>'
});
new Vue({
el: '#id4',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
});
</script>
注意这里进行了 v-bind:post=“post”,这样才能在template中使用这个对象
<!--其中一个页面结果是,注意看生成的id的位置:
<div id="1"><h3>My journey with Vue</h3> <div>1111</div></div>
-->
<div id="id5">
<blog-post v-for="post in posts" v-bind:id="post.id" v-bind:key="post.id" v-bind:post="post"></blog-post>
</div>
<script>
Vue.component('blog-post',{
props:['post'],
template:' <div>\n' +
' <h3>{{ post.title }}</h3>\n' +
' <div v-html="post.content"></div>\n' +
' </div>',
});
new Vue({
el:'#id5',
data:{
posts: [
{ id: 1, title: 'My journey with Vue',content:'1111'},
{ id: 2, title: 'Blogging with Vue' ,content:'2222'},
{ id: 3, title: 'Why Vue is so fun' ,content:'3333'}
]
}
});
</script>
<!-- 效果:点击按钮增加div的字体大小
首先添加了一个v-on:enlarge-text="postFontSize += 0.1"
然后通过 v-on:click=$emit('enlarge-text')调用对应的方法
-->
<div id="id6">
<div :style="{fontSize : postFontSize1 + 'em'}">
<blog-post v-on:enlarge-text="postFontSize1 += 0.1" v-for="post in posts" v-bind:post="post" v-bind:key="post.id"> </blog-post>
</div>
<!-- 同时$emit('enlarge-text',0.2) 第二个参数也可以通过$event获取。第二个div每次+0.2-->
<div :style="{fontSize : postFontSize2 + 'em'}">
<blog-post v-on:enlarge-text="postFontSize2 += $event" v-for="post in posts" v-bind:post="post" v-bind:key="post.id"> </blog-post>
</div>
<!-- 同时还可以通过函数的方式 -->
<div :style="{fontSize : postFontSize3 + 'em'}">
<blog-post v-on:enlarge-text="onEnlargeText" v-for="post in posts" v-bind:post="post" v-bind:key="post.id"> </blog-post>
</div>
</div>
<script>
Vue.component('blog-post',{
props:['post'],
template:'<div><h3>{{post.title}}</h3>' +
'<button v-on:click="$emit(\'enlarge-text\',0.2)">enlarge text</button>' +
'<div v-html="post.content"></div></div>'
});
new Vue({
el: '#id6',
data: {
posts: [
{ id: 1, title: 'My journey with Vue',content:'1111'},
],
postFontSize1: 1,
postFontSize2: 1,
postFontSize3: 1,
},
methods:{
onEnlargeText: function (arg) {
this.postFontSize3 += arg;
}
}
});
</script>
组件使用v-model
<!--
<custom-input v-model="searchText"></custom-input>
实际是
<custom-input :value="searchText" @input="searchText = $event" ></custom-input>
-->
<div id="id7">
<custom-input v-model="searchText"></custom-input>
<span>{{searchText}}</span>
</div>
<script>
Vue.component('custom-input',{
props:['value'],
template:' <input\n' +
' v-bind:value="value"\n' +
' v-on:input="$emit(\'input\', $event.target.value)"\n' +
' >',
});
new Vue({
el:'#id7',
data:{
searchText:0,
}
});
</script>
通过插槽分发内容
<!--
<slot></slot>代表对应的'omething bad happened.'
结果:
<div id="id8"><strong>Error!</strong>
Something bad happened.
</div>
-->
<alert-box id="id8">
Something bad happened.
</alert-box>
<script>
Vue.component('alert-box', {
template: `
<div>
<strong>Error!</strong>
<slot></slot>
</div>
`
});
new Vue({
el:'#id8',
})
</script>
动态组件
<!--
效果点击切换页面会一直切换不同的组件
这里用到了:is 可以认为:is=对应的组件名称
-->
<div id="id9">
<button @click="change">切换页面</button>
<component v-bind:is="currentTabComponent"></component>
</div>
<script>
Vue.component('tab-home', { template: '<div>Home component</div>' });
Vue.component('tab-posts', { template: '<div>Posts component</div>' });
Vue.component('tab-archive', { template: '<div>Archive component</div>' });
new Vue({
el: '#id9',
data: {
currentTab: 'Home',
index :0,
tabs: ['Home', 'Posts', 'Archive']
},
computed: {
currentTabComponent: function () {
return 'tab-' + this.currentTab.toLowerCase()
}
},
methods: {
change:function () {
this.index ++;
if (this.index >= 3) {
this.index = 0;
}
this.currentTab = this.tabs[this.index];
}
}
})
</script>