【SOLID原则前端中的应用】里氏替换原则(Liskov Substitution Principle,LSP)- vue3示例

发布于:2024-07-10 ⋅ 阅读:(138) ⋅ 点赞:(0)

里氏替换原则(Liskov Substitution Principle,LSP)规定,子类对象必须能够替换父类对象,并且程序的行为保持不变。
在Vue 3中,这意味着我们在创建可替换的组件时,应该确保子组件能够完全替代父组件,而不会引发错误或不一致的行为。


在这里插入图片描述

示例:EmailInput 组件

1. 创建基本输入组件 BaseInput.vue

这个组件是一个基本的输入框组件,可以接受任何类型的输入。

<!-- BaseInput.vue -->
<template>
    <div class="base-input">
      <label :for="id">{{ label }}</label>
      <input :id="id" :type="type" v-model="internalValue" />
    </div>
  </template>
  
  <script>
  export default {
    name: 'BaseInput',
    props: {
      id: {
        type: String,
        required: true
      },
      label: {
        type: String,
        required: true
      },
      type: {
        type: String,
        default: 'text'
      },
      modelValue: {
        type: [String, Number],
        default: ''
      }
    },
    computed: {
      internalValue: {
        get() {
          return this.modelValue;
        },
        set(value) {
          this.$emit('update:modelValue', value);
        }
      }
    }
  };
  </script>
  
  <style scoped>
  .base-input {
    margin-bottom: 10px;
  }
  label {
    display: block;
    margin-bottom: 5px;
  }
  input {
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
  }
  </style>
2. 创建电子邮件输入组件 EmailInput.vue

这个组件扩展了 BaseInput,添加了电子邮件格式验证和错误提示功能。

<!-- EmailInput.vue -->
<template>
    <div class="email-input">
      <BaseInput 
        :id="id" 
        :label="label" 
        type="email" 
        v-model="emailValue" 
        @update:modelValue="validateEmail"
      />
      <p v-if="error" class="error">{{ error }}</p>
    </div>
  </template>
  
  <script>
  import BaseInput from './BaseInput.vue';
  
  export default {
    name: 'EmailInput',
    components: {
      BaseInput
    },
    props: {
      id: {
        type: String,
        required: true
      },
      label: {
        type: String,
        required: true
      },
      modelValue: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        emailValue: this.modelValue,
        error: ''
      };
    },
    watch: {
      emailValue(newValue) {
        this.$emit('update:modelValue', newValue);
        this.validateEmail();
      }
    },
    methods: {
      validateEmail() {
        const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailPattern.test(this.emailValue)) {
          this.error = '无效的邮箱地址';
        } else {
          this.error = '';
        }
      }
    }
  };
  </script>
  
  <style scoped>
  .email-input {
    margin-bottom: 10px;
  }
  .error {
    color: red;
    font-size: 0.875em;
  }
  </style>
3. 使用组件

在父组件中无缝替换 BaseInputEmailInput

<!-- App.vue -->
<template>
  <div id="app">
    <!-- 使用BaseInput -->
    <BaseInput id="username" label="Username" v-model="username" placeholder="请输入用户名" />

    <!-- 使用EmailInput替换BaseInput -->
     <br>
    <EmailInput id="email" label="Email" v-model="email"  placeholder="邮箱地址" />
  </div>
</template>

<script>
import BaseInput from './components/BaseInput.vue';
import EmailInput from './components/EmailInput.vue';

export default {
  name: 'App',
  components: {
    BaseInput,
    EmailInput
  },
  data() {
    return {
      username: '',
      email: ''
    };
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

总结

上面的示例中,首先创建了一个通用输入组件 BaseInput,它可以接受任何类型的输入。
然后,创建了一个电子邮件输入组件 EmailInput,通过扩展 BaseInput 来专门处理电子邮件输入,并增加了电子邮件格式验证和错误提示功能。

EmailInput 继承了 BaseInput 的所有属性和方法,同时增加了对电子邮件格式的验证。
如果输入的电子邮件格式不正确,会显示错误提示信息。
这样,我们可以在需要电子邮件输入的地方无缝替换 BaseInputEmailInput,而不需要修改其他代码。

通过这种方式,我们遵循了里氏替换原则,确保子组件能够替代父组件而不改变程序的行为。


网站公告

今日签到

点亮在社区的每一天
去签到