MST

星途 面试题库

面试题:Vue中v-bind动态属性绑定的高级用法场景

在一个电商项目的商品列表页,每个商品项都有一个图片展示,图片的 'alt' 属性需要根据商品的不同名称动态设置,同时图片的 'src' 属性需要根据商品的不同规格从一个对象数组中动态获取。假设商品数据结构为 {name: '商品名称', spec: '规格'},图片资源数组为 [{spec: '规格1', src: '图片路径1'}, {spec: '规格2', src: '图片路径2'}]。请用Vue的v - bind动态属性绑定实现该功能,并且阐述如何优化这种动态属性绑定在大量商品列表下的性能。
37.2万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

1. Vue 的 v - bind 动态属性绑定实现

假设我们有一个 商品列表组件,模板代码如下:

<template>
  <div>
    <ul>
      <li v - for="(product, index) in products" :key="index">
        <img
          :alt="product.name"
          :src="getImageSrc(product.spec)"
        />
        <p>{{ product.name }}</p>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: [
        { name: '商品1', spec: '规格1' },
        { name: '商品2', spec: '规格2' }
      ],
      imageResources: [
        { spec: '规格1', src: '图片路径1' },
        { spec: '规格2', src: '图片路径2' }
      ]
    };
  },
  methods: {
    getImageSrc(spec) {
      return this.imageResources.find(image => image.spec === spec).src;
    }
  }
};
</script>

在上述代码中,通过 v - for 遍历商品列表,使用 v - bind: 是 v - bind 的缩写)动态绑定 alt 属性为商品名称,通过调用 getImageSrc 方法动态获取图片的 src 属性。

2. 性能优化

  1. 使用计算属性代替方法调用
    • 上面代码中 getImageSrc 方法每次渲染都会被调用,对于大量商品列表会影响性能。可以使用计算属性来优化。
    • 修改代码如下:
<template>
  <div>
    <ul>
      <li v - for="(product, index) in products" :key="index">
        <img
          :alt="product.name"
          :src="imageSrcs[index]"
        />
        <p>{{ product.name }}</p>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: [
        { name: '商品1', spec: '规格1' },
        { name: '商品2', spec: '规格2' }
      ],
      imageResources: [
        { spec: '规格1', src: '图片路径1' },
        { spec: '规格2', src: '图片路径2' }
      ]
    };
  },
  computed: {
    imageSrcs() {
      return this.products.map(product => {
        return this.imageResources.find(image => image.spec === product.spec).src;
      });
    }
  }
};
</script>
  • 这样,计算属性 imageSrcs 只有在依赖数据(productsimageResources)发生变化时才会重新计算,提高了性能。
  1. 图片懒加载
    • 使用 IntersectionObserver API 或第三方库(如 vue - lazyload)实现图片懒加载。
    • vue - lazyload 为例,安装 npm install vue - lazyload 后,在 main.js 中配置:
import Vue from 'vue';
import VueLazyload from 'vue - lazyload';

Vue.use(VueLazyload);
  • 模板中修改图片绑定:
<template>
  <div>
    <ul>
      <li v - for="(product, index) in products" :key="index">
        <img
          v - lazy="imageSrcs[index]"
          :alt="product.name"
        />
        <p>{{ product.name }}</p>
      </li>
    </ul>
  </div>
</template>
  • 这样只有当图片进入视口时才会加载,减少了初始渲染时的请求数量,提升性能。
  1. 虚拟列表
    • 当商品列表非常长时,可以使用虚拟列表技术,如 vue - virtual - scroll - list
    • 安装 npm install vue - virtual - scroll - list,在组件中使用:
<template>
  <div>
    <virtual - scroll - list
      :data="products"
      :height="300"
      :item - height="50"
      key - field="name"
    >
      <template #default="{ item }">
        <img
          :alt="item.name"
          :src="getImageSrc(item.spec)"
        />
        <p>{{ item.name }}</p>
      </template>
    </virtual - scroll - list>
  </div>
</template>

<script>
import VirtualScrollList from 'vue - virtual - scroll - list';
export default {
  components: {
    VirtualScrollList
  },
  data() {
    return {
      products: Array.from({ length: 1000 }, (_, i) => ({ name: `商品${i + 1}`, spec: `规格${i % 2 === 0? '规格1' : '规格2'}` })),
      imageResources: [
        { spec: '规格1', src: '图片路径1' },
        { spec: '规格2', src: '图片路径2' }
      ]
    };
  },
  methods: {
    getImageSrc(spec) {
      return this.imageResources.find(image => image.spec === spec).src;
    }
  }
};
</script>
  • 虚拟列表只渲染可见区域的商品,大大减少了 DOM 数量,提高了渲染性能。