最近在尝试使用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 } ); }
后续遇到其余问题慢慢补充