视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Vuejs 页面的区域化与组件封装的实现
2020-11-27 22:30:40 责编:小采
文档

组件的好处

当我用vue写页面的时候,大量的数据页面渲染,引入组件简化主页面的代码量,当代码区域块代码差不多相同时,组件封装会更加简化代码。组件是Vue.js最强大的功能之一。

组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展。

我用一个读书软件的图书列表例子:

图书展示页 大家可以想想用vue如何实现这个页面的前端页面实现,再来实现逻辑功能;

图片显示的 '推荐图书' 和 '最新图书' 的列表展示是一样的,开始可以用重复的代码把先写好的 '推荐图书' 的代码复制一份就可以轻轻松松实现 '最新图书' 页面

如果其他页面也需要这个展示,或我想代码更加简洁一点,那么来组件如何封装就派上场啦

简要页面:图书列表展示页 - 图书列表组件

|- book.vue // 图书展示页面
 |-- BookList.vue // 图书列列表组件

基础部分相信使用过vue的伙计都知道如何使用,我直接上代码:

创建一个组件 - 注册组件 - 使用组件

// 引入组件
import BookList from '../../components/bookList/BookList.vue';

// 注册组件
components:{
 BookList,
},

// 使用组件
<book-list></book-list>

vue2.0 规定引入组件建议使用驼峰命名,使用时用 - 分开,vue才更好识别

之前没封封装组件的代码就不上传了,直接上代码:

图书列表页 - book.vue

|- book.vue - html 页面
 <template> 
 <div>
 <h2>欢迎来到波波图书馆!</h2>
 
 <!-- 推荐读书 -->
 <section class="box recommend-book">
 <!-- 大家注意 :books 是BookList.vue组件里图书对象数组 heading 是传给组件的标题 -->
 <book-list :books="recommendArray" heading="推荐图书"></book-list>
 </section>

 <!-- 最新图书 -->
 <section class="box update-book">
 <!-- 大家注意 :books 是BookList.vue组件里图书对象数组 heading 是传给组件的标题 -->
 <book-list :books="updateBookArray" heading="最新图书"></book-list>
 </section>

 </div>
 </template>

我是模拟数据,开发过程中是用api接口拿数据的,其实都一样,代码有点多,原理都一样,大家看一下也可以了解一下json的知识

|- book.vue - js 
<script>
 import BookList from '../../components/bookList/BookList.vue';
 export default({
 data(){
 return {

 // 推荐图书
 recommendArray:[
 {
 id:1,
 img_url: 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=671627465,1455045194&fm=173&s=23A2F3039C930EC41A2DB9090300D093&w=0&h=427&img.JPEG',
 book_name:'Vuejs-1',
 book_author:'liangfengbo',
 },

 {
 id:2,
 img_url: 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=671627465,1455045194&fm=173&s=23A2F3039C930EC41A2DB9090300D093&w=0&h=427&img.JPEG',
 book_name:'Vuejs-2',
 book_author:'liangfengbo',

 },

 {
 id:3,
 img_url: 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=671627465,1455045194&fm=173&s=23A2F3039C930EC41A2DB9090300D093&w=0&h=427&img.JPEG',
 book_name:'Vuejs-3',
 book_author:'liangfengbo',

 },
 ],

 // 最新图书
 updateBookArray:[
 {
 id:5,
 img_url: 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=671627465,1455045194&fm=173&s=23A2F3039C930EC41A2DB9090300D093&w=0&h=427&img.JPEG',
 book_name:'Vuejs-5',
 book_author:'liangfengbo',

 },

 {
 id:6,
 img_url: 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=671627465,1455045194&fm=173&s=23A2F3039C930EC41A2DB9090300D093&w=0&h=427&img.JPEG',
 book_name:'Vuejs-6',
 book_author:'liangfengbo',

 },
 {
 id:7,
 img_url: 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=671627465,1455045194&fm=173&s=23A2F3039C930EC41A2DB9090300D093&w=0&h=427&img.JPEG',
 book_name:'Vuejs-7',
 book_author:'liangfengbo',

 },
 ],
 }
 },

 // 引入组件
 components:{
 BookList,
 },

 methods : {
 
 },
 })
</script>

|- book.vue - css
<style>
 *{
 margin: 0;
 padding: 0;
 }
 li{
 list-style:none;
 }
 .box{
 height: auto;
 border-bottom: 1px solid #efefef;
 margin: 10px 0;
 padding: 5px 0;
 }
</style> 

组件 - BookList.vue

|- 组件 - BookList.vue - html
<template>
 <div>
 <!-- 头部 -->
 <!--这个是页面传来的标题 -->
 <h3 class="heading">{{heading}}</h3>
 <!-- 列表 -->
 <article class="book-list">
 <!-- 遍历图书数据 -->
 <li v-for="book in books">

 <router-link :to="{ name:'BookDetail',params:{ id: book.id }}">
 ![](book.img_url) <!-- 图书图片 -->
 {{book.book_name}} <!-- 图书名字 -->
 </router-link>

 </li> 
 </article>
 </div>
</template>

|- 组件 - BookList.vue - html

<script>
 export default({
 // props 数据传递的意思
 props:[
 'heading',//标题
 'books',//图书对象数组
 ],
 data(){
 return {
 
 }
 },
 methods : {
 
 },
 })
</script>

|- 组件 - BookList.vue - css

<style scoped>
 /*图书列表*/
 .book-list {
 width:100%;
 height:128px;
 display: flex;
 justify-content: space-around;
 }
 .heading {
 border-left: 4px solid #333;
 margin: 10px 0;
 padding-left: 4px;
 }
 .book-list li {
 width:80px;
 height: 100%;
 flex:1;
 margin:0 10px;

 }

 .book-list li img{
 height: 100px;
 width: 100%;
 }
 .book-list li a{
 text-align: center;
 font-size: 12px;
 text-decoration: none;
 display: inline-block;
 width: 100%;
 }
</style>

全部的代码就在这里啦,大家可以细心发现,组件封装,其实就向我们之前JavaScript函数封装一样,传递参数,接收参数,渲染数据,重复利用,大家可以直接运行看一下,注释有解释啦。

小干货

父组件 调用 子组件 方法为 :

在子组件上写上名字 如:

<start-set-timeout seconds=60 ref="contTimer"></start-set-timeout>

调用方法:this.$refs.contTimer.countTime(60)

但是

因为有数据的延迟 经常会出现调用子组件的事件出现undefined的事情:

TypeError: Cannot read property 'countTime' of undefined

解决方法是

// 调用时加一个定时器
setTimeout(() => {
 this.$refs.contTimer.countTime(60)
}, 20)

下载本文
显示全文
专题