如何开发自定义Vue组件(一):进度条组件?

如何引入vue.js

官网:https://cn.vuejs.org/v2/guide/installation.html

官网有详细的介绍,有多种方式满足你的不同需求,我用的最简单快捷的方法,如直接<script>vue.js的地址(可以把vue.js下载下来放入静态文件夹static下)</script>引入,Vue 会被注册为一个全局变量。

引入 <script src="/static/vue/vue.js"></script>

为什么要开发自定义组件?

复用,高效率,好维护,方便协同开发。

了解Vue组件的组成部分

  • Template: 就是html。
  • Css: 为了让html好看。
  • Component: Vue组件的核心,包含属性、传值、方法,其实就是把自定义组件注册下,成为vue的一员。

举例说明:光线移动的进度条

star-progress.png

Template

在原progress的基础上加上自定义的设置和css样式。

<script type="x-template" id="star-progress-block">
    <ul class="border-box">
      <li style="font-size:40px;"><span v-text="perValue"></span></li>
      <li>
        <div>
          <progress class="progress-linear" :value="value - min" :max="max - min" style="width:100%"></progress>
          <div ref="star" class="star-light" v-bind:style="starStyle"></div>
        </div>
      </li>
      <li style="color:rgb(93,133,141);"><slot></slot></li>
    </ul>
</script>

Css

基础样式是bootstrap.css,再加上自定义样式。
考虑到浏览器兼容器性,开发css需要多研究不同浏览器的特点,有针对的设置。

.border-box {
  height: 130px;
  padding: 20px;
  border: 1px solid rgb(45, 44, 60);
}

/*渐变+星光进度条*/
progress.progress-linear {
  width: 200px;
  height: 1px;
 color: #5D858D;
  /*兼容IE10的已完成进度背景*/
  border: none;
  background-color: #2D3C41;
  /*这个属性也可当作Chrome的已完成进度背景,只不过被下面的::progress-bar覆盖了*/
}

@keyframes foxfire-bg-gradient
{
  0%   {background-image: -moz-linear-gradient(0deg, #56BBCA 0%, #2D3C41 100%);}
  10%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 10%, #2D3C41 100%);}
  20%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 20%, #2D3C41 100%);}
  30%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 30%, #2D3C41 100%);}
  40%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 40%, #2D3C41 100%);}    
  50%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 50%, #2D3C41 100%);}
  60%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 60%, #2D3C41 100%);}
  70%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 70%, #2D3C41 100%);}
  80%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 80%, #2D3C41 100%);}
  90%  {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 90%, #2D3C41 100%);}
  100% {background-image: -moz-linear-gradient(0deg, #2D3C41 0%, #56BBCA 100%);}
}

@keyframes chrome-bg-gradient
{
  0%   {background-image: -webkit-linear-gradient(0deg, #56BBCA 0%, #2D3C41 100%);}
  10%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 20%, #2D3C41 100%);}
  20%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 40%, #2D3C41 100%);}
  30%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 60%, #2D3C41 100%);}
  40%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 80%, #2D3C41 100%);}    
  50%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 100%);}
  60%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 80%, #2D3C41 100%);}
  70%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 60%, #2D3C41 100%);}
  80%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 40%, #2D3C41 100%);}
  90%  {background-image: -webkit-linear-gradient(0deg, #2D3C41 0%, #56BBCA 20%, #2D3C41 100%);}
  100% {background-image: -webkit-linear-gradient(0deg, #56BBCA 0%, #2D3C41 100%);}
}

.star-light {
  position: relative;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: #ECFABD;
}
/*firefox*/
progress.progress-linear::-moz-progress-bar {
 animation-name: foxfire-bg-gradient;
  animation-duration: 3s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

/*chrome*/
progress.progress-linear::-webkit-progress-bar {
  background-color: #2D3C41;
  /*背景颜色*/
}

progress.progress-linear::-webkit-progress-value {
  animation-name: chrome-bg-gradient;
  animation-duration: 3s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

Component

为了让新组件成为vue的一员,所以需要注册。
其中props用于接收来自父组件的数据。官网举了props使用例子以及命名大小写的说明。
camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名。
举例:prop:myName -> DOM: my-name

官网:https://cn.vuejs.org/v2/guide/components-props.html

通过该组件可以更直观的发现,类似于为新组件增加了新属性,为了便于理解,我是这么说服自己的。
当然在以后的项目中,会再次发现props的用处确实是父组件传递值到子组件中。特别是当一个.vue文件作为组件的时候,尤其明显。而且这种传值是单向的,父传子。

Vue.component('star-progress-block', {
  data: function () {
    return {}
  },
  props: {
    min: {
      type: Number,
      default: 0
    },
    max: {
      type: Number,
      default: 100,
    },
    value: {
      type: Number,
      default: 0,
    },
    perValue: {
      type: String,
      default: ''
    }
  },
  computed: {
    'starStyle': function() {
      var top = '-5px', left = '' + ((this.value - this.min)/(this.max - this.min)) * 100 + '%'

      return {top, left}
    }
  },
  template:'#star-progress-block' // 也可以把star-progress-block内容贴这,用单引号或反单引号括起来,像这样: ` <ul>...</ul>`
})

到此,新的进度条组件就开发完成了,怎么应用呢?

如何应用自定义组件?

Html

像html普通组件一样使用,传值通过vue实例的data数据,这是双向绑定的。vue框架是MVVM模式,所以决定了数据是双向绑定的,这是另一个课题,有兴趣自行查阅资料。

<div class="col-md-3 first">
  <star-progress-block 
     :value="rate"
     :min="rateMin"
     :max="rateMax"
     :per-value="rateValue">
      测试
    </star-progress-block>
  </div>

Script

既然需要vue实例,所以new一个实例,设置data数据,即可显示进度条的数值。

var v = new Vue({
  el: '#app',
  data: {      
    rate: 0,
    rateMin: 0,
    rateMax: 100,
    rateValue: '准备中'
 }
 ....

总结

在之前的项目中开发了多个vue自定义组件,像进度条,菜单栏,时间框等,觉得有必要重新整理思路以备以后查阅,也希望有志同道合的人一起讨论。

前端开发变化多端,新技术层出不穷,宗旨只有一个,那就是更方便更快捷的开发出所需的页面。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容