Dynamically import components and js module files in vue

This article mainly introduces the contents of vue as follows:

1. Dynamically introduce components in .vue files

2. Dynamically introduce js module files in .vue files

 

1. Dynamic introduction of components

Reasons for dynamically introducing components : In actual business, such as the order detail page detail.vue, it contains the order details of multiple third businesses, but different business detail pages are very different, so it can only be based on different business sources. Write different detailed components, and display the corresponding components according to the business source

Problem : If there are more and more business sources for detail docking, and different sources have high demand for customization of the detail page, more and more components will be added. If the components are directly introduced on the page, then it is useless The component will cause a waste of resources, cause the page file to be large, and the loading time becomes longer

The general writing is as follows, the components used in the page are directly imported

<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>

Dynamic introduction of vue component writing, the difference from the above writing is that the way of introducing components is different

Dynamic introduction of component syntax:

a) Introduce components in this way in the components property: BComponent: () => {'./b.vue'}

b) Use v-if to control the display in the template: <BComponent v-if="isShowBComponent" />

c) Set isShowBComponent to true if the conditions are met

<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>

Special Instructions:

1. When the route is placed in <keep-alive>, there is an activated attribute in the vue file

2. If there is activated attribute in BComponent

Dynamically introduced, the method in BComponent's activated will not be executed

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

If you don’t need to introduce components dynamically, the methods in BComponent’s activated will be executed

The reason why the method in activated is dynamically introduced:

When the component's life cycle method is initialized, activated will be collected. If it is dynamically imported, when the file is loaded, the time for activated to collect has passed, then naturally the methods in BComponent's activated will not be executed.

 

2. Dynamically introduce js module files in .vue files

Reasons for dynamic introduction : For example, the payResult.vue file represents the payment result page. In reality, we have many third-party business scenarios that jump to the payment result page after the payment is completed. Different third-party services on this page will have some personalized requirements. For example, services A and B need to be shared, and business C does not need to be shared. At this time, we put some logical processing of the sharing function in the handle.js file, and share.vue represents the sharing component. At this time, if the business source is not distinguished, the handle.js share.vue component is uniformly loaded on the page when entering the page, then the C business itself does not need to share the function, but also loads related files for sharing, which will cause unnecessary resource loading and waste the page Rendering performance

Ideal state : According to the business source, only load and share related files when it is A and B business, and not load when it is C business. At this time, it is necessary to dynamically import js module files.

Dynamic introduction of the approximate process

1) Generally, the entry page may call the corresponding interface to get the data, such as the order details interface. The data returned by the interface may have fields that can distinguish the business source, such as processNo

2) Handle.js can be dynamically introduced according to processNo

3) Dynamically import js file syntax: import('./share.js').then(res => {}), res is object, which is the content exported by share.js, if there is a named export as aa and default export, The result is res.default, res.aa

The sample code is as follows:

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)
    })
},
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/tangxiujiang/article/details/115022364