vue3中提供了深只读/浅只读,实现就是递归的方式,所以按需去使用即可,下面提供一些个人的思考
不可变的优点与缺点
优点:
- 不可变是函数式编程中重要思想,因其不可变,所以规避潜在因为引用而出现的问题
- vue3提供的readonly/shadowReadonly有硬性的控制台提示,可以实时看到,搭配上github的工作流可以达到无法构建的硬性效果(硬性可以让团队变得更好)
- 优异的错误定位
缺点:
- 对于规范的团队,画蛇添足
- 因为深只读是递归实现,同时伴随着深拷贝,它们需要更多的内存
例子1
// App.vue
<script setup>
import {ref, readonly} from "vue";
import HelloWorld from '@/components/HelloWorld.vue'
const user = ref({})
const updateUser = (value) => {
user.value = value
}
</script>
<template>
<HelloWorld msg="Vite + Vue" :user="readonly(user)" @update:user="updateUser"/>
</template>
// HelloWorld.vue
<script setup>
import {ref} from 'vue'
const props = defineProps({
msg: String,
user: Object
})
const emit = defineEmits([
'update:user',
])
const count = ref(0)
const test = () => {
emit('update:user', {
...props.user,
newProp: 1
})
}
</script>
<template>
<h1>{{ msg }}</h1>
<p>{{user.newProp}}</p>
<button type="button" @click="test">change</button>
</template>
例子2
<script setup>
import {ref, readonly} from "vue";
import {useRoute, useRouter} from "vue-router";
import { pipe } from 'ramda'
import { useUserStore } from 'store/user'
const route = useRoute()
const router = useRouter()
const userStore = useUserStore
const navigateToDetail = pipe(
function genQuery(query) {
query.owner = userStore.userId
return query
},
// 自己试一下即可
// function genQuery(query) {
// const result = {...query}
// result.owner = userStore.userId
// return result
// },
function navigate(query) {
router.push({
path: '/detail',
query
})
}
)
</script>
<template>
<button @click="navigateToDetail(route)">跳转到详情页</button>
</template>
最后,仁者见仁智者见智,我在开发中会更多的抛弃代码给我带来的“副作用”(比如引用问题),更专注于业务。也引用一句话,代码没出现性能问题时,不需要提前优化
后续会陆续分享vue3个人觉得最佳实践