vue组件开发——基础

组件化开发缘由

前端组件化开发始于200X年,前端开发离不开HTML/CSS/JS,早期开发以页面为开发单位,三种语言各有特色,早期缺少固定规范,没有约束,野蛮开发。开发完时,前端开发者和上帝知道写的代码是什么意思;过了一个月后,就只有上帝知道这段代码什么意思。前端

随以前端组件这个概念逐渐在开发者脑海中生成,从早期的YUI、ExtJS再到web components,随着三大框架的出现,组件化开发开始家喻户晓,组件做为基本的抽象单元。React横空出世,让人们知道组件能够是函数,突破了人们原来基于页面的理解,经过将经常使用逻辑功能抽象成各类组件,方便开发时调用,测试,减小前端逻辑和ui的耦合等。vue

现阶段比较火的组件库,好比说antd系列以及elementui等,都是面向中后台系统开发出来的,由于中后台系统的功能相对来讲比较固定,UI样式要求并不复杂,能够在以往的业务逻辑中总结出一些经常使用的组件,将这些组件开发出来,方便中后台系统的开发。react

组件分类

组件能够分为四类:web

1.纯展现类组件

这类组件能够是一个list或者是一个table,主要承担向用户展现服务端数据的功能。传入数据,组件渲染生成对应DOM。vue-router

2.接入型组件(与服务端交互)

例子:vue-router中配置挂载的vue组件,承担者和服务端获取、发送数据这样的功能,而后再一层一层传递给纯展现类组件。浏览器

3.交互型组件

例子:表单组件,时间日期选择组件等,包含比较复杂的用户交互逻辑,一种比较通用的逻辑,强调复用。markdown

4.功能型组件

抽象化的,提供某些抽象功能。vue-router中的router-viewtransation组件。自己不渲染任何内容,做为一种扩展抽象机制的逻辑型组件存在antd

vue组件开发API

组件的两个基础就是props和event。框架

props:经过父组件传递props进来,简单组件能够将props转化成virtual DOM 最后再渲染成DOM,展示给用户。iview

event:组件须要支持除了浏览器原生事件以外,还须要支持一些组件的自定义事件,来支持UI交互功能。

slot:在如今三大框架下的组件,其实组件都是函数的概念,仅仅由props和event这样两个API只能开发一些简单的组件,开发复杂一些的组件还须要进一步的API支持,react中能够直接使用props去继承,而因为vue是SFC模式的,因此vue提供了slot这一API去弥补template在这一场景下的不足。

综上,vue组件开发离不开的三大API就是props、event、slot。

props

这里给出iview做者的一个简易button的例子

<template>
  <button
    :class="'i-button-size' + size"
    @click="handleClick"
    :disabled="disabled"
  >
    <slot name="icon"></slot>
    <slot></slot>
  </button>
</template>
<script>
// 判断参数是不是其中之一
function oneOf(value, validList) {
  for (let i = 0; i < validList.length; i++) {
    if (value === validList[i]) {
      return true;
    }
  }
  return false;
}

export default {
  inheritAttrs: false,
  props: {
    size: {
      validator(value) {
        return oneOf(value, ["small", "large", "default"]);
      },
      default: "default",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  created: function () {
    console.log(this.$attrs); //注意这里
  },
  methods: {
    handleClick(evt) {
      this.$emit("click", evt);
    },
  },
};
</script>

复制代码

这里须要注意几点

1.开发组件须要指定props的类型,可能的话设定默认值,以及添加validator函数,进行参数校验,提高组件的稳定性。

2.经过inheritAttrs: false$attrs,咱们能够手动控制除了props以外的attribute具体怎么继承。须要注意的是inheritAttrs: false并不能影响styleclass的继承

event

不一样于组件和props,事件的命名大小写敏感,而且推荐使用kebab-case的命名方式

以button组件中的点击事件为例子,有两种方式添加一个点击事件。

<template>
  <button @click="handleClick">
    <slot></slot>
  </button>
</template>
<script>
  export default {
    methods: {
      handleClick (event) {
        this.$emit('on-click', event);
      }
    }
  }
</script>
复制代码

经过 $emit,就能够触发自定义的事件 on-click ,在父级经过@on-click来监听

<i-button @on-click="handleClick"></i-button>
复制代码

直接在父级声明,但为了区分原生事件和自定义事件,要用到事件修饰符 .native

<i-button @click.native="handleClick"></i-button>
复制代码

这里再给出笔者写的一个简单版本的input组件

<template>
  <div class="fr-input" :class="[inputSize?'fr-input--' + inputSize:'']">
    <input
      class="fr-input__inner"
      :class="[inputSize?'fr-input__inner-'+inputSize:'']"
      :readonly="readonly"
      :value="value"
      @input="handleInput"
      @focus="handleFocus"
      v-bind="$attrs"
      autocomplete="off"
    />
  </div>
</template>
<script>
export default {
  name: 'FrInput',
  props: {
    value: [String, Number],
    readonly: Boolean,
    size: {
      type: String
    }
  },
  data() {
    return {
      focused: false
    }
  },
  computed: {
    inputSize() {
      return this.size
    }
  },
  methods: {
    handleInput(event) {
      this.$emit('input', event.target.value)
    },
    handleFocus(event) {
      this.focused = true
      this.$emit('focus', event)
    }
  }
}
</script>
复制代码

具体使用

<fr-input
    v-model="phoneNumber"
    type="text"
    name="name"
    spellcheck="false"
    placeholder="请输入手机号"
    class="input"
    size="mform100"
  ></fr-input>
复制代码

这里须要注意:value="value"@input="handleInput"其实就是v-model="value"的语法糖,在vue2.2版本以上后,可使用model选项来定制prop和event

slot

在props中给出的button组件例子中,若是想在父组件中添加一些文字内容, 这里使用了slot的默认插槽还有slot="icon"的具名插槽,插槽能够极大程度的扩展组件的功能。

<i-button>
  <i-icon slot="icon" type="checkmark"></i-icon>
  按钮 1
</i-button>
复制代码

本文简单介绍了一些组件化开发的概念、缘由以及vue组件化开发的相关API具体使用。接下来会进行一些更深刻的学习。

相关文章
相关标签/搜索