vue组件(全局注册、局部注册、prop传值)
vue组件使用
1、认识组件
(1) 创建组件的写法
写法: Vue.component("组件名",{ //xx });
//这里是全局注册组件的写法Vue.component()函数的第一个参数就是组件名
,
比如Vue.component(“my-comname”,{ //xx}}); 那么my-comname就是新建组件的名称;
(2)注意:
- 为了能在模板中使用,这些组件必须先注册以便 Vue能够识别;
- 当直接在DOM中使用一个组件(而不是在字符串模板或单文件组件)的时候,建议遵循W3C规范中的自定义组件名(字母全部小写且必须包含一个连字符),避免和当前以及以后的HTML元素相冲突。
- 有两种组件的注册类型:
全局注册
和局部注册
。
我们的组件都是通过 Vue.component 全局注册的。
全局注册的组件可以用在它被注册之后的任何(通过new Vue)新创建的Vue根实例,
也包括其组件树中的所有子组件的模板中。 - 组件是可复用的 Vue 实例,且带有一个名字。
(3)定义组件名的方式:
-
使用 kebab-case
写法:Vue.component('my-component-name', { //xx })
当使用 kebab-case (短横线分隔命名) 定义一个组件时,在引用这个自定义元素时也必须使用kebab-case,比如。 -
使用 PascalCase
写法:Vue.component('MyComponentName', { //xx })
当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。即 和 都可以。
注意:直接在DOM(即非字符串的模板)中使用时只有kebab-case是有效的。
<div id="app">
<button-counter></button-counter>
<hr>
<div id="dv" style="width:200px;height:200px;background-color:lightblue;">
<button-counter>我是#dv下的组件</button-counter>
</div>
</div>
<script src="js/vue.js"></script>
<script>
// 创建组件button-counter
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">你点了{{count}}次</button>'
});
/* 本例的组件名字是<button-counter>。我们可以在一个通过new Vue创建的Vue根实例中,
把这个组件作为自定义元素来使用。 */
new Vue({
el: '#app'
});
</script>
2、组件复用
组件的复用:组件可进行任意次数的使用
。
注意:
-
每一个组件的data,必须是一个函数;
-
每用一次组件, 就会有一个它的新实例被创建,组件之间不会相互影响。
如下的示例中,当点击按钮时, 每个组件都会控制各自的count(点击次数)。
<div id="id">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script src="js/vue.js"></script>
<script>
Vue.component("button-counter", {
// 我们定义<button-counter>组件时,它的data并不是如下面这样直接提供一个对象
// data:{
// count:0
// },
// 而是如下这样,一个组件的data选项必须是一个函数
data: function () {
return {
count: 0
}
},
template:`<button @click="count++">点击{{count}}次</button>`
});
let app = new Vue({
el: "#app"
});
</script>
3、全局注册组件
组件在注册之后可以用在任何新创建的Vue根实例(new Vue) 的模板中。
在所有子组件中也是如此,即这三个子组件在各自内部也都可以相互使用。
<style>
#poemList,#songpoemList,#yuanoperaList{
width: 300px;
height: 200px;
text-align: center;
line-height: 30px;
}
span{
display: block;
}
.poemName,.songpoemName,.yuanoperaName{
width: 100%;
}
.poemContent{
width: 200px;
margin-left: 50px;
}
</style>
<div id="app">
<mycomponet-a></mycomponent-a>
<mycomponent-b></mycomponent-b>
<mycomponent-c></mycomponent-c>
</div>
<script src="js/vue.js"></script>
<script>
Vue.component('mycomponent-a', {
data: function () {
return {
poem_title: "唐诗",
poem_name: "《静夜思》- 李白",
poem_content: "床前明月光,疑是地上霜。举头望明月,低头思故乡。"
}
},
template: `<div id="poemList"><h2>{{poem_title}}</h2><span class="poemName">{{poem_name}}</span><span class="poemContent">{{poem_content}}</span></div>`
});
Vue.component('mycomponent-b', {
data: function () {
return {
songpoem_title: "宋词",
songpoem_name:"《虞美人》- 李煜",
songpoem_content:"春花秋月何时了,往事知多少?小楼昨夜又东风,故国不堪回首月明!雕栏玉砌应犹在,只是朱颜改。问君能有几多愁?恰似一江春水向东流。"
}
},
template: `<div id="songpoemList"><h2>{{songpoem_title}}</h2><span class="songpoemName">{{songpoem_name}}</span><span class="songpoemContent">{{songpoem_content}}</span></div>`
});
Vue.component('mycomponent-c', {
data: function () {
return {
yuanopera_title: "元曲",
yuanopera_name:"《天净沙-秋思》- 马致远",
yuanopera_content:"枯藤老树昏鸦,小桥流水人家,古道西风瘦马。夕阳西下,断肠人在天涯。"
}
},
template: `<div id="yuanoperaList"><h2>{{yuanopera_title}}</h2><span class="yuanoperaName">{{yuanopera_name}}</span><span class="yuanoperaContent">{{yuanopera_content}}</span></div>`
});
new Vue({
el: '#app',
})
</script>
4、局部注册组件
全局注册往往是不够理想的。比如,你使用一个像webpack打包项目。
如果是全局注册所有的组件, 那么当你不需要使用某个或某些组件时,
它仍然会包含在你最终的包中。会造成了用户下载不必要的js。
这就需要我们注册局部组件。对于components 对象中的每个属性来说,其属性名就是自定义元素的名字
,其属性值就是这个组件的选项对象
。
<div id="app">
<localcom-a message="我是局部组件"></localcom-a>
<localcom-b message="我是局部组件的兄弟"></localcom-b>
<localcom-c message="上面是我大哥和二哥"></localcom-c>
</div>
<hr>
<div id="app2">
<mycom-x info="新组件"></mycom-x>
<mycom-y info="我也是新组件"></mycom-y>
</div>
<script src="js/vue.js"></script>
<script>
//由于前面说的全局注册组件带来的问题,我们可以通过一个普通的js对象来定义组件,如下:
var ComponentA = {
props: ["message"],
template: `<div id="dv1"><h1>{{message}}</h1><input type='text' v-model='message'></input></div>`
}
var ComponentB = {
props: ["message"],
template: `<div><h1>{{message}}</h1><input type='text' v-model='message'></input></div>`
}
var ComponentC = {
props: ["message"],
template: `<div><h1>{{message}}</h1><input type='text' v-model='message'></input></div>`
}
// 然后在 components 选项中定义你想要使用的组件:
let app = new Vue({
el: '#app',
components: {
'localcom-a': ComponentA,
'localcom-b': ComponentB,
'localcom-c': ComponentC
}
})
console.log(app);
// 注意:局部注册的组件在其子组件中不可用。
// 比如,你想组件a可以在组件中可用,如下写法:
var myComX = {
props: ["info"],
template: `<div><h1>{{info}}</h1><input type='text' v-model='info'></input></div>`
}
var myComY = {
components: {
'mycom-x': myComX
}
}
let app2 = new Vue({
el: "#app2",
components: {
'mycom-x': myComX,
'mycom-y': myComX
}
});
console.log(app2);
// 或者如果你通过 Babel 和 webpack使用ES2015模块,如下:
// import ComponentA from './ComponentA.vue'
// export default {
// components: {
// ComponentA
// },
// // ...
// }
/*注意
在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:
用在模板中的自定义元素的名称
包含了这个组件选项的变量名
*/
</script>
5、prop传值
Prop可以在组件上注册的一些自定义的attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个属性
。
为了给组件传递一个标题,我们可以用一个props选项将其包含在该组件可接受的prop列表中.一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
在上例中,我们能够在组件的实例中访问这个值,就像访问 data 中的值一样。
<!-- 一个prop被注册之后,可以把数据作为一个自定义的attribute传递进来 -->
<div id="app">
<!-- <article-post title="学习Vue指令"></article-post>
<article-post title="学习Vue事件"></article-post>
<article-post title="学习Vue组件"></article-post> -->
<article-post v-for="article in articles" :key="article.id"
v-bind:title="article.title"></article-post>
</div>
<script src="js/vue.js"></script>
<script>
Vue.component('article-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
});
let app = new Vue({
el: "#app",
data: {
articles: [{
id: 1,
title: '学习Vue指令'
},
{
id: 2,
title: '学习Vue事件'
},
{
id: 3,
title: '学习Vue组件'
}
]
}
});
</script>