本文主要分享关于组件化开发的理解,让刚入门的小伙伴少走一些弯路,提升开发效率,做者本人也是新手,若有不当之处,请大佬指出,感谢。javascript
相信不少刚入门的小伙伴,常常会写不少重复的代码,而这些代码通常状况下也都是大同小异,在这种状况下,如何让开发和学习变得更加高效,组件化的思想就显得尤其重要。这里经过设计一个简单的弹出框,给小伙伴们分享组件化的应用。css
组件化是对某些能够进行复用的功能进行封装的标准化工做。组件通常会内含自身的内部UI元素、样式和JS逻辑代码,它能够很方便的在应用的任何地方进行快速的嵌入。组件内部可使用其余组件来构成更复杂的组件。vue
在实际的开发中,咱们应该避免去编写重复的代码,将精力放在更加核心的部分,所以就须要将这些重复的代码抽取出来,封装成公共的组件,提升开发效率,但同时也要注意组件的健壮性和可复用性,让它可以尽量适应更多的场景。java
首先是弹出框的基本结构node
<div class="modal">
<div class="mask"></div>
<div class="modal-dialog">
<div class="modal-header">
<span>标题</span>
<a href="javascript:;" class="icon-close"></a>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<a href="javascript:;" class="btn">肯定</a>
<a href="javascript:;" class="btn btn-default">取消</a>
</div>
</div>
</div>
</div>
复制代码
基本结构很简单,稍微注意一点的就是slot
插槽,若是没有提供name属性,它将有一个隐含的名字default,而且在父组件若是没有指定slot
的v-slot
属性的话,内容会传给default插槽。css3
在这里定义了slot
的name属性body
,这种的叫作具名插槽,会匹配v-slot:body
的内容。git
注意,在父组件中调用须要用<template>
包裹,而且<template>
元素中的全部内容都将被传入相应的插槽。github
给弹出框加点样式sass
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000000;
opacity: 0.5;
}
.modal-dialog {
position: absolute;
top: 40%;
left: 50%;
width: 560px;
height: auto;
background-color: #ffffff;
transform: translate(-50%, -50%);
.modal-header {
height: 60px;
background-color: #F5F5F5;
padding: 0 25px;
line-height: 60px;
font-size: 16px;
.icon-close {
position: absolute;
top: 23px;
right: 25px;
width: 14px;
height: 14px;
background: url("/static/img/icon-close.png") no-repeat center;
background-size: contain;
}
}
.modal-body {
padding: 42px 40px 54px;
font-size: 14px;
}
.modal-footer {
height: 82px;
line-height: 82px;
text-align: center;
background-color: #F5F5F5;
}
}
}
复制代码
我这里使用的是scss
,使用的时候别忘了安装node-sass
和sass-loader
,如今咱们的页面是这个样子了ide
虽然仍是不太美观,可是已经基本上是一个弹出框的雏形了,而且我没有给a
标记样式,缘由在后面。
回过头再看看上面的css
代码,这里重复写了4次固定定位的代码,并且随着项目的推动,确定还有更多相似的代码,何不将这些部分抽取出来,进行封装呢?scss
提供了这个功能,将css
封装成函数,这里的函数直接会返回函数体。咱们在遇到相似的状况时,就可以直接复用。
在assets
目录下新建scss
文件夹并在里面新建mixin.scss
,在里面新建position
函数,代码以下:
@mixin position($pos: absolute, $top: 0, $left: 0, $w: 100%, $h: 100%) {
position: $pos;
top: $top;
left: $left;
width: $w;
height: $h;
}
复制代码
接着咱们引入mixin.scss
,用position
函数替换咱们原先的代码
经过@include方式使用scss
函数:@include position(fixed);
括号里面的是参数。
每个网站都有不少按钮,不过,同一个网站的按钮风格大多都是同样,无非是大小不一。所以能够单独在scss
文件下新建button.scss
而后在App.vue
里面引入这个文件,在后面除了一些特别的样式,其它就不须要给按钮定义样式了,这样也便于维护。这里给出个人button
文件,能够参考一下。
.btn {
display: inline-block;
width: 110px;
line-height: 30px;
text-align: center;
background-color: #FF6600;
color: #ffffff;
border: none;
cursor: pointer;
}
.btn-default {
background-color: #b0b0b0;
color: #d7d7d7;
}
.btn-large {
width: 202px;
height: 50px;
line-height: 50px;
font-size: 18px;
}
.btn-huge {
width: 300px;
height: 54px;
line-height: 54px;
font-size: 16px;
}
.btn-group {
.btn {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
}
复制代码
当前这个弹出框还只是一个固定的结构,它并不能在其余地方复用,须要进行一些处理,将全部可变部分抽取出来,例如标题,按钮,内容。由于有插槽,因此内容就不用考虑,须要关注的是标题和按钮,由于标题有多是提示,警告等等,按钮也有多是肯定、取消的一个或两个都有。而这些信息都是从父组件传递过来,须要用props
接收。
在props
里面添加以下代码,并给某些属性指定默认值:
props: {
// 弹框标题
title: String,
// 按钮类型: 1:肯定按钮 2:取消按钮 3:肯定取消
btnType: String,
// 按钮文本
sureText: {
type: String,
default: "肯定"
},
cancleText: {
type: String,
default: "取消"
},
showModal: Boolean
}
复制代码
添加完以后,还需从新改写代码
<div class="modal" v-show="showModal">
<div class="mask"></div>
<div class="modal-dialog">
<div class="modal-header">
<span>{{title}}</span>
<a href="javascript:;" class="icon-close" @click="$emit('cancle')"></a>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<a href="javascript:;" class="btn" v-if="btnType==1"@click="$emit('submit')"{{sureText}}</a>
<a href="javascript:;" class="btn" v-if="btnType==2"@click="$emit('cancle')">{{cancleText}}</a>
<div class="btn-group" v-if="btnType==3">
<a href="javascript:;" class="btn" @click="$emit('submit')">{{sureText}}</a>
<a href="javascript:;" class="btn btn-default" @click="$emit('submit')">{{cancleText}}</a>
</div>
</div>
</div>
</div>
复制代码
经过父组件传递的参数,来实现代码的重用,而且使用$emit
来向外抛出自定义事件,而后在父组件实现本身的业务逻辑。
在Home.vue
里面引入这个组件并调用
<modal
title="小星星"
sureText="肯定"
btnType="1"
:showModal="showModal"
@submit="go"
@cancle="showModal=false"
>
<template v-slot:body>
<p>给个小星星吧</p>
</template>
</modal>
复制代码
这里的@submit
和@cancle
就是咱们在组件里面自定义的事件
最终效果以下
实现完以后,感受有点弹出时生硬,不要紧,咱们给它加点动画,在css3中有transform
和transition
能够实现动画效果,可是咱们这里使用vue
内置组件<transition>
,让弹出框有一个从上面弹出的效果。
transition
组件能够为元素或组件添加过渡效果,只会把过渡效果应用到其包裹的内容上,而不会额外渲染 DOM 元素,也不会出如今可被检查的组件层级中。它能够经过多种方式进行过渡,在这里应用 class的方式过渡。
这幅图是Vue
官方给出的图,简单来讲,v-enter是动画开始的状态,v-enter-active进入过渡生效时的状态,v-enter-to是过渡的结束状态,leave同理,具体细节你们能够去cn.vuejs.org/v2/guide/tr…查看。
当没有指定的name属性时,过渡的类名会默认以v做为前缀,这里给transition指定name为
slide并用它包裹modal组件
<transition name="slide">
<div class="modal" v-show="showModal">
...
...
</div>
</transition>
复制代码
在style代码里面modal后面加上
&.slide-enter-active {
top: 0;
}
&.slide-leave-active {
top: -100%;
}
&.slide-enter {
top: -100%;
}
复制代码
而且给modal指定须要过渡的属性
transition: top 0.5s;
复制代码
加完这个以后,弹出框就会有一个滑上滑下的动画啦。
到此,咱们的弹出框就完成啦。
你也能够根据本身的需求去作适当的调整,开发出适合本身项目的弹出框。
每次在用这个弹出框的时候,还须要引入组件,也显得有点麻烦,所以,能够将其作成插件,可以全局调用,而不须要去引入。
在当前目录下新建index.js,经过使用install方法将其全局注册
import Modal from './Modal.vue'
const component = {
install: function (Vue) {
Vue.component('Modal', Modal)
}
}
export default component
复制代码
在main.js引入,并经过Vue.use()来全局使用,这样就能像其余ui库同样去使用它而不须要每次引入。
在实际开发中,组件化是尤其重要的,它可以帮助咱们写出更高质量的代码,也可以让咱们的代码更易于维护,尽早的树立组件化的思想,对写代码也是很是有帮助的。
本文只是对组件化的简单理解,有不对的地方,欢迎大佬指出。
感谢评论区大佬的点拨。