前端面试七之列表渲染和组件重用

发布于:2025-06-14 ⋅ 阅读:(23) ⋅ 点赞:(0)

一、列表渲染

<template>
  <div>
    <h1>用户列表</h1>
    <div v-if="loading">加载中...</div>
    <div v-else-if="error" class="error">加载失败:{{ error.message }}</div>
    <ul v-else>
      <li v-for="user in users" :key="user.id">
        <strong>{{ user.name }}</strong> - {{ user.email }}
      </li>
    </ul>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      users: [], // 用于存储用户数据
      loading: true, // 加载状态
      error: null, // 错误信息
    };
  },
  methods: {
    // 将接口请求逻辑分离成一个独立方法
    async fetchUsers() {
      try {
        const response = await axios.get('https://jsonplaceholder.typicode.com/users');
        this.users = response.data; // 将获取到的用户数据存储到 users 中
      } catch (error) {
        this.error = error; // 存储错误信息
      } finally {
        this.loading = false; // 加载完成
      }
    },
  },
  mounted() {
    // 在 mounted 钩子中调用 fetchUsers 方法
    this.fetchUsers();
  },
};
</script>

<style>
.error {
  color: red;
}
</style>

代码解释

代码解释

(1)分离接口请求逻辑
  • 将接口请求逻辑封装到 fetchUsers 方法中,使代码更加模块化。

  • fetchUsers 方法中使用 async/await 处理异步请求。

  • 请求成功时,将响应数据存储到 users 中。

  • 请求失败时,将错误信息存储到 error 中。

  • finally 块中,将 loading 设置为 false,表示加载完成。

(2)在 mounted 钩子中调用方法
  • mounted 钩子中调用 fetchUsers 方法,确保在组件挂载完成后发起请求。

  • 这种方式使代码更加清晰,逻辑更加分离。

(3)v-for 和 v-if
  • v-for:用于循环渲染列表。v-for="user in users" 表示对 users 数组中的每个元素进行循环,并将每个元素赋值给 user

  • v-if:用于根据条件显示或隐藏元素。v-if="loading" 表示如果 loadingtrue,则显示加载提示;v-else-if="error" 表示如果存在错误,则显示错误信息。

二、组件重用

 组件重用是 Vue.js 的一个重要特性,允许你创建可复用的组件,从而提高代码的可维护性和可读性。通过将通用的功能封装成独立的组件,你可以在多个地方重复使用这些组件,并且可以通过传入不同的属性(props)和插槽(slots)来定制它们的行为和外观。

示例:创建一个可重用的自定义按钮组件

1. 创建自定义按钮组件

src/components 文件夹中创建一个名为 CustomButton.vue 的文件。

<template>
  <button
    :style="buttonStyle"
  >
    <slot>默认按钮文本</slot>
  </button>
</template>

<script>
export default {
  name: 'CustomButton',
  props: {
    // 按钮的颜色
    color: {
      type: String,
      default: 'blue',
    },
    // 按钮的大小
    size: {
      type: String,
      default: 'medium',
    },
  },
  computed: {
    // 动态生成按钮的样式
    buttonStyle() {
      const baseStyle = {
        backgroundColor: this.color,
        color: this.textColor,
        border: 'none',
        borderRadius: '4px',
        cursor: 'pointer',
        transition: 'background-color 0.3s',
        padding: this.padding,
        fontSize: this.fontSize,
      };
      return baseStyle;
    },
    // 根据背景颜色动态调整文字颜色
    textColor() {
      return this.color === 'white' ? 'black' : 'white';
    },
    // 动态调整按钮的内边距
    padding() {
      switch (this.size) {
        case 'small':
          return '4px 8px';
        case 'medium':
          return '8px 16px';
        case 'large':
          return '12px 24px';
        default:
          return '8px 16px';
      }
    },
    // 动态调整按钮的字体大小
    fontSize() {
      switch (this.size) {
        case 'small':
          return '12px';
        case 'medium':
          return '14px';
        case 'large':
          return '16px';
        default:
          return '14px';
      }
    },
  },
};
</script>

<style scoped>
button {
  border: none;
  border-radius: 4px;
  padding: 8px 16px; /* 默认值 */
  cursor: pointer;
  transition: background-color 0.3s;
  font-size: 14px; /* 默认值 */
}

button:hover {
  opacity: 0.8;
}
</style>

2. 在父组件中使用自定义按钮

src/App.vue 文件中引入并使用 CustomButton 组件。

<template>
  <div id="app">
    <h1>自定义按钮示例</h1>
    <CustomButton color="green" size="large">
      点击我
    </CustomButton>
    <CustomButton color="red" size="small">
      删除
    </CustomButton>
    <CustomButton color="blue" size="medium">
      提交
    </CustomButton>
    <CustomButton color="white" size="medium">
      白色按钮
    </CustomButton>
  </div>
</template>

<script>
import CustomButton from './components/CustomButton.vue';

export default {
  name: 'App',
  components: {
    CustomButton,
  },
};
</script>

<style>
#app {
  text-align: center;
  margin-top: 60px;
}
</style>

(2)父组件

 

  • 1)CustomButton 组件
  • 插槽(Slot):使用 <slot> 元素允许父组件传入按钮的文本内容。如果父组件没有传入内容,则显示默认的“默认按钮文本”。

  • 属性(Props)

    • color:按钮的背景颜色,默认值为 'blue'

    • size:按钮的大小,默认值为 'medium'

  • 在父组件中,通过 colorsize 属性传入按钮的颜色和大小。

  • 使用插槽传入按钮的文本内容。

    • 计算属性(Computed Properties)

      • buttonClass:根据 size 动态生成按钮的类名。

      • buttonStyle:根据 color 动态生成按钮的样式。

      • textColor:根据背景颜色动态调整文字颜色,确保文字在不同背景颜色下都能清晰可见。

    • 样式(Style):为按钮定义了基本样式,并根据大小动态调整字体大小和内边距。