1. 基础组件编写

1.1 组件目录结构

1.2 组件文件代码

<template><transition name="fade"><div class="notification" :style="style"><span class="content">{{content}}</span><a class="btn" @click="handleClose">{{btn}}</a></div></transition>
</template><script>
export default {name: 'Notification',props: {content: {type: String,required: true},btn: {type: String,default: '关闭'}},computed: {style () {return {}}},methods: {handleClose (e) {e.preventDefault()this.$emit('close')}}
}
</script><style lang="stylus" scoped>
.notificationdisplay flexbackground-color #303030color rgba(255, 255, 255, 1)align-items centerpadding 20pxposition fixedmin-width 280pxbox-shadow 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.8)flex-wrap wraptransition all .3s.contentpadding 0.btncolor #ff4081padding-left 24pxmargin-left autocursor pointer
</style>

1.3 组件使用的过渡效果样式代码

html, body{margin: 0padding: 0width: 100%height: 100%
}body{background-image: url(../images/beijing.jpg)background-size: coverbackground-position: centerfont: 14px/1.5 tahoma,arial,'Hiragino Sans GB','\5b8b\4f53',sans-serifcolor: #4d4d4d-webkit-font-smoothing: antialiased // 这个属性可以使页面上的字体抗锯齿,使用后字体看起来会更清晰舒服font-weight: 300
}.fade-enter-active, .fade-leave-active{transition: opacity .5s
}
.fade-enter, .fade-leave-to{opacity: 0
}

1.4 如果我们直接使用这个编写好的组件,只能是我们在编写一个Vue组件的时候引用这个Notification的组件把它写在模版里面,把它去显示出来,我们这里作为一个全局通用型组件,而且我们可以把它发布到第三方去使用的组件,所以我们这里会为其提供一个类似于Vue插件的使用方法。

友情提醒:我们在定义组件的时候最好都给组件定义一个name,因为我们去编写一个组件库,我们会有非常多的组件要注册到全局的Vue的组件里面,这个时候如果没有一个name,那么每个组件注册的时候都需要用字符串去写name,这个维护性是非常不好的,如果你在组件内部就把组件的name定义好,那就可以很方便的把组件一个个定义过去就OK了。

1.5 入口文件引入组件,然后将其定义为插件即可再全局使用该组件了

1.6 在app组件中使用我们自定义的通知组件,直接使用即可无需再次注册

1.7 打开浏览器查看显示效果

1.8 总结

现在看我们这个组件的静态展示效果已经出现了,基本也就是这个样子,我们使用组件的时候需要在模版里面去定义,而且它还没有变成全局性的那种提示要从右下角弹出来,我们如果要在模版里进行这种效果控制还需要给组件添加属性visible用来控制组件的显示隐藏,然后在我们自己的逻辑中判断什么时候该显示什么时候该消失,整个逻辑就会变得很复杂,那我们用起来非常的困难,因为这种是临时性的组件,等到某个特殊的情况才需要我们去Notification一下,那么如果我们写在模版里,则一开始就需要定义好这个组件而且需要控制这个组件是不显示的,这种用法明显感觉是很奇怪的。所以,后面我们就要去改进它,让我们自定义的这个组件可以通过Vue的一些功能去实现我们可以通过API的方式去调用它。用起来就会变得非常方便了~

2. 通过API方式调用组件

2.1 扩展Notification组件,因为只有上面定义的两个属性是不够使用的,所以我们使用Vue.extends去扩展这个组件,为什么我们不在原来的组件是直接进行修改呢?因为那些属性添加上之后,如果我们在app.vue组件中在模版中使用这个组件的时候就会变得不好用,因此我们选择去扩展组件,而不是去修改原来的组件。这样既可以复用原来组件的代码,然后又可以达到我们扩展功能的目的。那么我们如何去扩展我们原来的组件呢?需要新创建一个文件,专门用来做API调用时使用的。

代码:

import Notification from './notification.vue'export default {extends: Notification,data () {return {verticalOffset: 0}},computed: {style () {return {position: 'fixed',right: '20px',bottom: `${this.verticalOffset}px`}}}
}

2.2 编写API调用逻辑处理文件

代码:

import Vue from 'vue'
import Component from './func-notification'/*** 思考:我们为什么要这么去做呢?因为我们这里是一个方法,我们要通过JS的方法调用去创建一个Vue的组件,这个组件我们怎么去创建最方便呢?* 我们肯定是通过去new的方式,我们可以直接通过new Vue去创建一个组件,那么我们同样可以通过Vue.extend返回的方法,我们去创建一个组件。*/
const NotificationConstructor = Vue.extend(Component)const instances = [] // 存储通知组件实例列表
let seed = 1 // 用来生成组件的idconst notify = (options) => {if (Vue.prototype.$isServer) returnconst instance = new NotificationConstructor({propsData: options})instance.id = `notification_${seed++}` // 生成唯一id,用来做删除时使用// 通过$mount()不传节点的时候,只是生成了一个$el的对象,但是这个时候还没有真正的插入到DOM节点里面去,此时标签节点已经生成好了instance.vm = instance.$mount()document.body.appendChild(instance.vm.$el)// 计算高度let verticalOffset = 0instances.forEach((item) => {verticalOffset += item.$el.offsetHeight + 16 // 每个组件高度间隔16px})verticalOffset += 16 // 最下面的组件底部距离最底部也有16px的间隙instance.verticalOffset = verticalOffsetinstances.push(instance)return instance.vm
}export default notify

2.3 将编写的API调用方法挂载到Vue.prototype原型对象上,这样在Vue的实例中就可以直接使用this.$xxx方法了

代码:

import Notification from './notification.vue'
import notify from './function'export default (Vue) => {Vue.component(Notification.name, Notification)Vue.prototype.$notify = notify
}

2.4 在app.vue组件中使用该API来生成通知

代码:

<template><div><notification content="测试通知组件模版使用" /></div>
</template><script>
export default {data () {return {}},mounted () {this.$notify({content: '测试通知组件API使用!!!',btn: 'close'})}
}
</script><style>
</style>

2.5 打开浏览器查看效果,通过API调用方式成功生成我们想要的组件效果!!!

3. 点击发送通知

3.1 接下来我们实现每次点击按钮发送通知

3.2 改造代码实现点击按钮发送通知

代码:

<template><div><!-- <notification content="测试通知组件模版使用" /> --><button @click="notify">发送通知</button></div>
</template><script>
export default {data () {return {}},mounted () {},methods: {notify () {this.$notify({content: '测试通知组件API使用!!!',btn: 'close'})}}
}
</script><style>
</style>

3.3 添加通知自动关闭功能

代码:

import Notification from './notification.vue'export default {extends: Notification,data () {return {verticalOffset: 0,autoClose: 3000}},computed: {style () {return {position: 'fixed',right: '20px',bottom: `${this.verticalOffset}px`}}},mounted () {this.createTimer()},beforeDestory () {this.clearTimer()},methods: {createTimer () {if (this.autoClose) {this.timer = setTimeout(() => {/*** 思考:这里我们需要把我们的组件隐藏掉,如果直接将组件删除掉效果会比较差,所以我们也要通过transition去做,* 通过transition去做,我们就需要通过某个属性去控制我们组件的显示与否,所以我们在我们的组件上面去添加一个visible属性,* 该属性用来控制组件的显示与隐藏。在默认组件内部该属性值是true,也就是说默认是显示的。*/this.visible = false}, this.autoClose)}},clearTimer () {if (this.timer) {clearTimeout(this.timer)}}}
}

调用API修改

代码:

import Vue from 'vue'
import Component from './func-notification'/*** 思考:我们为什么要这么去做呢?因为我们这里是一个方法,我们要通过JS的方法调用去创建一个Vue的组件,这个组件我们怎么去创建最方便呢?* 我们肯定是通过去new的方式,我们可以直接通过new Vue去创建一个组件,那么我们同样可以通过Vue.extend返回的方法,我们去创建一个组件。*/
const NotificationConstructor = Vue.extend(Component)const instances = [] // 存储通知组件实例列表
let seed = 1 // 用来生成组件的idconst notify = (options) => {if (Vue.prototype.$isServer) return/*** 我们希望我们的func-notification组件中的autoClose属性是通过options传入的,但是又不希望它是通过props传入而是作为data使用的,* 那么我们如何处理呢?我们可以拿到options形式传入的autoClose参数,然后以data的形式传给组件,其余的数据以props形式传递给组件* */const {autoClose,...rest} = optionsconst instance = new NotificationConstructor({propsData: {...rest},data: {autoClose: autoClose === undefined ? 3000 : autoClose}})instance.id = `notification_${seed++}` // 生成唯一id,用来做删除时使用// 通过$mount()不传节点的时候,只是生成了一个$el的对象,但是这个时候还没有真正的插入到DOM节点里面去,此时标签节点已经生成好了instance.vm = instance.$mount()document.body.appendChild(instance.vm.$el)// 计算高度let verticalOffset = 0instances.forEach((item) => {verticalOffset += item.$el.offsetHeight + 16 // 每个组件高度间隔16px})verticalOffset += 16 // 最下面的组件底部距离最底部也有16px的间隙instance.verticalOffset = verticalOffsetinstances.push(instance)return instance.vm
}export default notify

友情提示:使用扩展运算符,需要做如下配置:

安装依赖包

➜  vue-demo npm install babel-preset-stage-2
npm WARN vue-demo@1.0.0 No repository field.+ babel-preset-stage-2@6.24.1
added 13 packages from 1 contributor and audited 8458 packages in 6.963s
found 5 vulnerabilities (2 low, 1 moderate, 2 high)run `npm audit fix` to fix them, or `npm audit` for details
➜  vue-demo npm run dev

配置.babelrc文件

{"presets": ["env","stage-2"],"plugins": ["transform-vue-jsx"]
}

修改webpack.config.js配置

3.4 点击发送通知按钮后查看效果

3秒后的效果,通知消失了

Vue组件化|通用组件开发——Notification通知组件相关推荐

  1. 一种灵活可靠的工作方式:组件化设计与开发

    一种灵活可靠的工作方式:组件化设计与开发 2017/03/20阅读 6.9k 评论 3收藏 174 零基础学产品,BAT产品总监带,2天线下集训+1年在线课程,全面掌握优秀产品经理必备技能.了解详情 ...

  2. Vue(组件化编程:非单文件组件、单文件组件)

    一.组件化编程 1. 对比传统编写与组件化编程(下面两个解释图对比可以直观了解) 传统组件编写:不同的HTML引入不同的样式和行为文件 组件方式编写:组件单独,复用率高(前提组件拆分十分细致) 理解为 ...

  3. Android - 组件化、模块化开发

    转载请注明出处:https://blog.csdn.net/mythmayor/article/details/107184467 一.组件化与模块化介绍 组件化 组件:最初的目的是代码重用,功能相对 ...

  4. 三、Vue组件化开发学习笔记——组件化的基本步骤、全局组件和局部组件、父组件和子组件、注册组件的语法糖、模板分离写法、组件的数据存放

    一.什么是组件化? 人面对复杂问题的处理方式: 任何一个人处理信息的逻辑能力都是有限的 所以,当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆的内容. 但是,我们人有一种天生的能力,就是将问题 ...

  5. js组件化、模块化开发

    组件化 为什么要组件化开发 有时候页面代码量太大,逻辑太多或者同一个功能组件在许多页面均有使用,维护起来相当复杂,这个时候,就需要组件化开发来进行功能拆分.组件封装,已达到组件通用性,增强代码可读性, ...

  6. 2020 Android 大厂面试-插件化、模块化、组件化,移动开发工程师的岗位职责

    替换了主工程context中LoadedApk的mResource对象 将新的Resource添加到主工程ActivityThread的mResourceManager中,并且根据Android版本做 ...

  7. 2020 Android 大厂面试-插件化、模块化、组件化,android开发环境的搭建视频

    if (Constants.COMBINE_RESOURCES) { //插件和主工程资源合并时需要hook住主工程的资源 Resources resources = ResourcesManager ...

  8. html 组件化 编辑器,V14.0发布:组件化编辑器+数据透视表

    SpreadJS 是一款基于 HTML5 的纯前端表格控件,兼容 450 种以上的 Excel 公式,具备"高性能.跨平台.与 Excel 高度兼容"的产品特性,可为用户提供高度类 ...

  9. 业务逻辑组件化android,AppJoint 极简 Android 组件化方案

    AppJoint 极简 Android 组件化方案.仅包含 3 个注解加 1 个 API,超低学习成本,支持渐进式组件化. 开始接入 在项目根目录的 build.gradle 文件中添加 AppJoi ...

  10. android给组件加上id,Android组件化入门:一步步搭建组件化架构

    Linux编程点击右侧存眷,免费入门到精晓! 作者丨Android手艺干货分享 https://www.jianshu.com/p/73b4fc288dd8 1.媒介 比来因为买卖需求调换,有考虑采用 ...

最新文章

  1. linux查看docker使用率,Linux系统非Docker环境如何限制CPU使用率
  2. 顺序表基本操作函数总结
  3. linux下c的学习
  4. Mac OSX使用VMware Fusion安装windows虚拟机教程
  5. 扩展图形输出 1111 java
  6. C#LeetCode刷题之#811-子域名访问计数​​​​​​​(Subdomain Visit Count)
  7. 【BZOJ-3721】Final Bazarek 贪心
  8. GDB同步显示源代码——layout
  9. std::map的使用
  10. winform(C#)拖拽实现获得文件路径
  11. ext2、ext3、ext4文件系统区别
  12. oracle表重命名 索引,Oracle索引
  13. python 拼音排序_Python实现针对中文排序的方法
  14. 本地文件共享到云服务器,Linux系统通过RDP上传文件到Windows云服务器
  15. DDD | 领域驱动设计初探
  16. Oracle--同义词详解
  17. html4角星,运用ai绘画出5角星4角星三角形形状的设置步骤
  18. B站视频封面图片获取_CodingPark编程公园
  19. CentOS 添加微软雅黑字体
  20. 深入理解Linux网路技术内幕学习笔记第四章:通知链

热门文章

  1. js实现html页面转为pdf下载
  2. T SNE降维matlab程序,关于t-SNE降维方法
  3. 字号大小对应表(字号换算磅值)
  4. 逻辑学学习.3--- 命题逻辑 (一):基本概念
  5. 【NetApp】NetApp存储设备的CPU使用率分析
  6. cdr添加节点快捷键_cdr快捷键大全_cdr教程【图文】
  7. 超级玛丽java_超级玛丽java实现源码
  8. 计算机一级pdf百度云,计算机一级(实操).pdf
  9. ubuntu下安装matlab
  10. Java代码如何翻译成机器语言