vue的组件化开发

vue的组件化开发

组件(Component)是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。
官方文档:https://cn.vuejs.org/v2/guide/components-registration.html

什么叫做组件化

vue.js 有两大法宝,一个是数据驱动,另一个就是组件化,那么问题来了,什么叫做组件化,为什么要组件化?接下来我就针对这两个问题一一解答,所谓组件化,就是把页面拆分成多个组件,每个组件依赖的 CSS、JS、模板、图片等资源放在一起开发和维护。 因为组件是资源独立的,所以组件在系统内部可复用,组件和组件之间可以嵌套,如果项目比较复杂,可以极大简化代码量,并且对后期的需求变更和维护也更加友好。

如何进行组件化开发

  1. 全局注册
    在 vue.js 中我们可以使用 Vue.component(tagName, options) 进行全局注册,例如
Vue.component('my-component', {
     
  // 选项
})
  1. 局部注册
    Vue.js 也同样支持局部注册,我们可以在一个组件内部使用 components 选项做组件的局部注册,例如:
import HelloWorld from './components/HelloWorld'

export default {
     
  components: {
     
    HelloWorld
  }
}

区别:全局组件是挂载在 Vue.options.components 下,而局部组件是挂载在 vm.$options.components 下,这也是全局注册的组件能被任意使用的原因。

组件化开发必备知识

所谓工欲善其事,必先利其器,在正式开发一个组件之前,我们先要掌握一些必备的知识,这里我只会简单介绍一下,详情参考官网。

name

组件的名称,必填

<lx-niu/>
<lx-niu></lx-niu/>

name: 'lxNiu'

js 中使用驼峰式命令,HTML 使用kebab-case命名。

props

组件属性,用于父子组件通信,可通过this.msg访问

<div>{
     {
     msg}}</div>

props: {
     
  msg: {
     
    type: String,
    default: ''
  }
}

show: Boolean // 默认false

msg: [String, Boolean]  // 多种类型

computed

处理data或者props中的属性,并返回一个新属性

<div>{
     {
     newMsg}}</div>

computed: {
     
  newMsg() {
     
    return 'hello ' + this.msg
  }
},

render

用render函数描述template

<lx-niu tag='button'>hello world</lx-niu>

<script type="text/javascript">
  export default {
     
    name: 'lxNiu',
    props: {
     
      tag: {
     
        type: String,
        default: 'div'
      },
    },
    // h: createElement
    render(h) {
     
      return h(this.tag,
        {
     class: 'demo'}, 
        this.$slots.default)
    }
  }
</script>

render 中的 h 其实就是 createElement,它接受三个参数,返回一个 vnode
h 参数解释:
args1: {string | Function | Object} 用于提供DOM的html内容
args2: {Object} 设置DOM样式、属性、绑定事件之类
args3: {array} 用于设置分发的内容

注:vue编译顺序: template–> compile --> render --> vnode --> patch --> DOM

mixins

// mixin.js
export default {
     
  data() {
     
    return{
     
       msg: 'hello world'
    }
  },
  methods: {
     
    clickBtn() {
     
      console.log(this.msg)
    }
  },
}

// index.vue
<button @click="clickBtn">button</button>

import actionMixin from "./mixin.js";
export default {
     
  methods: {
     },
  mixins: [actionMixin]
}

style

向子组件传递样式

// 父组件
<lx-niu :bodyStyle='{color: "red"}'/>


// 子组件
<template>
  <div :style='bodyStyle'>hello world</div>
</template>

<script>
  export default {
     
    name: 'lxNiu',
    props: {
     
      bodyStyle: {
     },
    },
  }
</script>

class

定义子组件的类名

// 父组件
<lx-niu round type='big'/>

// 子组件
<div :class="[
  type ? 'lx-niu__' + type : '',
  {'is-round': round},
]">控制</div>

//真实DOM
<div class='lx-niu__big is-round'>hello</div>

slot

分发内容,有传入时显示,无传入 DOM 时显示默认,分为无名和具名两种,this.s l o t s . d e f a u l t 默 认 指 向 无 名 插 槽 , 多 个 s l o t 时 用 法 t h i s . slots.default 默认指向无名插槽,多个 slot 时用法 this.slots.default默认指向无名插槽,多个slot时用法this.slots.name

<lx-niu>
  <div slot='header'>header</div>
  <div class="body" slot='body'>
    <input type="text">
  </div>
  <div slot='footer'>footer</div>

  <button class='btn'>button</button>
</lx-niu>

<template>
  <div>
    <slot name='header'></slot>
    <slot name='body'></slot>
    <slot name='footer'></slot>
    <slot></slot>
  </div>
</template>

<script>
  export default {
     
    name: 'lxNiu',
    mounted() {
     
      this.$slots.header // 包含了slot="foo"的内容
      this.$slots.default // 得到一个vnode,没有被包含在具名插槽中的节点,这里是button
    }
  }
</script>

等等。。。详细请查看官方文档:https://cn.vuejs.org/v2/guide/components-registration.html

你可能感兴趣的:(javascript,vue.js)