vue中避免使用函数来绑定依赖

634 阅读3分钟
如果你正在使用vue编写业务,可能遇到一个数据比较多,他们都遵循相同的模式,需要在data里定义多个变量来绑定依赖,然后你不想在data里定义多个变量,在接口调回后每个都重新赋值,采用这种方式绑定依赖:

<div v-if='fuctionA(args)'>
</div>
<div v-for='item in fuctionB()' >
 <div v-if='functionC(item)' :style='fuctionA(item.attribute)'></div>
</div>
 

所有的依赖都通过一个函数return,给函数传入不同参数来返回一个数据,这种写法虽然简洁,data中不用定义变量,但会导致当触发组件更新时,这些函数又会全部执行一次 如果你的数组长度过长,或者组件更新很频繁,就会导致内存占用过大,函数暴栈,页面崩溃等问题

比如以下示例:

<template>
  <div>
    <div v-for="item in navList" :style="styleConfig('nav')" :key="item.id">
      导航父级菜单
      <div v-for="item2 in item.chilren" :key="item2.id" :style="styleConfig('navChild')">子菜单</div>
    </div>
    <div :style="styleConfig('c')"></div>
    <div :style="styleConfig('d')"></div>
    <div class="num">{{num}}</div>
  </div>
</template>
 
<script>
// 假如以下就是后端返回的数据
 
//菜单列表
let dataList = [],
  chilrenList = [];
for (let i = 0; i < 20; i++) {
  dataList.push({
    name: `父级菜单${i}`,
    id:`a${i}`
  });
  chilrenList.push({
    name: `子级菜单${i}`,
     id:`b${i}`
  });
  dataList[i].chilren = chilrenList;
}
// 动态设置的样式
let config = {
  navConfig: {
    color: "#333333",
    hoverColor: "#e6e6e6",
    bgColor: "#ffffff",
    hoverBgColor: "#d3d3d3",
    childColor: "#333333",
    childHoverColor: "#e6e6e6",
    childBgColor: "#ffffff",
    childHoverBgColor: "#d3d3d3"
  },
  config1: {},
  config2: {}
  //... 可能还有会有很多个配置
};
export default {
  data() {
    return {
      num: 1,
      navList: []
    };
  },
  mounted() {
    this.navList = dataList;
    // 通过一个定时器来触发组件实时更新
    setInterval(() => {
      this.num++;
    }, 1000);
  },
  methods: {
    //传入不同的key来返回不同的样式
    styleConfig(key) {
      console.log("abc");
      if (key === "nav") {
        return {
          color: config.navConfig.color,
          backGroundColor: config.navConfig.bgColor
        };
      } else if (key === "navChild") {
        return {
          color: config.navConfig.childColor,
          backGroundColor: config.navConfig.childBgColor
        };
      } else {
        return {
          width: "15px"
        };
      }
    }
  }
};
</script>

可以看到我通过一个定时器来触发组件更新, 菜单的动态样式直接绑定一个函数返回,每当触发更新时函数就会执行20+20+2=42次,接下来可以看到:

明明可以只需要在第一次渲染时执行4次,结果导致了每次更新都会执行42次,这样必会造成内存的损耗;

稍微改写一下

<template>
  <div>
    <div v-for="item in navList" :style="config.nav" :key="item.id">
      导航父级菜单
      <div v-for="item2 in item.chilren" :key="item2.id" :style="config.navChild">子菜单</div>
    </div>
    <div :style="config.c"></div>
    <div :style="config.d"></div>
    <div class="num">{{num}}</div>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      num: 1,
      navList: [],
      config:{
        nav:'',
        navChild:'',
        c:'',
        d:'',
      }
    };
  },
  mounted() {
    this.navList = dataList;
    let attr=Object.keys(this.config)
     attr.forEach(key=>{
       this.config[key]=this.styleConfig(key)
     })
   // 通过一个定时器来触发组件实时更新
    setInterval(() => {
      this.num++;
    }, 1000);
  },
};
</script>
 

 在data中定义一个config,对应的属性来保存动态样式,把属性名当做之前的条件key 传给函数,循环拿到对应的值,把用绑定依赖的函数替换成config的属性

可以看到函数只会在第一次渲染时调用,更新时不再调用


所以老老实实用data中声明的变量来绑定依赖,不要用函数