Vue3组件(17)给表单控件设置一个插槽

简介: 给表单控件设置一个插槽

image.png


表单的自定义子控件



表单封装之后就会遇到一个古老的问题 —— 需要放进去一个新类型的子控件怎么办?


表单控件又不可能把所有类型的框架都封装进去,这在以前都是很头痛的问题,如果是需要修改封装好的代码才可以实现的话,那就太郁闷了。


但是现在在Vue里面,至少有两种解决方案,还都挺优雅的。


用插槽设置自定义组件



Vue的组件有插槽这个功能,一开始还没想起来,这的多谢好友“@我滴神”的提醒,才想起来可以用插槽。好吧其实是我以前还不会用插槽。。。


研究了一下Vue官网,又结合 el-input 设置的插槽理解了一下,发现还不难,于是给表单控件设置了这样的插槽。


<el-form
      :model="formModel"
      ref="formControl" // 官网把这两个属性设置成一样的,结果被坑了,,,
      :rules="rules"
      :inline="false"
      class="demo-form-inline"
      label-suffix=":"
      label-width="130px"
      size="mini"
    >
      <el-row>
        <!--不循环row,直接循环col,放不下会自动往下换行。-->
        <el-col
          v-for="(ctrId, index) in formColSort"
          :key="'form_'+index"
          :span="formColSpan[ctrId]"
        >
          <el-form-item
            :label="getCtrMeta(ctrId).label"
            :prop="getCtrMeta(ctrId).colName"
          >
            <!--判断要不要加载插槽-->
            <template v-if="getCtrMeta(ctrId).controlType === 1">
              <slot :name="ctrId">父组件没有设置插槽</slot>
            </template>
            <!--表单item组件,采用动态组件的方式-->
            <template v-else>
              <component
                :is="ctlList[getCtrMeta(ctrId).controlType]"
                v-model="formModel[getCtrMeta(ctrId).colName]"
                v-bind="getCtrMeta(ctrId)"
                @myChange="mySubmit">
              </component>
            </template>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
复制代码


在原先v-for循环的基础上,加上一个判断,根据meta的controlType 来判断,如果=== 1 好的,那么就是要用插槽,然后把控件ID设置给插槽的name属性,这样就可以按照控件ID来加载外部指定的插槽了。


外部使用方法



父组件首先要设置好插槽,这个就可以很随意了,插槽嘛就是可以各种各样的,我们先来个简单的。


<elForm
    v-model="model"
    v-model:partModel="partModel"
    :meta="meta">
      <template v-slot:102="">
        <h3>这是外面建立的子控件</h3>
        <el-input v-model="model.colName" placeholder="请输入内容"></el-input>
      </template>
      <template v-slot:104="">
        <h3>这是外面建立的另一个子控件</h3>
        <input type="text">
      </template>
  </elForm>
复制代码


用 template 设置好控件ID,这样可以设置多个插槽。


然后再设置一下表单的meta即可


// 设置使用插槽的表单子控件
    meta.itemMeta[102].controlId = 102
    meta.itemMeta[102].colName = '属性名称'
    meta.itemMeta[102].controlType = 1
复制代码


属性的具体内以后在介绍,总之,不用改表单控件的内部代码,就可以实现随意往里加新的子控件的需求了。


支持验证等功能吗?



测试了一下,支持各种功能,表单数据验证、排序、占位等都是支持的,和表单自带的子控件是一样的功能。 只是 v-model 需要外部设置一下。


这些还要感谢 Vue 和 UI库的强大。


$ref怎么处理?



element的官网例子里面,重置表单用的是Vue2的方式,正巧在Vue 官网看到了$ref的用法,于是改成了Vue3的方式实现重置表单的功能。


// Vue2 的方法
methods: {
  resetForm(formName) {
    this.$refs[formName].resetFields();
  }
}
// Vue3的方法
// 获取 $ref
  const formControl = ref(null) // 设置给el-form 的ref属性
  onMounted(() => {
    console.log('表单dom', formControl)
  })
  const resetForm = () => {
    // 清空表单
    formControl.value.resetFields()
  }
复制代码


这样表的控件就更完善了,另外,这不过了几天嘛,结果再看代码,居然看不懂了。。。


源码



github.com/naturefwvue…



相关文章
|
1天前
|
存储 API
vue3中如何动态自定义创建组件并挂载
vue3中如何动态自定义创建组件并挂载
|
1天前
|
JavaScript
vue 函数化组件
vue 函数化组件
|
6天前
|
JavaScript
Vue组件传值异步问题--子组件拿到数据较慢
Vue组件传值异步问题--子组件拿到数据较慢
11 0
|
2天前
|
JavaScript
vue中watch的用法
vue中watch的用法
|
2天前
|
JavaScript 前端开发
vue动态添加style样式
vue动态添加style样式
|
2天前
|
JavaScript 前端开发
Vue项目使用px2rem
Vue项目使用px2rem
|
1天前
|
JavaScript API
vue学习(13)监视属性
vue学习(13)监视属性
10 2
|
1天前
|
JavaScript
vue知识点
vue知识点
7 2
|
1天前
|
JavaScript 前端开发
vue学习(15)watch和computed
vue学习(15)watch和computed
9 1
|
9天前
|
JavaScript 前端开发
vue学习(6)
vue学习(6)
30 9