Solve the problem of using reactive responsiveness in vue3, and the page does not change after assignment?


scene reason

We need to use the server's data to render to the page in vue3. I use the responsive data attribute generated by reactive, but the requested data is not rendered and displayed on the page after mounting.

Technology: vue3,element-ui-plus


1. Examples

home.vue

<template>
  <div class="common-layout">
    <el-menu @select="changeMenu" :collapse="isCollapse" active-text-color="#409eff" background-color="#333744"
      class="el-menu-vertical-demo" default-active="2" text-color="#fff" :unique-opened="true">
      <el-sub-menu :index="item.path" v-for="(item) in parmar.menus" :key="item.id">
        <template #title>
          <el-icon>
            <List />
          </el-icon>
          <span>{
   
   { item.authName }}</span>
        </template>
        <el-menu-item :index="item2.path" v-for="(item2) in item.children" :key="item2.id">
          <el-icon>
            <Menu />
          </el-icon>
          {
   
   { item2.authName }}
        </el-menu-item>
      </el-sub-menu>
    </el-menu>
  </div>
</template>

<script setup>
// 引入模块
import {
      
       reactive, onMounted } from 'vue'
import {
      
       useRouter } from 'vue-router'
import http from '@/utils/request'

const router = useRouter();

let menusList = reactive([

]);

onMounted(() => {
      
      
  getData()
})

const getData = async () => {
      
      
  let {
      
       data } = await http.get('/menus');
  // 这里直接赋值,会导致menusList失去响应式了
  menusList = data.data;
  console.log(menusList);
}

const changeMenu = (key) => {
      
      
  router.push('/home/' + key)
}
</script>

<style lang="less" scoped>
.common-layout {
      
      
  height: 100vh;
  box-sizing: border-box;
  position: relative;
  overflow: hidden;

  /deep/.el-menu--vertical {
      
      
    margin: 0;
    border-right: none !important;
    overflow-x: hidden;
    height: calc(100vh - 100px);
    user-select: none;
  }

  .el-menu-vertical-demo:not(.el-menu--collapse) {
      
      
    width: 200px;
    min-height: 400px;
  }
}
</style>

insert image description here
Through direct assignment, we can see that the data has become ordinary data, not responsive.

Two, the solution

1. Use ref to store responsive data

code show as below:

<script setup>
// 引入模块
import {
      
       ref, reactive, onMounted } from 'vue'
import http from '@/utils/request'

let menusList = ref([

]);

onMounted(() => {
      
      
  getData()
})

const getData = async () => {
      
      
  let {
      
       data } = await http.get('/menus');
  // 这里直接赋值value,在页面上直接使用menusList即可!
  menusList.value = data.data;
  
}
</script>

insert image description here
It can be seen that the printed data is data hijacked by ref and is responsive.

2. Use objects to wrap the data to be changed in reactive

code show as below:

<script setup>
// 引入模块
import {
      
       reactive, onMounted } from 'vue'
import http from '@/utils/request'

let parmar = reactive({
      
      
  menus: [

  ]
});


onMounted(() => {
      
      
  getData()
})

const getData = async () => {
      
      
  let {
      
       data } = await http.get('/menus');
  // 这里直接赋值对象里面的数据,就不会造成把响应式替换掉的情况了,直接在页面上通过parmar.menus使用数据!
  parmar.menus = data.data;
  console.log( parmar);
}
</script>

insert image description here
Using this approach, the data is also reactive.

3. The for of loop pushes to the reactive data without destroying the data structure

code show as below:

<script setup>
// 引入模块
import {
      
       reactive, onMounted } from 'vue'
import http from '@/utils/request'

let menusList = reactive([])

onMounted(() => {
      
      
  getData()
})

const getData = async () => {
      
      
  let {
      
       data } = await http.get('/menus');
  for (let i of data.data){
      
      
    menusList.push(i);
  }
  console.log(menusList);
}
</script>

insert image description here


Summarize

The main problem is to use reactivethe generated responsive data and 响应式数据replace it with the value in the direct assignment 普通数据, resulting 无法监听数据in changes.

Guess you like

Origin blog.csdn.net/weixin_61102579/article/details/129581031