vue中动态引进组件、动态引进js模块文件

本文主要介绍vue内容如下:

1、在.vue文件中动态引进组件

2、在.vue文件中动态引进js模块文件

一、动态引进组件

动态引进组件原因:在实际业务中,比如订单详情页面detail.vue,里面包含了多个第三业务的订单详情,但是不同的业务详情页面区别又很大,所以只能根据不同的业务来源,书写不同的详情组件,在根据业务来源展示相应的组件

问题:如果详情对接的业务来源越来越多,并且不同的来源对于详情页面定制化需求又高,这样就会增加越来越多的组件,如果在页面都是直接引进组件,那么没用到的组件就会造成资源浪费,导致页面文件大,并在加载时间变长

一般写法如下,页面中用到的组件都直接引进来

<template>
  <div>
    <Bcomponent v-if="isShowBComponent" />
    <CComponent v-else-if="isShowCComponent" />
    <p v-else-if="isShowPage">show another something</p>
  </div>
</template>

<script>
// 直接引进来,不必要的组件也加载,造成页面体积增大
import BComponent from './b.vue'
import CComponent from './c.vue'

export default {
  data() {
    return {
      isShowBComponent: false,
      isShowCComponent: false,
      isShowPage: false,
      condition: 0
    }
  },
  components: {
    BComponent,
    CComponent
  },
  mounted() {
    this.gtDataFromInterface()
  },
  methods: {
    gtDataFromInterface() {
      // 通过接口拿到数据后,根据字段返回值,确定要展示那个组件,比如接口返回字段condition,根据它的返回值展示
      // 在这里赋值
      this.condition = condition
      this.handleShowPage()
    },
    handleShowPage() {
      if (this.condition === 1) {
        this.isShowBComponent = true
      } else if (this.condition === 1) {
        this.isShowCComponent = false
      } else {
        this.isShowPage = true
      }
    }
  }
}
</script>

动态引进vue组件写法,和上面写法不同的地方就是引进组件的方式不一样

动态引进组件语法:

a)在components属性里面用这种方式引进组件:BComponent: () => {'./b.vue'}

b)在template中用v-if控制展示:<BComponent v-if="isShowBComponent" />

c)在符合的条件下将isShowBComponent设置为true

<template>
  <div>
    <Bcomponent v-if="isShowBComponent" />
    <CComponent v-else-if="isShowCComponent" />
    <p v-else-if="isShowPage">show another something</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShowBComponent: false,
      isShowCComponent: false,
      isShowPage: false,
      condition: 0
    }
  },
  components: {
    // 动态引进,当isShowBComponent=true的时候,才会真正加载BComponent组件文件
    BComponent: () => import('./b.vue'),
    CComponent: () => import('./c.vue')
  },
  mounted() {
    this.gtDataFromInterface()
  },
  methods: {
    gtDataFromInterface() {
      // 通过接口拿到数据后,根据字段返回值,确定要展示那个组件,比如接口返回字段condition,根据它的返回值展示
      // 在这里赋值
      this.condition = condition
      this.handleShowPage()
    },
    handleShowPage() {
      if (this.condition === 1) {
        this.isShowBComponent = true
      } else if (this.condition === 1) {
        this.isShowCComponent = false
      } else {
        this.isShowPage = true
      }
    }
  }
}
</script>

特殊说明:

1、当路由放在<keep-alive>里面,则vue文件里面就有activated属性

2、如果BComponent里面有activated属性

动态引进的化,BComponent的activated里面的方法就不会执行

 components: {
    // 动态引进,当isShowBComponent=true的时候,才会真正加载BComponent组件文件
    BComponent: () => import('./b.vue'),
    CComponent: () => import('./c.vue')
  }

如果不用动态引进组件的方式,则BComponent的activated里面的方法会执行

动态引进activated里面的方法不执行原因:

在初始化组件的声明周期方法的时候,就会对activated进行收集,如果是动态引进,则当文件加载完成时候,已经过了activated进行收集的时机,那么自然BComponent的activated里面的方法不会执行

二、在.vue文件中动态引进js模块文件

动态引进原因:比如payResult.vue文件表示支付结果页面,现实中我们有很多第三方业务场景在支付完成之后跳转到支付结果页面,在该页面不同的第三方业务会有一些个性化的需求,比如A、B业务需要做分享功能,C业务不需要做分享功能,这时候我们将分享功能的一些逻辑处理放在了handle.js文件里面,share.vue表示分享组件。这时候如果不区分业务来源,一进页面统一加载handle.js  share.vue组件,那么C业务本身不需要分享功能,但也加载了分享的相关文件,这会造成不必要的资源加载,浪费页面渲染性能

理想状态:根据业务来源,当为A、B业务的时候才加载分享相关文件,当为C业务则不加载,这时候就需要动态引进js模块文件了

动态引进大概流程

1)一般进页面可能会调相应的接口拿数据,比如订单详情接口,该接口返回的数据可能有可以区分业务来源的字段,比如processNo

2)可以根据processNo来动态引进handle.js

3)动态引进js文件语法:import('./share.js').then(res => {}),res为object,是share.js导出的内容,如果有具名导出为aa和默认导出,则结果为res.default,res.aa

示例代码如下:

payResult.vue

<template>
  <div>
    <Sahre  :isShow="shareData.isShow" :dataInfo="shareData.dataInfo" @click="shareData.closeEvent"/>
  </div>
</template>

<script>
export default {
  components: {
    // 动态引进组件
    Share: () => import('./share.vue')
  },
  data() {
    return {
      shareData: {
        isShow: false,         // 控制组件的显隐,
        dataInfo: {},          // 组件的数据
        closeEvent: () => {}   // 组件的关闭事件
      }
    }
  },
  mounted() {
    this.getInitData()
  },
  methods: {
    getInitData() {
      // 通过接口拿到数据,判断是某服务,serviceName
      let flag1 = serviceName === 'daiJia'
      let flag2 = serviceName === 'battery'
      if (flag1 || flag2) {
        // 这种动态引进的方式,会返回一个Promise
        import('./share.js').then(res => {
          // share.js是默认导出,所以通过res.default拿到数据
          this.shareData = res.default
          // 根据相应的服务,调用相应的方法
          if (flag1) {
            // 这里要把组件实例传过去
            this.shareData.getSetDaiJiaData(this)
          } else if (flag2) {
            this.shareData.getSetBatteryData(this)
          }
        })
      }
    }
  }
}
</script>

share.js

export default {
  isShow: false,
  dataInfo: {},
  closeEvent: () => {
    // 注意这里要用箭头函数,才能拿到this对象,并且this指向的是该文件导出的内容,即有个default属性的对象
    // 如果用一般的声明方式,则this为null
    this.default.isShow = false
  },
  getSetDaiJiaData(vm) {
    // 通过接口那数据
    // 这里不能通过this.$store去访问,需要在调用的地方传vm进来
    vm.$store.dispatch('').then(res => {
      this.isShow = res.isShow
      this.dataInfo = res.data
    }).catch(err => {
      console.error(err)
    })
  },
  getSetBatteryData(vm) {
    // 通过接口那数据
    vm.$store.dispatch('').then(res => {
      this.isShow = res.isShow
      this.dataInfo = res.dataInfo
    }).catch(err => {
      console.error(err)
    })
},
}

猜你喜欢

转载自blog.csdn.net/tangxiujiang/article/details/115022364
今日推荐