需求

现在有一个公共组件,在多个端都需要使用,但传入组件的参数不同,每个端都要写个vue的页面或是component有点麻烦。

<template>
  <child blPath="/patient/record" nextPatientPath="/patientList"></child>
</template>
<script>
import child from 'baqi-doctor/src/pages/group/checkJoinInfo'
export default {
   
  name: 'CheckJoinInfo',
  components: {
    child }
}
</script>
<style scoped>
</style>

我们可以在路由中使用渲染函数来创建组件,实现代码如下,在router.js中的routes数组中增加以下对象

{
   
  path: '/group/checkJoinInfo',
  name: 'CheckJoinInfo',
  meta: {
    title: '患者请求详情' },
  component: () => new Promise(resolve => {
   
    import('baqi-doctor/src/pages/group/checkJoinInfo').then(vm => {
   
      resolve(Vue.component('CheckJoinInfo', {
   
        render: createElement => createElement(vm.default, {
   
          props: {
   
            blPath: '/patient/record',
            nextPatientPath: '/patientList'
          }
        })
      }))
    })
  })
}

涉及到知识点

路由懒加载

参考Vue-Router官方的路由懒加载示例,此处import返回的是个promise,Vue在需要使用到这个组件的时候才会调用Foo的then方法,获取组件

const Foo = () => import('./Foo.vue')

所以上述路由routes的comoptent可以直接返回一个promise

component: () => new Promise(resolve => {
   
//...

Vue.component

此API为Vue注册全局组件,最后返回组件本身,官方文档API用法如下

// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({
    /* ... */ }))

// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', {
    /* ... */ })

Vue.component和Vue.extend区别

Vue.extend使用基础 Vue 构造器,创建一个“子类”,实现继承,返回的是一个“扩展实例构造器”。Vue.extend生成的构造器和父类Vue一样,需要实例化后才能使用。

const Vue2 = Vue.extend({
    /* 预设选项 */ })
const vm2 = new myVue({
    /* 其他选项 */ })

Vue.component 是用来全局注册组件的方法,可直接使用this.$store或this.$router等功能。
也可将使用Vue.extend扩展后的构造器生成组件

Vue.component('my-component', Vue.extend({
    /* ... */ }))

渲染函数createElement

createElement函数接收三个参数
第一个为一个 HTML 标签名或者组件选项对象
第二个为与模板中 attribute 对应的数据对象
第三个参数为子组件
看官方示例

createElement('h1', '一则头条'),
createElement(MyComponent, {
   
  props: {
   
    someProp: 'foobar'
  }
})

第一个参数可以传入html标签名或者其他组件,第二参数用以扩展第一个参数,可以扩展html标签或是Vue的组件。
所以上述需扩展的组件可以使用createElement函数进行扩展

Vue.component('CheckJoinInfo', {
   
  render: createElement => createElement(vm.default, {
   
    props: {
   
      blPath: '/patient/record',
      nextPatientPath: '/patientList'
    }
  })
})