vue3与vue2使用的一些对比

Posted JenK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3与vue2使用的一些对比相关的知识,希望对你有一定的参考价值。

最近在尝试使用vue3,整理了一些和vue2在使用上的一些区别

1. 代码结构变化

1.1 vue2script结构

<template>
  <div>
  </div>
</template>

<script>
export default {
  name: \'\',
  components: {},
  props: {},
  data() {
    return {}
  },
  watch: {},
  created() {},
  mounted() {},
  methods: {}
}
</script>

<style  lang="scss" scoped></style>

1.2 vue3script结构

<template> </template>
<script lang="ts">
  import { defineComponent, onMounted, reactive, UnwrapRef, watch } from \'vue\';

  interface State {}
  export default defineComponent({
    name: \'components name\',
    props: {},
    setup(props) {
      console.log(\'props: \', props);
      //data
      const state: UnwrapRef<State> = reactive({});

      //Lifecycle Hooks
      onMounted(() => {});
      //watch
      watch(
        () => props,
        (_count, _prevCount) => {},
        {
          deep: true,
          immediate: true,
        }
      );
      //methods
      const getList = () => {};
      
      return {
        state,
        getList
      };
    },
  });
</script>
<style lang="scss" scoped></style>
因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。

下表包含如何在 setup () 内部调用生命周期钩子:

选项式 APIHook inside setup
beforeCreateNot needed*
createdNot needed*
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered

2. 变量的声明与赋值

//import { ref } from \'vue\';
const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

变量的声明有点类似于reactState Hook

3. 对象/数组的声明与赋值(响应性)

推荐使用reactive包裹数组,

//import { reactive } from \'vue\';
const state = reactive({
  arr: []
});

state.arr = [1, 2, 3]

或者

const state = ref([])

state.value = [1, 2, 3]

或者

const arr = reactive([])

arr.push(...[1, 2, 3])

这几种办法都可以触发响应性,然后界面中正常使用v-for即可,推荐第一种

4. props/$emit

父子组件传值的写法

  • 父组件
<Search @searchData="searchData" :quaryParams="quaryParams"/>

父组件的写法和vue还是一样的,只是子组件需要作一些改变

  • 子组件
<script lang="ts">
import { defineComponent } from \'vue\';
interface GetUserListParams {
    pageNum: number;
    pageSize: number;
    roleName: string;
}
export default defineComponent({
    name: \'Search\',
    props: {
        quaryParams: {
            type: Object as PropType<GetUserListParams> ,
            default: () = > ({
                pageNum: 1,
                pageSize: 10,
                roleName: \'\'
            })
        }
    },
    emits: [\'searchData\'],//需要声明emits
    setup(_props, context) {
    
      const onSubmit = () => {
        context.emit(\'searchData\', "我是子节点传递给父节点的值");
      }
      
      return {
        getData
      }
    }
});
</script>

5. Provide / Inject

5.1 vue2写法

  • 父组件
<!-- src/components/MyMap.vue -->
<template>
  <MyMarker />
</template>

<script>
import MyMarker from \'./MyMarker.vue\'

export default {
  components: {
    MyMarker
  },
  provide: {
    location: \'North Pole\',
    geolocation: {
      longitude: 90,
      latitude: 135
    }
  }
}
</script>
  • 子组件
<!-- src/components/MyMarker.vue -->
<script>
export default {
  inject: [\'location\', \'geolocation\']
}
</script>

5.2 vue3写法

  • 父组件
<!-- src/components/MyMap.vue -->
<template>
  <MyMarker />
</template>

<script>
import { provide, reactive, ref } from \'vue\'
import MyMarker from \'./MyMarker.vue

export default {
  components: {
    MyMarker
  },
  setup() {
    const location = ref(\'North Pole\')
    const geolocation = reactive({
      longitude: 90,
      latitude: 135
    })

    provide(\'location\', location)
    provide(\'geolocation\', geolocation)
  }
}
</script>
  • 子组件
<!-- src/components/MyMarker.vue -->
<script>
import { inject } from \'vue\'

export default {
  setup() {
    const userLocation = inject(\'location\', \'The Universe\')
    const userGeolocation = inject(\'geolocation\')

    return {
      userLocation,
      userGeolocation
    }
  }
}
</script>

更多可阅读Provide / Inject

6. watch

  • vue2
watch: {
    count: {
      handler: function(val, oldval) {},
      immediate: true,
      deep: true
    }
}
  • vue3
 setup() {
     const count = ref(0)
     //监听count
     watch(
         () = > count, (_count, _prevCount) = > {}, {
             deep: true,
             immediate: true
         }
     );
 }

7.重置数据

在vue2里我们可以使用this.$options.data.xxx来重置某个数据的初始值
vue3目前只探索出只有这个可以用

  setup() {
    const initialState = {
      name: "",
      lastName: "",
      email: ""
    };

    const form = reactive({ ...initialState });

    function resetForm() {
      Object.assign(form, initialState);
    }

    return { form, resetForm };
  }

8.获取$.XXX

比如$forceUpdate迫使组件实例重新渲染

<template>
  <div>
    <div>{{arr}}</div>
    <button @click="handleClick">add</button>
  </div>
</template>
<script lang="ts">
import { defineComponent, getCurrentInstance } from "vue";

export default defineComponent({
  setup() {
    const { ctx: _this }: any = getCurrentInstance()
    let arr = [1]
    const handleClick = () => {
      arr.push(2)
      _this.$forceUpdate()
    }
    return {
      arr
    };
  },
});
</script>

9.定义全局变量

以axios为例

vue2

import axios from \'axios\'
Vue.prototype.$axios = axios

使用this.$axios.xxx

vue3-global-api

Vue.prototype Replaced by config.globalProperties
import axios from \'axios\';

const app = Vue.createApp(App);
app.config.globalProperties.$axios = axios;

使用this.$axios.xxx

vue3-provide/inject

Provide

import axios from \'axios\';

const app = Vue.createApp(App);
app.provide(\'$axios\', axios); 

Inject

Composition API:

const { inject } = Vue;
...
setup() {
  const $axios = inject(\'$axios\');   
  // $axios.get(...)
}

Options API:

inject: [\'$axios\'],

以上是关于vue3与vue2使用的一些对比的主要内容,如果未能解决你的问题,请参考以下文章

vue3对比vue2

vue3,对比 vue2 有什么优点?

想知道Vue3与Vue2的区别?五千字教程助你快速上手Vue3!

vue2和vue3的基础用法对比第二篇

vue2.0与vue3.0 循环渲染对比

Vue3和Vue2对比,我们如何选用?