21

trying to use vue3 recently, and I sorted out some differences in the use of

1. Code structure changes

1.1 vue2 of script structure

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

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

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

1.2 vue3 of script structure

<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>
Because setup runs around beforeCreate and created lifecycle hooks, there is no need to define them explicitly. In other words, any code written in these hooks should be written directly in the setup function.

The following table contains how setup () call the life cycle of the hook inside:

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

2. Variable declaration and assignment

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

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

The variable declaration is somewhat similar to react of State Hook

3. Object/array declaration and assignment (responsiveness)

It is recommended to use reactive wrapping arrays,

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

state.arr = [1, 2, 3]

or

const state = ref([])

state.value = [1, 2, 3]

or

const arr = reactive([])

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

These methods can trigger responsiveness, and then v-for normally in the interface. The first one is recommended.

4. props/$emit

How to write parent-child components by value

  • Parent component
<Search @searchData="searchData" :quaryParams="quaryParams"/>

The parent component is written in the vue , but the child component needs to be changed.

  • Subassembly
<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 write 0614a8d8109c0d

  • Parent component
<!-- 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>
  • Subassembly
<!-- src/components/MyMarker.vue -->
<script>
export default {
  inject: ['location', 'geolocation']
}
</script>

5.2 vue3 write 0614a8d8109c82

  • Parent component
<!-- 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>
  • Subassembly
<!-- 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>

More can read 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. Reset data

In vue2 we can use this.$options.data.xxx to reset the initial value of a certain data
Vue3 currently only explores that only this can be used

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

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

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

    return { form, resetForm };
  }

8. Get $.XXX

For example, $forceUpdate forces the component instance to re-render

<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. Define global variables

Take axios as an example

vue2

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

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

Use 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'],

WX20210922-091703.png


雾岛听风
12.1k 声望8.7k 粉丝

丰富自己,胜过取悦别人。