专业的编程技术博客社区

网站首页 > 博客文章 正文

VUE3使用watch监听响应式数据时,第一次不更新的问题

baijin 2024-10-28 14:48:03 博客文章 8 ℃ 0 评论

最近在练习写管理后台的网页时,碰到一个问题 ,描述如下:

通过侧边栏点击对应的菜单,把对应选择的菜单信息传递到table组件,table组件中通过watch对选择的菜单数据进行监听,当出现变化时,对table进行更新,但是第一次点击时,table总是不更新,通过日志发现数据也变化了,但是watch中的代码并未执行。

以下时文心一言3.5给出的解决方案和解释:

原代码:第一次点击菜单时,watch中的api不执行,导致table数据不变化。

 <script setup>
 import { api } from '@/api/index'
 import { ref, watch } from 'vue';
 // 表格数据
 const tableColumn = ref({'id': 'ID', 'username': '用户名', 'role_name': '角色', 'department_name': '部门'});
 const tableData = ref([
   { name: '张三', age: 20, gender: '男' },
   { name: '李四', age: 25, gender: '女' },
   { name: '王五', age: 30, gender: '男' },
 ]);
 const tableColumnObj = {
   '用户管理': {'id': 'ID', 'username': '用户名', 'role_name': '角色', 'department_name': '部门'},
   '角色管理': {'id': 'ID', 'role_name': '角色'},
   '菜单管理': {'id': 'ID', 'menu_name': '菜单', 'parent_menu_name': '父菜单', 'menu_url': '菜单地址'},
   '部门管理': {'id': 'ID', 'department_name': '部门'},
 };
 const props = defineProps({
 	selectedMenu: Object,
 });
  
 watch(()=>props.selectedMenu, (newValue, oldValue) => {
   tableColumn.value = tableColumnObj[newValue.menu.menu_name]
   api.getTableList(newValue.menu.menu_url).then(res => {
     tableData.value = res.data;
 	});
 });
 </script>

以下是文心给的修改方案:

<script setup>
import { api } from '@/api/index'
import { ref, watch, onMounted } from 'vue';
// 表格数据
const tableColumn = ref({'id': 'ID', 'username': '用户名', 'role_name': '角色', 'department_name': '部门'});
const tableData = ref([
  { name: '张三', age: 20, gender: '男' },
  { name: '李四', age: 25, gender: '女' },
  { name: '王五', age: 30, gender: '男' },
]);
const tableColumnObj = {
  '用户管理': {'id': 'ID', 'username': '用户名', 'role_name': '角色', 'department_name': '部门'},
  '角色管理': {'id': 'ID', 'role_name': '角色'},
  '菜单管理': {'id': 'ID', 'menu_name': '菜单', 'parent_menu_name': '父菜单', 'menu_url': '菜单地址'},
  '部门管理': {'id': 'ID', 'department_name': '部门'},
};
const props = defineProps({
	selectedMenu: Object,
});
 
const onSelectedMenuChange = (newValue, oldValue) => {  
  console.log('watch', newValue, oldValue);  
  tableColumn.value = tableColumnObj[newValue.menu.menu_name];  
  api.getTableList(newValue.menu.menu_url).then(res => {  
    tableData.value = res.data;  
    console.log('xx', res.data);  
  });  
};
 
watch(() => props.selectedMenu, onSelectedMenuChange);
 
onMounted(() => {  
  onSelectedMenuChange(props.selectedMenu, undefined); // 传入当前值和 undefined 作为旧值  
});
</script>

原因:在 Vue 3 的 Composition API 中,watch 函数默认不会在初始化时立即执行其回调函数,即它不会模拟 Options API 中 watch 的 immediate: true 行为。这是 watch 函数的设计决定的,它只会在其依赖的值发生变化时执行回调函数,所以通过用onMounted 在组件挂载后立即调用一次回调函数,达到immediate的效果。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表