1

How the interactive receiver UI components are compatible with Vue2 and Vue3

Interactive receiver SDK

Polyway Cloud live broadcast products can initiate interactions such as sign-in, lottery, and questionnaires during the live broadcast process. Correspondingly, these interactions also need to be presented on the viewing side. In order to make Polyway Cloud live viewing page and customer-customized viewing page can easily access these functions, we have made the interactive function into an SDK, that is, the interactive receiver SDK.

The interactive receiver SDK is developed in strict accordance with the separation of logic and UI . Based on the logic layer, you can develop UIs with different interfaces, and even UIs with different technology stacks. The default UI is developed based on Vue.js 2.6.

As we all know, Vue.js 3.x has been officially released. If a set of UI components developed based on Vue.js 2.6 is used in a Vue.js 3.x project, an error will occur; if a set of UI components that can be adapted to Vue.js 3.x is re-developed, it is necessary to maintain two A set of codes is not conducive to subsequent function iterative updates.

This article mainly describes how to build two versions of Vue.js components on the basis of one code, so as to adapt to Vue.js 2.6 and Vue.js 3.x (the following will refer to Vue.js 2.6 and Vue.js 3 respectively). .x is abbreviated as Vue2 and Vue3).

Introduction to Vue2 and Vue3 Compatible Architecture

On the basis of the original code, the packages of Vue2 and Vue3 are compiled and constructed respectively.

  • Advantages: Subsequent functions are added or optimized, and the source code of interactive functions only needs to be changed once.
  • Disadvantage: Unable to reference UI component libraries that are not compatible with Vue2 and Vue3. Cannot use Vue2, Vue3 incompatible syntax, including Vue3 new features.

未命名文件 (5).png

Set up a Vue3 build environment for UI component projects

The original UI component project directory structure is as follows:

  • directory ui

    • directory vue2

      • directory build
      • directory src
      • file package.json
      • ..

In order to build a Vue3 build environment, create a new vue3 directory in the ui directory, and copy all configuration files except src in the vue2 directory. The directory structure is as follows:

  • directory ui

    • directory vue2

      • directory build
      • directory src
      • file package.json
      • ...
    • directory vue3

      • directory build
      • file package.json
      • ...

Next, modify the configuration file in the vue3 directory, update vue to 3.1 in package.json, install the same version of @vue/compat and @vue/compiler-sfc , and add vue- loader upgrade to above 16

 "dependencies": {
-  "vue": "^2.6.12",
+  "vue": "^3.1.0",
+  "@vue/compat": "^3.1.0",
-  "vue-loader": "15.9.7"
+  "vue-loader": "16.0.0"
   ...
},
"devDependencies": {
+  "@vue/compiler-sfc": "^3.1.0"
}

After setting the alias @vue/compat for vue in Webpack's build configuration, incompatible code snippets in Vue3 can be detected.
Set the webpack entry file path to point to the source code in the src directory.

 const srcDirname = path.resolve(__dirname, '../../vue2/src');
module.exports = {
    entry: path.join(srcPath, 'main.js'),
    resolve: {
        alias: {
            vue: '@vue/compat',
            '@': srcDirname
        }
    },
    ...
}

The environment is now set up.

Handling code compatibility issues

After running the project, there are still problems opening the demo page, and abnormal information appears in the console. These problems need to be fixed before the project can run normally.

The problem is mainly caused by the following reasons: (For more compatibility issues, refer to the official documentation )

  • Vue2 and Vue3 create nodes through extend and createApp respectively
  • In Vue3 $options property cannot be modified
  • Vue3 does not support filter filter
  • Vue3 does not support slot syntax below 2.6
  • Vue3 does not support global methods $set
  • Life cycle destroy and beforeDestroy, renamed unmounted and beforeUnmount in Vue3

Vue2 and Vue3 create nodes through extend and createApp respectively

For code that cannot be run in Vue2 and Vue3 at the same time, two sets of codes can be written separately by judging the version number

 import Vue from 'vue';
function isVue3() {
    return Vue.version.startsWith('3.');
}

if(isVue3()) {
    // Vue3 环境代码
    const TipApp = Vue.createApp(SubmitTip, propsData);
    TipApp.mount(wrapContain);
    // 业务代码...
} else {
    // Vue2 环境代码
    const Componet = Vue.extend(SubmitTip, propsData);
    const TipApp = new Componet({
        propsData
    });
    TipApp.$mount(wrapContain);
    // 业务代码...
}

In Vue3 $options property cannot be modified

Reason: In Vue2 $options can be modified dynamically, but in Vue3 $options properties are only readable and cannot be modified.

Solution: Move the logic code originally placed in $options to data() .

 // 原来的写法
export default {
  $i18n: null,
  provide() {
    // 初始化多语言实例
    this.$options.$i18n = new I18n(this.$options.langs);
    // 设置响应式语言属性
    this.$options.$i18n.updateLocale(() => this.lang);
    return {
      getI18n: () => this.$options.$i18n
    };
  },
  ...
}

// 替代写法
export default {
  data() {
    return {
      _i18n: null
    }
  }
  provide() {
    // 初始化多语言实例
    this._i18n = new I18n(this.langs);
    // 设置响应式语言属性
    this._i18n.updateLocale(() => this.lang);
    return {
      getI18n: () => this._i18n,
    };
  },
  ...
}

Vue3 does not support filter filter

You can use methods instead of filter. E.g:

 <!-- 过滤器filter写法 -->
 <div> {{ date  |  dateFilter }}</div>

<!-- methods写法 -->
 <div> {{ dateFilter(date) }}</div>

Vue3 does not support slot syntax below 2.6

Runs both Vue2 and Vue3 using the latest slot syntax. E.g:

 <!-- 废弃语法-->
<template>
    <template slot="header">
      <h1> title </h1>
    </template>
</template>
 <!--2.6语法-->
<template>
    <template v-slot:header>
      <h1> title </h1>
    </template>
</template>

image.png

Vue3 does not support global methods $set

Reason: Removed in Vue3 $set .

Solution: Avoid using $set , you can make sure that object properties have been handled reactively when defining or assigning objects and arrays in data() .

 <!--错误示例-->
<template>
    <div v-for="(item,index) in list">
        名字:{{ item.name }},
        性别:{{ item.sex }},
    </div>
</template>
<script>
export default {
    data() {
        return {
            list: []
        }
    },
    mounted() {
      this.list.push({name: '张三'})
      // 在vue3中不生效
      this.$set(this.list[0], 'sex', 'man');
    }
}
</script>
 <!--正确示例-->
<template>
    <div v-for="(item,index) in list">
        名字:{{ item.name }},
        性别:{{ item.sex }},
    </div>
</template>
<script>
export default {
    data() {
        return {
            list: []
        }
    },
    mounted() {
      this.list.push({name: '张三', sex: 'man'})
    }
}
</script>

Life cycle destroy and beforeDestroy, renamed unmounted and beforeUnmount in Vue3

Use different method names by version judgment.

 export const BEFORE_DESTROY = isVue3() ? 'beforeUmount' : 'beforeDestory';
export const DESTORY = isVue3() ? 'unmounted' : 'destory';
 import { BEFORE_DESTROY } from '@/assets/utils/compat';

export default {
  [BEFORE_DESTROY]() {
    // 业务代码...
  }
}

ws
4 声望0 粉丝