共计 3651 个字符,预计需要花费 10 分钟才能阅读完成。
文章目录
- 前言
- 一、关于 reactive 数据直接赋值破坏响应式结构
- 二、关于获取当前路由地址的两个注意点
-
- 1.router.currentRoute 相当于 $route
- 2.router.currentRoute 是 ref 响应式数据 要拿值的话需要.value,或者用 unref 转
- 三、关于父组件传递 props 异步数据到子组件遇到的问题
-
- 1. 子组件使用 watch 监听
- 2. 子组件使用 computed 计算属性返回
- 3. 父组件使用 v -if 判断,等获取到数据后再渲染子组件
- 四、关于通过 ref 获取组件实例调用子组件方法遇到的一些问题
-
- 1. 父组件 watch 判断已经获取到子组件 ref 实例后再操作
- 2.nextTick 方法,在 DOM 更新后调用
- 总结
前言
对于新手而言,底子不足,积累有限,用个技术只知其然,不知其所以然,羡慕大佬理解底层原理,一看就能锁定问题,还能举一反三,但成长的路总是迂回曲折的,记忆靠不住就只能费手喽~
一、关于 reactive 数据直接赋值破坏响应式结构
在使用 reactive 定义复杂结构的响应式数据时,当我们将响应式对象的属性赋值或解构至本地变量时,或是将该属性传入一个函数时,会失去响应性,推荐的写法是:
script setup>
import {reactive,onMounted,toRefs} from 'vue'
const state=reactive({
arr:[]
})
const { arr } = toRefs(state)onMounted(()=>{
state.arr=[1,2,3]
})
script>
template>
div> 用在模板渲染:{{arr}} div>
template>
style>
style>
同理,在使用 provide,inject 组件通讯的时候,需要把整个响应式对象一起传过去,举例:
父组件代码
template>
div>
p>{{list}}p>
p> 姓名:{{user.name}}p>
p> 年龄:{{user.age}}p>
div>
Version>Version>
template>
script setup>
import { reactive, toRefs, onMounted, provide, ref } from 'vue';
import Version from './Version.vue';
const isUpdate = ref(false)
const state = reactive({
list: [],
user: {},
})
const { list, user } = toRefs(state)
onMounted(() => {
state.list = [1, 2, 3],
state.user = { name: '小小梦想家', age: 18 }
isUpdate.value = true
})
provide('userInfo',state.user)
provide('userDetail',state)
provide('isUpdate_a',isUpdate)
provide('isUpdate_b',isUpdate.value)
script>
style scoped lang="less">style>
子组件代码
template>
div>
h2>reactiveh2>
p> 只传递 reactive 对象的单个属性,破坏了响应性:{{userInfo}}p>
p> 传递整个 reactive 对象,通过读取对象属性的方式获取需要的数据:{{userDetail.user}}p>
h2>refh2>
p> 破坏了响应性,只获取到的初始值:{{isUpdate_b}}p>
p> 能获取到的最新值:{{isUpdate_a}}p>
div>
template>
script setup>
import { inject } from 'vue';
const userInfo = inject('userInfo')
const userDetail = inject('userDetail')
const isUpdate_a = inject('isUpdate_a')
const isUpdate_b = inject('isUpdate_b')
script>
style scoped lang="less">style>
页面效果
二、关于获取当前路由地址的两个注意点
1.router.currentRoute 相当于 $route
但是 $route.path 或者 $route.fullPath 只能在.vue 文件中使用,js 模块中要使用 router.currentRoute
2.router.currentRoute 是 ref 响应式数据 要拿值的话需要.value,或者用 unref 转
代码如下(示例):
template>
p>$route 获取当前路由地址:{{$route.path}}p>
p>router.currentRoute:{{currentRoute_false}}p>
p>router.currentRoute.value:{{currentRoute_true}}p>
template>
script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
const currentRoute_false = router.currentRoute.fullPath
const currentRoute_true = router.currentRoute.value.fullPath
script>
style scoped lang='less'>
style>
三、关于父组件传递 props 异步数据到子组件遇到的问题
vue3 中,使用 props 传递异步数据的时候 子组件存在拿不到数据的情况,照理这个问题 vue2 应该也是存在的,但确实之前写 2 项目的时候并没有出现过类似的问题 大概是 2 里面用工厂函数返回默认值是可以等待异步数据的?
先记录一下我在 3 里面尝试过的几种方案吧;
1. 子组件使用 watch 监听
import { ref, watch } from 'vue';
export default {
name: 'Watch',
props: {
list: {
type: Array,
default: () => [],
},
},
setup(props) {
const list = ref([]);
watch(
() => props.list,
(val) => {
list.value = val;
}
);
return {
list,
};
},
};
2. 子组件使用 computed 计算属性返回
script>
import { computed } from 'vue';
export default {
name: 'Computed',
props: {
list: {
type: Array,
default: () => [],
},
},
setup(props) {
const list = computed(() => props.list);
return {
list,
};
},
};
/script>
3. 父组件使用 v -if 判断,等获取到数据后再渲染子组件
template>
div id="app">
child :dataList="dataList" v-if="isGetData">/child>
/div>
/template>
script setup>
import child from './views/child'
import { ref, onMounted } from 'vue'
const isGetData = ref(false)
const dataList = ref([])
onMounted(() => {
setTimeout(() => {
dataList.value = [1, 2, 3]
isGetData.value = true
}, 200)
})
/script>
四、关于通过 ref 获取组件实例调用子组件方法遇到的一些问题
在父组件中用 ref 实例直接去调用子组件暴露的方法,有些情况下会报错,提示找不到该方法。原因是此时子组件还没挂载好,目前尝试过的可行方案有
1. 父组件 watch 判断已经获取到子组件 ref 实例后再操作
watch(
[echartRef, () => props.chartData],
([el, data]) => {
if (!el || (data.xData && data.xData.length === 0)) return;
initChart();
},
{ immediate: true, deep: true }
);
2.nextTick 方法,在 DOM 更新后调用
const handleClick = () => {
nextTick(() => {
commentRef.value?.getData()
})
总结
小问题还是有很多,一时间也想不全了,后面想到再补充吧~ 现学现用总算把第一个 vue3 项目完成了,没有同事强烈推荐的惊喜,就觉得用个啥都要 import 挺麻烦的,.value 也挺讨厌~ 有的时候一下没反应过来,找半天……不过整体还是不错的,值得学习,尤其 setup 语法糖下,简直不要太爽。。
原文地址: 盘点初次使用 vue3 遇到的那些小坑