An overview of the

Since Vite2 also supports VUE2 and native TS, I would like to try whether VUE2 can be smoothly transited to VUE3 and see the differences between them. I will try to write vuE2 in the same way as I used to write VUE3. Two days ago, I mentioned two vuE2 component libraries, view-UI and Element-UI, which are supported by THE PR for the Ite – plugin-Components. Will there be any problems in using them in real projects

Project structures,

Vite2 support vue2

Install dependencies:

    "vite-plugin-vue2": "^ 1.7.2." ".Copy the code

Configuration vite. Config:

import { createVuePlugin } from "vite-plugin-vue2";
export default defineConfig({
  plugins: [createVuePlugin()]
})
Copy the code

Install the template compiler

It is used to parse the VUE2 file. The version corresponds to vuE2

 "vue-template-compiler": "^ 2.6.14".Copy the code

Support JSX/TSX composite

Plug-in support

Simply configure JSX to be enabled in the createVuePlugin plugin

 createVuePlugin({
      jsx: true,})Copy the code

Declaration in use

Adding a declaration file

Create a new shim-tsx.d.ts in SRC,

// file: shim-tsx.d.ts
import Vue, { VNode } from 'vue';
import { ComponentRenderProxy } from '@vue/composition-api';

declare global {
  namespace JSX {
    interface Element extends VNode {}
    interface ElementClass extends ComponentRenderProxy {}
    interface ElementAttributesProperty {
      $props: any; // specify the property name to use
    }
    interface IntrinsicElements {
      [elem: string] :any; }}}Copy the code

Support for ts

Install dependencies

Install typescript dependencies and the Vue compiler

 "typescript": "^ 4.1.3." "."vue-tsc": "^ 0.1.7"
Copy the code

File name replacement TS

Change the entry file js to ts and the index. HTML entry file to main.ts

 <script type="module" src="/src/main.ts"></script>
Copy the code

Add a type declaration file

  • add.vuefiletsThe statement, andmain.tsNew directory at the same levelshims-vue.d.ts,
declare module "*.vue" {
  import Vue from "vue";
  // eslint-disable-next-line prettier/prettier
  export default Vue;
}

Copy the code

Support for vuE3 features (with inclusion API)

Install dependencies

"@vue/composition-api": "^ 1.0.3".Copy the code

The main function comes in and uses it

import VueCompositionAPI from "@vue/composition-api";
Vue.use(VueCompositionAPI);
Copy the code

Problems encountered

This API needs to be introduced first because some of the dependent libraries also use the compositionApi and will report an error if the order is reversed

Configuring component Libraries

 "view-design": "^ 4.6.1." "."element-ui": "^ 2.15.3".Copy the code

Additional dependent

Vite does not recognize the commonJS syntax require in view-UI, so you need to install a plug-in to solve the problem

"@originjs/vite-plugin-commonjs": "^ 1.0.0 - beta6".Copy the code
import { viteCommonjs } from "@originjs/vite-plugin-commonjs";
export default defineConfig({
    plugins: [
         viteCommonjs(),
    ]
})
Copy the code

Configuration vite

import ViteComponents, {
  ElementUiResolver,
  ViewUiResolver,
} from "vite-plugin-components";

export default defineConfig({
    plugins: [
         ViteComponents({
               dirs: ["src/views"].// Scan the paths of user-defined components. The relative path can be configured./
               customComponentResolvers: [
                   ViewUiResolver(),
                   ElementUiResolver(),
               ]
         })
    ]
})

Copy the code

Set alias

Configuration vite. Config

import path from "path";
export default defineConfig({
  // Configure the alias
  resolve: {
    alias: [{find: "@".replacement: path.resolve(__dirname, "src"),},],},})Copy the code

Change the tsconfig. Json

Configuration Add the following two configurations to avoid the following error message displayed on the import interface in the TS file

Cannot find module ‘@/hooks/useForm’ or its corresponding type declarations.Vetur(2307)

{
  "compilerOptions": {
    / /... slightly
    "baseUrl": "src"."paths": {
      "@ / *": [". / *"]}},/ /... slightly
}
Copy the code

Problems encountered

Start the configuration of the above two items still do not work, or error, restart VScode is good

vue-router

Vue2 can only use Vue-Router3

  • Install dependencies
 "vue-router": "^ 3.5.2." ".Copy the code
  • Configured to use

Same as before

import Vue from 'vue'
Vue.use(Router);
export default new Router({
  // mode:'history',
  routes: [{path: '/'.component: () = >  import("@/views/index.vue"),},]});Copy the code

Using pinia

Install dependencies:

The vuE2 version can only be used in Pinia1.

pinia@next install Pinia v2 for Vue 3. If your app is using Vue 2, you need to install Pinia v1: pinia@latest and @vue/composition-api. If you are using Nuxt, you should follow these instructions.

But I used pinia@latest to let me choose the version, I did not find the 1.0 version, should refer to the 0. X version, if using 2

    "pinia": "^ 0.5.2".Copy the code

Load and import component libraries on demand

Use vite-plugin-Components to implement on-demand loading. Version 0.13.0 supports view-UI and Elemental-UI, two of the more mainstream component libraries

Install dependencies:

"vite-plugin-components": "^ 0.13.0".Copy the code

Used in projects

//main.ts
import { createPinia, PiniaPlugin } from 'pinia'
Vue.use(PiniaPlugin)
const store = createPinia();
new Vue({
  el: "#app",
  router,
  pinia:store,// Use a plugin to get this property
  render: h= > h(App),
});
Copy the code

Problems encountered

In the past, I used to create a store folder, create an index.ts folder, import it into the main. Ts folder, but I always told you that the compositionAPi was not introduced, even if I had introduced it at the top of the main. But only to introduce pinia in main, not much also just a sentence

A pit in the development of a project

The VEtur of the TSX reported an error

Description: when setting the size property of a button in the view-UI table using TSX to dynamically render columns, the error is displayed:

Property ‘size’ does not exist on type ‘ComponentOptions<Vue, DefaultData, DefaultMethods, DefaultComputed, PropsDefinition, DefaultProps>’.Vetur(2769)

The size property of ts is defined as a non-mandatory property

Solution: Today update vscode found no error, pretty pit ~

Vue2 defines a TSX error in setup

Description: The following error message is displayed:

Cannot read property ‘$createElement’ of undefined

Solution: Found that the setup function should be injected into the setup, check the setup parameters passed in the definition did not find the definition of the render function, but only write in the data function, the render function can be successfully injected in

Properties added dynamically do not take effect immediately

$set = $set(item,’editing’,!!); $set = $set(item,’editing’,!!); item.editing)

Use of shared data in hooks is not reactive

Description: similar to const data = todostore. total; This form, and then computed the other variables using data, will lose the response in VUE2, but vuE3 is normal

//vue3
  const data: UnwrapRef<DataItem[]> = todoStore.total;
  const unfinish = computed(() = >
    data.filter((item: DataItem) = >item.finish ! =true));const finishes = computed(() = > data.filter((item: DataItem) = > item.finish));
Copy the code

Solution: Use the state attribute of store for computed

//vue2
  const unfinish = computed(() = >
  todoStore.total.filter((item: DataItem) = >item.finish ! =true));const finishes = computed(() = >  todoStore.total.filter((item: DataItem) = > item.finish));
Copy the code

Pinia deleting data does not trigger interceptors

Description: The following method can be used to delete the array data and enter the interceptor in VUE3, but not in VUE2

//vue3
  const clearAll = () = > {
    todoStore.$state.total.length = 0; // The interceptor is not triggered if $reset is used
  };
Copy the code

Solution: After testing, pinia’s interceptor test results are as follows:

//vue2
  const clearAll = () = > {
    Todostore. $state. Total =[] todostore. $state
    // TodoStore. $state.total. Length = 0
    // vue.set (todostore.$state. Total,'length',0
    todoStore.$state.total.splice(0,todoStore.$state.total.length)// This is the only way to trigger all deletions. reset length to 0 does not work
  
  };

Copy the code

Reference documentation

Summary of successful use of Vite in VUE2 environment!!

The code address

Main project: github: github.com/nabaonan/to…

The vuE2 project directory is VUe2-vite-TS

Welcome to star ~

conclusion

In general, the TS version of vue2 is very close to vue3 if it works with the compositionApi. The element version of vuE2 is a direct copy of vue3 code, which has very few changes. Element-plus and Element-UI are also the same thing, and both pages can be reused. There is a small bug, however, that popConfirm does not include the popover style. This has been fixed in Element-Plus, and element-UI is left alone. Can only introduce their own style to solve, other all good. Vue2.7 is supposed to have built-in compositionApi. In that case, vuE3 code will be copied directly and will not need to be changed. Vue2 also has some unsupported functions, such as the emit function. The emit needs to be externally passed into the hooks function.

Recently, I found that a big guy in VUE2 mentioned a huge PR that reconstructs VUE2 into TS. I really appreciate the big guy who is a ten times engineer. I hope he will be included soon