# Migrate from the vue2 project to vue3, parts to be adapted to

The following are the points that must be adapted for migration to vue3, so that the vue2 project can run normally on vue3. For more inlistation, see the complete List of non-compatible features (opens new window)

  • main.js

    • Create an application instance

      // Before - Vue 2
      import Vue from 'vue'
      import App from './App'
      // with no need for vue3
      Vue.config.productionTip = false
      // vue3 is no longer needed
      App.mpType = 'app'
      const app = new Vue({
      ...App
      })
      app.$mount()
      
      // After - Vue 3
      import App from './App'
      import { createSSRApp } from 'vue'
      export function createApp() {
         const app = createSSRApp(App)
         return {
            app
         }
      }
      
    • Global attributes, for example: global network request

    // Before - Vue 2
    Vue.prototype.$http = () => {};
    
    // After - Vue 3
    const app = createApp({});
    app.config.globalProperties.$http = () => {};
    
    • Plug-in use, for example: use store of vuex
    // Before - Vue 2
    import store from "./store";
    Vue.prototype.$store = store;
    
    // After - Vue 3
    import store from "./store";
    const app = createApp(App);
    app.use(store);
    
  • The project root directory must create a index.html file, copy and paste the following contents:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
        <title></title>
        <!--preload-links-->
        <!--app-context-->
      </head>
      <body>
        <div id="app"><!--app-html--></div>
        <script type="module" src="/main.js"></script>
      </body>
    </html>
    
  • Only the use of ES6 module specification is supported, and commonJS needs to be changed to ES6 module specification

    • Module import, e.g.:

      //Before - Vue 2, use commonJS
      var utils = require("../../../common/util.js");
      
      //After - Vue 3, only ES6 module is supported
      import utils from "../../../common/util.js";
      
    • Module export, e.g.:

      //Before - Vue 2, if dependent, export using commonJS
      module.exports.X = X;
      
      //After - Vue 3, can be manually changed to ES6 for export
      export default { X };
      
  • vuex Usage

    // Before - Vue 2
      import Vue from 'vue'
      import Vuex from 'vuex'
      Vue.use(Vuex)
      const store = new Vuex.Store({
          state: {}
      })
      export default store
    
    // After - Vue 3
      import { createStore } from 'vuex'
      const store = createStore({
          state: {}
      })
      export default store
    
  • Avoid using v-if and v-for on the same element at the same time

    However, in Vue3, v-if always become valid before v-for. The above writing will be inconsistent with expectations in Vue3. Because of grammatical ambiguity, it is recommended to avoid using both on the same element (More details (opens new window)).

  • Adaptation of life cycle

    In Vue3, the life cycle of component uninstallation is renamed

    • destroyed is modified to unmounted
    • beforeDestroy is modified to beforeUnmount
  • Adaptation of events

    Vue3 now provides a emits option, similar to the existing props option. This option can be used to define the events that a component can emit to its parent object, More details (opens new window)

    It is strongly recommended to use emits to record all events emitted by each component.

    This is particularly important because the .native modifier has been removed. emits Now all listeners for unused declared events will be included in the component $attrs. By default, the listener will be bound to the root node of the component.

    <template>
      <button @click="onClick">OK</button>
    </template>
    <script>
    export default {
      emits: ['click'],
      methods:{
        onClick(){
          this.$emit('click', 'OK')
        }
      }
    }
    </script>
    
  • Adaptation of v-model v-model of Vue3 has changed greatly when compared with Vue2. You can use multiple model, and the corresponding syntax has also changed. More (opens new window)

    • ... When modelValue is modified for custom components, the default names of Vue3 v-model props and events have been changed. props.value is changed to props.modelValue and event.value is changed to update:modelValue

      export default {
        props: {
          // value:String,
          //Replace value as modelValue
          modelValue:String
        }
      }
      
  • Event return: Change the previous this.$emit('input') to this.$emit('update:modelValue'), this step will be omitted in vue3

    The v-model on the custom component is equivalent to passing the modelValue prop and receiving the thrown update:modelValue event:

      <ChildComponent v-model="pageTitle" />
      
      <!-- Abbreviation for the following: -->
      
      <ChildComponent
        :modelValue="pageTitle"
        @update:modelValue="pageTitle = $event"
      />
    

    If the model name needs to be changed, as an alternative to the model option in the component, we can now pass an argument to v-model:

      <ChildComponent v-model:title="pageTitle" />
      
      <!-- Abbreviation for the following: -->
      
      <ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
    
  • Adaptation of slots

    Vue3 will not support the usage of slot="xxx", please use v-slot:xxx usage. More (opens new window)

    <!-- Usage supported by Vue2 -->
    <uni-nav-bar>
      <view slot="left" class="city">
        <!-- ... -->
      </view>
    </uni-nav-bar>
    
    <!-- Usage supported by Vue3 -->
    <uni-nav-bar>
      <template v-slot:left>
        <view class="city">
          <!-- ... -->
        </view>
      </template>
    </uni-nav-bar>
    
  • From Vue 3.0+, filters have been deleted and are no longer supported, it is recommended to replace them with method calls or computed attributes. More (opens new window)