# 自定义扩展

您还可以自定义类型扩展,将自定义类型、自定义表单组件、自定义行展示组件整合为一个模块

# 开发一个自定义扩展

此处以demo-extend (opens new window) 为例来展示如何开发一个自定义扩展

# 1. 自定义一个表单组件

这个表单组件需要符合v-model写法,具体请参考vue文档 (opens new window)
简单来说就是要能通过value属性输入值,并且通过input、change等事件返回改变后的值

<template>
  <span>
    <el-tag :type="color" >您点击了:  {{currentValue}}</el-tag>
    <el-button :disabled="disabled || readonly" class="d2-ml-5" @click="doClick('1')">点击1</el-button>
    <el-button :disabled="disabled || readonly" @click="doClick('2')">点击2</el-button>
    插槽:<slot name="test1" :value="1"/>
  </span>
</template>

<script>
// 表单扩展组件示例
// 需要符合v-model的写法
// 简单来说就是,接收value参数,当用户对value进行改变时,通过input通知父组件修改value的值。
export default {
  name: 'd2p-form-input',
  props: {
    // 值
    value: {
      type: String,
      required: false
    },
    // 禁用
    disabled: {
      type: [Boolean],
      required: false,
      default: false
    },
    // 只读
    readonly: {
      type: [Boolean],
      required: false,
      default: false
    },
    // 你可以定义一些参数,通过component.props传进来
    color: {
      required: false
    }
  },
  data () {
    return {
      // 本组件的实际value值
      // 由于value值是props参数,是不允许修改的,需要用别的值存起来
      currentValue: ''
    }
  },
  computed: {
    // 你也可以通过computed来监听value的变化,跟watch作用类似,根据实际情况选用
    // currentValue () {
    //   return this.value
    // }
  },
  watch: {
    value (value) {
      // 父组件收到input事件后会通过v-model改变value参数的值
      // 然后此处会watch到value的改变,发出change事件
      // change事件放在此处发射的好处是,当外部修改value值时,也能够触发form-data-change事件
      this.$emit('change', value)
      if (this.currentValue === value) {
        return
      }
      // 如果值是被外部改变的,则修改本组件的currentValue
      this.setValue(value)
    }
  },
  created () {
    // 给currentValue设置初始值
    this.setValue(this.value)
  },
  mounted () {
  },
  methods: {
    setValue (value) {
      // 在这里对 传入的value值做处理
      this.currentValue = value
    },
    // 用户触发按钮点击
    doClick (value) {
      // 发出input事件通知父组件,然后请看上面watch的注释 ↑↑↑↑
      this.$emit('input', value)
    }
  }
}
</script>

# 2. 自定义一个行展示组件

d2-crud-plus舍弃了column.component的行编辑功能,将column.component作为了行展示组件使用

该组件也需要符合v-model写法,由于是展示组件,无需发送input和change事件
但要求能够感知传入的value值的变化
所以必须通过watch或者computed方式来根据value变化而改变展示结果

<template>
  <el-tag :type="color">您选择了-> {{value}}</el-tag>
</template>
<script>
// 本示例是行展示组件的最简版本
// 如果要对值做一些处理后再展示,请看index-advance.vue版本
export default {
  name: 'd2p-row-format',
  props: {
    // 接收row.xxx的值
    value: {
      type: String,
      required: false
    },
    color: {
      require: false
    }
  }
}
</script>

# 3. 定义字段类型

你也可以直接使用已注册的符合v-model的其他组件组合使用

export default {
  // 字段类型配置,注册之后即可在crud.js中使用了
  'demo-extend': {
    // 表单组件配置
    form: { component: { name: 'd2p-form-input', props: { color: 'danger' } } },
    // 行组件配置
    component: { name: 'd2p-row-format', props: { color: 'success' } },
    // 行展示时居中
    align: 'center'
    // 您还可以写更多默认配置
  }
}

# 4. 打包成组件包

import { d2CrudPlus } from '../utils/d2-crud-plus'
import types from './types'

function install (Vue, options) {
  Vue.component('d2p-form-input', () => import('./lib/d2p-form-input'))
  Vue.component('d2p-row-format', () => import('./lib/d2p-row-format'))
  if (d2CrudPlus != null) {
    // 注册字段类型`demo-extend`
    d2CrudPlus.util.columnResolve.addTypes(types)
  }
}

// 导出install, 通过`vue.use(D2pDemoExtend)`安装后 ,`demo-extend` 就可以在`crud.js`中使用了
export default {
  install
}

# 5. 在项目中安装

import { D2pDemoExtend } from 'd2p-extends' 
Vue.use(D2pDemoExtend)

# 6. 使用

查看效果 (opens new window)

export const crudOptions = {
  columns: [
     {
      title: '自定义组件',
      key: 'demo',
      type: 'demo-extend'
    }, 
  ]
}

# d2p-extends(现有自定义扩展)

d2p-extends (opens new window)

# 扩展组件懒加载

内部组件采用()=>import()方式进行引用即可实现组件懒加载