前端面试五之vue2基础

1.属性绑定v-bind(:)

v-bind 是 Vue 2 中用于动态绑定属性的核心指令,它支持多种语法和用法,能够灵活地绑定 DOM 属性、组件 prop,甚至动态属性名。通过 v-bind,可以实现数据与视图之间的高效同步,是构建动态界面的重要工具。

<template>
  <div class="demo-container">
    <!-- 基础属性绑定 -->
    <div :id="dynamicId">动态 ID 的 div</div>

    <!-- 绑定多个属性 -->
    <div :="{ id: dynamicId, title: dynamicTitle, class: 'my-class' }">
      绑定多个属性
    </div>

    <!-- 动态属性名 -->
    <div :[attributeName]="attributeValue">
      动态属性名绑定
    </div>

    <!-- 布尔属性绑定 -->
    <button :disabled="isDisabled">点击我</button>

    <!-- 绑定组件的 prop -->
    <child-component :message="parentMessage" :title.sync="parentTitle"></child-component>
  </div>
</template>

<script>
// 定义子组件
const ChildComponent = {
  props: {
    message: String,
    title: String
  },
  template: `
    <div>
      <h3>子组件</h3>
      <p>从父组件接收到的 message: {{ message }}</p>
      <p>从父组件接收到的 title: {{ title }}</p>
      <button @click="updateTitle">更新父组件的 title</button>
    </div>
  `,
  methods: {
    updateTitle() {
      // 使用 $emit 触发父组件的更新
      this.$emit('update:title', '新的标题');
    }
  }
};

export default {
  name: "demo",
  components: {
    ChildComponent
  },
  data() {
    return {
      dynamicId: 'my-dynamic-id', // 动态 ID
      dynamicTitle: '这是一个标题', // 动态标题
      attributeName: 'class', // 动态属性名
      attributeValue: 'my-class', // 动态属性值
      isDisabled: false, // 布尔属性
      parentMessage: 'Hello from parent!', // 父组件的 message
      parentTitle: '初始标题' // 父组件的 title
    };
  }
};
</script>

<style scoped>
.demo-container {
  margin: 20px;
  padding: 20px;
  border: 1px solid #ccc;
}
.my-class {
  color: blue;
  font-weight: bold;
}
button {
  margin-top: 10px;
}
</style>

1.1示例代码中的父子组件通信

  1. 父组件向子组件传递数据

    • 父组件在模板中使用 :message="parentMessage":title.sync="parentTitle"

    • Vue 会将 parentMessageparentTitle 的值传递给子组件的 messagetitle

    • 子组件通过 props 接收这些值,并可以在模板中使用。

  2. 子组件向父组件传递事件

    • 子组件在模板中有一个按钮,点击按钮时调用 updateTitle 方法。

    • updateTitle 方法通过 this.$emit('update:title', '新的标题') 触发一个自定义事件 update:title,并传递新值 '新的标题'

    • 父组件监听到 update:title 事件后,会自动更新 parentTitle 的值为 '新的标题'

1.2面试问题:

  • 如何实现父子组件之间的数据传递?

  • 父组件如何向子组件传递数据?

  • 子组件如何向父组件传递事件?

回答要点:

  • 父组件向子组件传递数据: 使用 props

    • 父组件通过 v-bind 将数据绑定到子组件的 props

    • 子组件通过 props 接收父组件传递的数据。

  • 子组件向父组件传递事件: 使用 $emit

    • 子组件通过 this.$emit 触发一个自定义事件,并传递数据。

    • 父组件通过监听子组件的事件来接收数据。

      <!-- 父组件 -->
      <template>
        <div>
          <child-component :message="parentMessage" @update:title="handleTitleUpdate"></child-component>
        </div>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent
        },
        data() {
          return {
            parentMessage: 'Hello from parent!',
            parentTitle: 'Initial Title'
          };
        },
        methods: {
          handleTitleUpdate(newTitle) {
            this.parentTitle = newTitle;
          }
        }
      };
      </script>
      <!-- 子组件 -->
      <template>
        <div>
          <p>Message from parent: {{ message }}</p>
          <button @click="updateTitle">Update Parent Title</button>
        </div>
      </template>
      
      <script>
      export default {
        props: {
          message: String
        },
        methods: {
          updateTitle() {
            this.$emit('update:title', 'New Title');
          }
        }
      };
      </script>

    • .sync 修饰符的作用

      • 简化父子组件之间的双向绑定。

2.事件绑定 v-on(@)

v-on 是 Vue.js 中用于绑定事件监听器的指令,它允许你为 DOM 元素或组件绑定事件处理函数。通过 v-on,你可以监听用户的交互行为(如点击、输入等),并在事件触发时执行特定的逻辑。

<template>
  <div>
    <h1>事件绑定示例</h1>
    <button @click="handleClick">点击我</button>
    <input type="text" @input="handleInput($event)">
    <a href="https://example.com" @click.prevent="handleLinkClick">链接</a>
    <div @click="handleDivClick">
      <button @click.stop="handleButtonClick">点击我</button>
    </div>
    <input type="text" @keyup.enter="handleSubmit">
  </div>
</template>

<script>
export default {
  methods: {
    handleClick() {
      alert('按钮被点击了!');
    },
    handleInput(event) {
      console.log('输入框的值:', event.target.value);
    },
    handleLinkClick() {
      alert('链接被点击了,但不会跳转!');
    },
    handleDivClick() {
      alert('div 被点击了!');
    },
    handleButtonClick() {
      alert('按钮被点击了,但不会触发 div 的点击事件!');
    },
    handleSubmit() {
      alert('回车键被按下,表单提交!');
    }
  }
};
</script>

2.1基本用法

1. 监听原生 DOM 事件

v-on 可以用来监听原生 DOM 事件,例如 clickinputmouseover 等。

<button @click="handleClick">点击我</button>
2. 监听组件事件

v-on 也可以用来监听自定义组件的事件。子组件通过 $emit 触发事件,父组件通过 v-on 监听这些事件。

<child-component @custom-event="handleCustomEvent"></child-component>
  • custom-event 是子组件触发的自定义事件。

  • handleCustomEvent 是父组件中定义的事件处理函数。

3. 传递事件参数 

在事件处理函数中,你可能需要访问事件对象(例如获取输入框的值或鼠标的位置)。可以通过 $event 获取事件对象。

<input type="text" @input="handleInput($event)">
4. 传递额外参数

除了事件对象,你还可以传递其他参数到事件处理函数。

<button @click="handleClick('Hello', $event)">点击我</button>


methods: {
  handleClick(message, event) {
    console.log(message); // 输出 "Hello"
    console.log(event.type); // 输出 "click"
  }
}
5.事件修饰符

Vue 为 v-on 提供了一些事件修饰符,用于更方便地处理常见的事件行为。

 .stop:阻止事件冒泡
  • 点击按钮时,handleButtonClick 会被触发,但不会触发 handleDivClick

<div @click="handleDivClick">
  <button @click.stop="handleButtonClick">点击我</button>
</div>
.prevent:阻止默认行为
  • 点击链接时,不会跳转到 https://example.com,因为默认行为被阻止了。

<a href="https://example.com" @click.prevent="handleLinkClick">链接</a>
.capture:使用事件捕获模式
  • 在事件冒泡阶段,handleDivClick 会在 handleButtonClick 之前被触发。

<div @click.capture="handleDivClick">
  <button @click="handleButtonClick">点击我</button>
</div>
.self:只触发绑定元素自身的事件
  • 只有直接点击按钮时,handleButtonClick 才会被触发。

<div @click="handleDivClick">
  <button @click.self="handleButtonClick">点击我</button>
</div>
.once:事件只触发一次
  • handleClick 只会在第一次点击时被触发,之后的点击不会触发。

2.2总结

v-on 是 Vue 中非常强大的指令,用于绑定事件监听器。它支持以下功能:

  1. 监听原生 DOM 事件和自定义组件事件。

  2. 传递事件对象和额外参数。

  3. 使用事件修饰符(如 .stop.prevent.capture 等)简化事件处理逻辑。

  4. 使用键盘修饰符(如 .enter.tab 等)处理键盘事件。

 3.双向绑定v-model

v-model 是 Vue 中实现双向数据绑定的核心指令,它允许你将表单输入和应用状态进行同步。通过 v-model,表单元素的值会自动与 Vue 实例的数据保持一致,同时用户对表单的修改也会实时更新到数据中,反之亦然。这种双向绑定机制是 Vue 的一大特色,极大地简化了表单处理逻辑。

3.1基本用法

<template>
  <div class="v-model-demo">
    <h2>v-model 双向绑定示例</h2>

    <!-- 输入框 -->
    <div>
      <label for="text-input">输入框:</label>
      <input id="text-input" v-model="message" placeholder="输入内容">
      <p>输入的内容是:{{ message }}</p>
    </div>

    <!-- 多行文本框 -->
    <div>
      <label for="textarea">多行文本框:</label>
      <textarea id="textarea" v-model="multiLineMessage" placeholder="输入多行内容"></textarea>
      <p>输入的内容是:</p>
      <p style="white-space: pre">{{ multiLineMessage }}</p>
    </div>

    <!-- 单个复选框 -->
    <div>
      <label><input type="checkbox" v-model="singleCheckbox"> 单个复选框</label>
      <p>复选框是否选中:{{ singleCheckbox }}</p>
    </div>

    <!-- 多个复选框 -->
    <div>
      <label><input type="checkbox" v-model="checkedCities" value="北京"> 北京</label>
      <label><input type="checkbox" v-model="checkedCities" value="上海"> 上海</label>
      <label><input type="checkbox" v-model="checkedCities" value="广州"> 广州</label>
      <p>选中的城市:{{ checkedCities }}</p>
    </div>

    <!-- 单选按钮 -->
    <div>
      <label><input type="radio" v-model="picked" value="A"> A</label>
      <label><input type="radio" v-model="picked" value="B"> B</label>
      <p>选中的选项是:{{ picked }}</p>
    </div>

    <!-- 下拉选择框 -->
    <div>
      <label for="select">下拉选择框:</label>
      <select id="select" v-model="selected">
        <option disabled value="">请选择</option>
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="广州">广州</option>
      </select>
      <p>选中的城市是:{{ selected }}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "VModelDemo",
  data() {
    return {
      message: "", // 输入框绑定的数据
      multiLineMessage: "", // 多行文本框绑定的数据
      singleCheckbox: false, // 单个复选框绑定的数据
      checkedCities: [], // 多个复选框绑定的数据
      picked: "", // 单选按钮绑定的数据
      selected: "" // 下拉选择框绑定的数据
    };
  }
};
</script>

<style scoped>
.v-model-demo {
  margin: 20px;
  font-family: Arial, sans-serif;
}
label {
  margin-right: 10px;
}
p {
  margin: 10px 0;
}
textarea {
  width: 100%;
  height: 100px;
}
select {
  width: 100%;
}
</style>

v-model 的工作原理

v-model 实际上是一个语法糖,它背后做了以下几件事:

  1. 绑定 value 属性

    • 对于 <input><textarea>v-model 会绑定 value 属性。

    • 对于 <select>v-model 会绑定 value 属性到选中的 <option>

    • 对于 <input type="checkbox"><input type="radio">v-model 会绑定 value 属性到对应的值。

  2. 监听 inputchange 事件

    • v-model 会监听表单元素的 input 事件(对于 <input><textarea>)或 change 事件(对于 <select><input type="checkbox"><input type="radio">)。

    • 当事件触发时,它会自动更新绑定的数据。

3.2v-model 修饰符 

<template>
  <div class="v-model-modifiers-demo">
    <h2>v-model 修饰符示例</h2>

    <!-- .lazy 修饰符 -->
    <div>
      <label for="lazy-input">输入框(.lazy):</label>
      <input id="lazy-input" v-model.lazy="lazyMessage" placeholder="输入内容">
      <p>输入的内容是:{{ lazyMessage }}</p>
      <!--
        .lazy 修饰符:
        - 默认情况下,v-model 在每次 input 事件触发时更新数据。
        - 使用 .lazy 修饰符后,数据会在 change 事件触发时更新,即用户离开输入框时。
      -->
    </div>

    <!-- .number 修饰符 -->
    <div>
      <label for="number-input">输入框(.number):</label>
      <input id="number-input" v-model.number="numberValue" type="number" placeholder="输入数字">
      <p>输入的数字是:{{ numberValue }}</p>
      <!--
        .number 修饰符:
        - 默认情况下,v-model 会将输入框的值作为字符串处理。
        - 使用 .number 修饰符后,输入框的值会自动转换为数字类型。
      -->
    </div>

    <!-- .trim 修饰符 -->
    <div>
      <label for="trim-input">输入框(.trim):</label>
      <input id="trim-input" v-model.trim="trimMessage" placeholder="输入内容">
      <p>输入的内容是:{{ trimMessage }}</p>
      <!--
        .trim 修饰符:
        - 默认情况下,v-model 会保留输入框的首尾空格。
        - 使用 .trim 修饰符后,输入框的值会自动去除首尾空格。
      -->
    </div>
  </div>
</template>

<script>
export default {
  name: "VModelModifiersDemo",
  data() {
    return {
      lazyMessage: "", // .lazy 修饰符绑定的数据
      numberValue: 0, // .number 修饰符绑定的数据
      trimMessage: "" // .trim 修饰符绑定的数据
    };
  }
};
</script>

<style scoped>
.v-model-modifiers-demo {
  margin: 20px;
  font-family: Arial, sans-serif;
}
label {
  margin-right: 10px;
}
p {
  margin: 10px 0;
}
input {
  width: 100%;
  padding: 8px;
  margin-bottom: 10px;
}
</style>
  1. 输入框(.lazy)

    • 用户输入内容时,数据不会立即更新,直到用户离开输入框(触发 change 事件)。

    • {{ lazyMessage }} 会显示最终的输入内容。

  2. 输入框(.number)

    • 用户输入数字时,数据会自动转换为数字类型。

    • {{ numberValue }} 会显示数字类型的值。

  3. 输入框(.trim)

    • 用户输入内容时,首尾空格会被自动去除。

    • {{ trimMessage }} 会显示去除首尾空格后的内容。

3.3自定义组件中的 v-model 

在自定义组件中,v-model 默认绑定的是子组件的 value 属性和 input 事件。如果你需要自定义 v-model 的行为,可以通过 props$emit 来实现。

<template>
  <div>
    <custom-input v-model="message"></custom-input>
    <p>输入的内容是:{{ message }}</p>
  </div>
</template>

<script>
import CustomInput from './CustomInput.vue';

export default {
  components: {
    CustomInput
  },
  data() {
    return {
      message: ''
    };
  }
};
</script>
<!-- CustomInput.vue -->
<template>
  <input
    :value="value"
    @input="$emit('input', $event.target.value)"
    placeholder="输入内容"
  >
</template>

<script>
export default {
  props: ['value']
};
</script>
  • 工作原理

  • 父组件传递数据到子组件

    • 父组件通过 v-model="message"message 的值传递给子组件的 value prop

    • 子组件的 value prop 会接收这个值,并将其绑定到输入框的 value 属性上。

  • 子组件向父组件发送数据

    • 当用户在输入框中输入内容时,input 事件被触发。

    • 子组件通过 $emit('input', $event.target.value) 将用户输入的值发送回父组件。

    • 父组件监听到 input 事件后,会更新 message 的值。

  • 双向绑定

    • 父组件的 message 和子组件的输入框内容始终保持同步。

    • 用户在输入框中输入的内容会实时更新到父组件的 message 中。

    • 父组件的 message 如果发生变化,输入框的内容也会自动更新。

4.计算属性 Computed

在 Vue 2 中,计算属性(Computed Properties)是一种非常强大的功能,它允许你基于 Vue 实例的数据动态计算值。计算属性是响应式的,当依赖的响应式数据发生变化时,计算属性会自动重新计算并更新。

计算属性通常用于以下场景:

  1. 基于现有数据派生新数据:例如,将用户的输入转换为大写或计算总价。

  2. 简化模板逻辑:避免在模板中编写复杂的逻辑。

  3. 缓存计算结果:计算属性会缓存结果,只有当依赖的数据发生变化时才会重新计算。

计算属性通过 computed 选项定义。计算属性的值由一个函数返回,这个函数的返回值会自动绑定到模板中。

<template>
  <div>
    <p>原字符串:{{ message }}</p>
    <p>大写字符串:{{ upperCaseMessage }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'hello'
    };
  },
  computed: {
    upperCaseMessage() {
      return this.message.toUpperCase();
    }
  }
};
</script>

 

  • data:定义了响应式数据 message

  • computed:定义了计算属性 upperCaseMessage

    • upperCaseMessage 是一个函数,返回 message 的大写形式。

    • 计算属性的值会自动更新,当 message 发生变化时,upperCaseMessage 也会重新计算。

计算属性的缓存机制

计算属性是基于它们的依赖进行缓存的。只有当依赖的响应式数据发生变化时,计算属性才会重新计算。这意味着如果你的依赖数据没有变化,计算属性的值不会重新计算,从而提高性能。

计算属性与方法的区别

计算属性和方法都可以基于数据动态计算值,但它们有一些关键区别:

  1. 缓存机制

    • 计算属性:会缓存结果,只有当依赖的响应式数据发生变化时才会重新计算。

    • 方法:每次调用都会重新计算,不会缓存结果。

  2. 使用场景

    • 计算属性:适用于基于现有数据派生新数据的场景,尤其是需要缓存结果的场景。

    • 方法:适用于需要动态执行的逻辑,例如事件处理函数。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值