最近在嘗試使用vue3,整理了一些和vue2在使用上的一些區別css
vue2
的script
結構<template> <div> </div> </template> <script> export default { name: '', components: {}, props: {}, data() { return {} }, watch: {}, created() {}, mounted() {}, methods: {} } </script> <style lang="scss" scoped></style>
vue3
的script
結構<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 ()
內部調用生命週期鉤子:html
選項式 API | Hook inside setup |
---|---|
beforeCreate | Not needed* |
created | Not needed* |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
//import { ref } from 'vue'; const count = ref(0) console.log(count.value) // 0 count.value++ console.log(count.value) // 1
變量的聲明有點相似於react
的State Hook
vue
推薦使用reactive包裹數組,react
//import { reactive } from 'vue'; const state = reactive({ arr: [] }); state.arr = [1, 2, 3]
或者git
const state = ref([]) state.value = [1, 2, 3]
或者api
const arr = reactive([]) arr.push(...[1, 2, 3])
這幾種辦法均可以觸發響應性,而後界面中正常使用v-for
便可,推薦第一種數組
父子組件傳值的寫法ide
<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>
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>
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 / Injectui
watch: { count: { handler: function(val, oldval) {}, immediate: true, deep: true } }
setup() { const count = ref(0) //監聽count watch( () = > count, (_count, _prevCount) = > {}, { deep: true, immediate: true } ); }
後續遇到其餘問題慢慢補充