【老司机带你飞】vue.js基础入门教程(十一)

vue

组件

组件(Component)是vue.js" title="vue.js">vue.js最强大的功能之一。

组件可以扩展HTML元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用。

组件在vue脚手架开发中扮演着很重要的角色。

1) 注册全局组件

<div id="app">

<button-counter></button-counter>

</div>

<script>

Vue.component('button-counter',{

data:function(){

return {

count:0

}

},

template:"<button v-on:click='count++'>你敲击了{{count}}次</button>"

});

var app = new Vue({

el:"#app"

})

</script>

注意:

a. 组件的注册应该写在vue实例之前

b. Vue.component()中传入的第一个值是组件名称,第二个值是一个对象,是组件的选项参数

c. data选项必须是一个函数,目的是组件复用时组件数据的相互独立

d. 组件名称不要和原有的html标签名称相同,会产生冲突

e. 组件名称使用“component-name”和“componentName”(小驼峰)时,模板中调用组件都要写为:<component-name></component-name>

2)通过props选项,向子组件传递数据

<div id="app">

<blog-post title="博客标题"></blog-post>

</div>

<script>

Vue.component('blog-post',{

props:["title"],

template:"<h1>{{title}}</h1>"

});

var app = new Vue({

el:"#app"

})

</script>

在实际开发当中,data中可能存在多组博文数据,我们可以这样操作

<div id="app">

<blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:title="blog.title"></blog-post>

</div>

<script>

Vue.component('blog-post',{

props:["title"],

template:"<h1>{{title}}</h1>"

});

var app = new Vue({

el:"#app",

data:{

blogs:[

{id:1,title:"标题1"},

{id:2,title:"标题2"},

{id:3,title:"标题3"},

{id:4,title:"标题4"}

]

}

})

</script>

3)单个根元素

一般一个组件模板中都不止一个包含一个标签,此时我们需要把多个标签包含在一个根元素中,不然只会显示第一个元素内容。

<div id="app">

<blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:title="blog.title" v-bind:content="blog.content"></blog-post>

</div>

<script>

Vue.component('blog-post',{

props:["title","content"],

template:"<div>" +

"<h1>{{title}}</h1>" +

"<p>{{content}}</p>" +

"</div>"

});

var app = new Vue({

el:"#app",

data:{

blogs:[

{id:1,title:"标题1",content:"博文1"},

{id:2,title:"标题2",content:"博文2"},

{id:3,title:"标题3",content:"博文3"},

{id:4,title:"标题4",content:"博文4"}

]

}

})

</script>

如果博客数据中包含多个字段,我们可以考虑把整个的博客数据传入组件

<div id="app">

<blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:blog="blog"></blog-post>

</div>

<script>

Vue.component('blog-post',{

props:["blog"],

template:"<div>" +

"<h1>{{blog.title}}</h1>" +

"<p>{{blog.content}}</p>" +

"<p>{{blog.time}}</p>" +

"<p>{{blog.comment}}</p>" +

"</div>"

});

var app = new Vue({

el:"#app",

data:{

blogs:[

{id:1,title:"标题1",content:"博文1",time:"今天",comment:"评论1"},

{id:2,title:"标题2",content:"博文2",time:"今天",comment:"评论2"},

{id:3,title:"标题3",content:"博文3",time:"今天",comment:"评论3"},

{id:4,title:"标题4",content:"博文4",time:"今天",comment:"评论4"}

]

}

})

</script>

4)监听子组件事件

<div id="app">

<div v-bind:style="{fontSize:fontSize+'em'}">

<blog-post v-for="blog in blogs" v-bind:key="blog.id" v-bind:blog="blog" v-on:enlarge-text="fontSize+=0.1"></blog-post>

</div>

</div>

<script>

Vue.component('blog-post',{

props:["blog"],

template:"<div>" +

"<button v-on:click='$emit(\"enlarge-text\")'>放大字体</button>" +

"<h1>{{blog.title}}</h1>" +

"<p>{{blog.content}}</p>" +

"<p>{{blog.time}}</p>" +

"<p>{{blog.comment}}</p>" +

"</div>"

});

var app = new Vue({

el:"#app",

data:{

blogs:[

{id:1,title:"标题1",content:"博文1",time:"今天",comment:"评论1"},

{id:2,title:"标题2",content:"博文2",time:"今天",comment:"评论2"},

{id:3,title:"标题3",content:"博文3",time:"今天",comment:"评论3"},

{id:4,title:"标题4",content:"博文4",time:"今天",comment:"评论4"}

],

fontSize:1

}

})

</script>

a. 组件调用处绑定自定义事件

b. 组件模板内部绑定正常的vue事件,如:v-on:click,执行组件调用处的自定义事件,以此达到父组件监听子组件事件的目的

v-on:click可以放置一个方法名,在methods方法中使用$emit执行组件调用处的自定义事件

Vue.component('blog-post',{

props:["blog"],

template:"<div>" +

"<button v-on:click='enlargeText'>放大字体</button>" +

"<h1>{{blog.title}}</h1>" +

"<p>{{blog.content}}</p>" +

"<p>{{blog.time}}</p>" +

"<p>{{blog.comment}}</p>" +

"</div>",

methods:{

enlargeText:function () {

this.$emit('enlarge-text');

}

}

});

5)动态组件

在不同组件之间进行动态切换是非常有用的,如选项卡的操作,可以通过页面标签<component>绑定is属性来实现

<style>

.tab-button{

border: 0;

outline: none;

}

.active{

background: #999;

color: #ffffff;

}

#app div{

height: 200px;

border: 1px solid #cccccc;

}

</style>

<div id="app">

<button v-for="tab in tabs" v-bind:class="['tab-button',{active:currentTab===tab.menuCode}]" v-on:click="currentTab=tab.menuCode">{{tab.menuName}}</button>

<component v-bind:is="currentTabComponent"></component>

</div>

<script>

Vue.component('tab-home',{

template:'<div>首页组件</div>'

});

Vue.component('tab-about',{

template:'<div>关于我们组件</div>'

});

Vue.component('tab-contact',{

template:'<div>联系我们组件</div>'

});

var app = new Vue({

el:"#app",

data:{

currentTab:'home',

tabs:[

{

menuCode:'home',

menuName:'首页'

},

{

menuCode:'about',

menuName:'关于我们'

},

{

menuCode:'contact',

menuName:'联系我们'

}

]

},

computed:{

currentTabComponent:function () {

return 'tab-'+this.currentTab;

}

}

})

</script>

最终实现:

6)在动态组件上使用keep-alive

将动态组件放入到keep-alive标签中,可以使组件中切换状态保持住

<style>

.tab-button{

border: 0;

outline: none;

}

.active{

background: #999;

color: #ffffff;

}

#app div{

height: 200px;

border: 1px solid #cccccc;

}

.navli{

list-style: none;

cursor: pointer;

}

.navactive{

background: #999999;

color: #ffffff;

}

.nav-ul{

width:20%;

float: left;

}

.navComponent{

width: 70%;

float: left;

}

</style>

<div id="app">

<button v-for="tab in tabs" v-bind:class="['tab-button',{active:currentTab===tab.menuCode}]" v-on:click="currentTab=tab.menuCode">{{tab.menuName}}</button>

<keep-alive>

<component v-bind:is="currentTabComponent"></component>

</keep-alive>

</div>

<script>

Vue.component('tab-home',{

data:function(){

return {

currentNav:"nav1",

navs:[

{

navCode:"nav1",

navName:"导航1"

},

{

navCode:"nav2",

navName:"导航2"

},

{

navCode:"nav3",

navName:"导航3"

}

]

}

},

template:'<div>' +

'<ul class="nav-ul">' +

'<li v-for="nav in navs" v-bind:class="[\'navli\',{navactive:currentNav===nav.navCode}]" v-on:click="currentNav=nav.navCode">{{nav.navName}}</li>' +

'</ul>' +

'<component v-bind:is="currentNavComponent" class="navComponent"></component>'+

'</div>',

computed: {

currentNavComponent: function () {

return this.currentNav;

}

}

});

Vue.component('nav1',{

template:'<div>导航1内容</div>'

});

Vue.component('nav2',{

template:'<div>导航2内容</div>'

});

Vue.component('nav3',{

template:'<div>导航3内容</div>'

});

Vue.component('tab-about',{

template:'<div>关于我们组件</div>'

});

Vue.component('tab-contact',{

template:'<div>联系我们组件</div>'

});

var app = new Vue({

el:"#app",

data:{

currentTab:'home',

tabs:[

{

menuCode:'home',

menuName:'首页'

},

{

menuCode:'about',

menuName:'关于我们'

},

{

menuCode:'contact',

menuName:'联系我们'

}

]

},

computed:{

currentTabComponent:function () {

return 'tab-'+this.currentTab;

}

}

})

</script>


7)注册局部组件

全局组件很容易产生不被用到的组件资源浪费,此时会用到局部组件注册(在脚手架环境下体现更明显)

<div id="app">

<component-a></component-a>

<component-b></component-b>

</div>

<script>

var componentA = {

template:"<h1>局部组件A</h1>"

}

var componentB = {

template:"<h1>局部组件B</h1>"

}

var app = new Vue({

el:"#app",

components:{

'component-a':componentA,

'component-b':componentB

}

})

</script>

——易动学院毕老师

QQ:732005030

扫码加微信

以上是 【老司机带你飞】vue.js基础入门教程(十一) 的全部内容, 来源链接: utcz.com/z/375385.html

回到顶部