Vue动态组件

前言

  之前对Vue的了解很局限,感觉上和我实验室老师的Nodom框架很像,也可以说Nodom有一些借鉴Vue的地方,所以当时学习Vue也只是草草的入了个门,然后就从做demo开始学习。最近觉得自己用Vue好像到瓶颈期了,因为觉得Vue的教程是最好的资料,就准备认真的在过一遍Vue的教程。

动态组件&异步组件

  由于项目的问题,要解决从服务端获取表单内容,来动态生成表单,这就有点触及我的知识盲区了。难道要一个一个页面写,这也太傻了吧。了解了之后大概可以分为三种可以使用的方法,动态组件、异步组件、JSX。JSX了解不多,就不深入了。异步组件:

Vue.component('async-example', function (resolve, reject) {
  setTimeout(function () {
    // 向 `resolve` 回调传递组件定义
    resolve({
      template: '<div>I am async!</div>'
    })
  }, 1000)
})

  通过定义工厂函数来异步解析组件定义,只有组件在需要被渲染的时候才会触发这个工厂函数,而且Vue会将结果缓存起来供未来使用。不适用动态生成多个不同表单的应用场景。

  动态组件:

<component v-bind:is="currentTabComponent"></component>

  使用Vue的is特性来决定要加载的组件,针对使用element-ui、iview等ui框架的话生成表单、验证等要方便的多。这样一来就可以定义一套格式规范,从服务端拿到这些数据然后根据type选择相应组件生成表单,只要把统一的样式定好,就基本可以实现动态生成组件了。以iview为例:

<!-- html -->
<Form>
   <FormItem>
      <component :is="componentName"></component>
   </FormItem>
</Form>

// ts
public componentName: string = 'Input';

不同表单的数据问题

  实现生成动态表单的问题已经解决了,但是由于我的需要不仅要生成表单还要拿到相应的数据。

  经过几天的思考(当然这几天还在做其他的东西),暂时想到了一种解决方案,因为vue的v-model就是拿来做数据的双向绑定的,肯定要围绕这一点来想办法。因为所有生成表单的信息都要来自服务端,那么这些事肯定也要一并从服务端拿了,初步的想法是统一一个字段名来做form的数据对象名,叫plugin-form,然后在每个表单元素中定义一个字段名plugin-form-item,这样通过v-model就可以进行数据的双向绑定,用户进行了输入以后,数据就会绑定到相应字段上,只需遍历整个表单元素,将数据封装成对象就可以了。

// 服务端数据返回 json
{
    plugin_name: 'xxx',
    ···
    plugin_form: 'appForm',
    form_item: [
        {
            type: 'Input',
            plugin_form_item: 'app_name',
            ···
        },
        {
            type: 'Input',
            plugin_form_item: 'project_path',
            ···
        },
    ]
}
// 通过v-model拿到的数据
appForm: {
    app_name: '用户输入',
    project_path: '用户输入'
}

提交&数据校验问题

  因为要涉及很多个不同的表单提交,可以用button提交暂存到localstorage,然后依次取出提交就可以了。关于校验可能要麻烦一些,还没有想好结构,但使用async-validator应该也没有太大问题。

其他

  动态组件的意思就像是给组件加了一个v-if,只不过用is特性的方式看起来更优雅一些。想到动态组件,因为Vue官方教程切换tab时用的是动态组件,我一般使用的是router-view,然后上了下思否好像基本都是使用的router-view。