Vue-8-组件双向传值

一、概述

看着别人写的组件,各种知识点不懂,难以理解其中的逻辑,实在没法工作,今天学习下组件传值,子组件既能接收父组件的值,也能返回更新后的值给父组件。
刚好最近看了Cursor,下载试用了下,真是太好用了,对于我这种前端小白来说,大大提升了学习的效率。

二、金额币种输入组件开发

Cursor怎么使用就不说了,大家可以自行搜索,下载后的IDE跟VS简直一模一样,按上Ctrl+L快捷键,快速和AI对话,轻轻松松实现了如下金额币种组件的实现。

<template>
  <div class="input-money">
    <el-select v-model="selectedCurrency" @change="handleCurrencyChange" class="currency-select">
      <el-option v-for="currency in currencies" :key="currency.code" :label="`${currency.code} - ${currency.name}`"
        :value="currency.code" />
    </el-select>
    <el-input v-model="displayValue" @input="handleInput" @blur="handleBlur" @focus="handleFocus" class="money-input" />
  </div>
</template>

<script>
export default {
  name: 'InputMoney',
  props: {
    // ... 现有的 props ...
    value: {
      type: [String, Number],
      default: ''
    },
    currency: {
      type: String,
      default: 'USD'  // 设置默认货币为美元
    }
  },
  data() {
    return {
      displayValue: this.formatValue(this.value),
      selectedCurrency: this.currency,  // 使用 props 中的 currency 初始化
      currencies: [
        { code: 'USD', name: '美元' },
        { code: 'EUR', name: '欧元' },
        { code: 'JPY', name: '日元' },
        { code: 'GBP', name: '英镑' },
        { code: 'CNY', name: '人民币' },
        // 可以根据需要添加更多货币
      ]
    }
  },
  methods: {
    formatValue(value) {
      if (!value) return '';
      value = value.toString().replace(/[^\d.]/g, '');
      const parts = value.split('.');
      parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
      return parts.join('.');
    },
    handleCurrencyChange() {
      this.$emit('update:currency', this.selectedCurrency);
    },
    handleInput(value) {
      const formattedValue = this.formatValue(value);
      this.displayValue = formattedValue;
      this.$emit('input', formattedValue.replace(/,/g, ''));
    },
    handleBlur() {
      let value = this.displayValue.replace(/[^\d.]/g, '');
      const parts = value.split('.');
      if (parts.length > 1) {
        parts[1] = parts[1].slice(0, 2);  // 保留两位小数
      }
      const formattedValue = this.formatValue(parts.join('.'));
      this.displayValue = formattedValue;
      this.$emit('blur', formattedValue.replace(/,/g, ''));
    },
    handleFocus() {
      // 获得焦点时的处理
      this.$emit('focus');
    }
  },
  watch: {
    // ... 现有的 watch ...
    value(newVal) {
      this.displayValue = this.formatValue(newVal);
    },
    currency(newVal) {
      this.selectedCurrency = newVal;
    }
  }
}
</script>

<style scoped>
.input-money {
  display: flex;
  align-items: center;
}

.currency-select {
  width: 150px;
  margin-right: 10px;
}

.money-input {
  flex-grow: 1;
}

/* 移除 Element UI 默认样式 */
.input-money :deep(.el-input__inner),
.input-money :deep(.el-select .el-input__inner) {
  border: 1px solid #ccc;
  border-radius: 4px;
}

.input-money :deep(.el-input__inner:focus),
.input-money :deep(.el-select .el-input__inner:focus) {
  border-color: #007bff;
  box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
</style>

父组件引用也特别方便

<template lang="">
  <div>
    <input-money v-model="amount" :currency="currency" @update:currency="val => currency = val" />

    <div>
      {{currency}} - {{amount}}
    </div>
  </div>
</template>
<script>
import InputMoney from '@/views/input-money/input-money.vue' // 假设组件路径

export default {
  components: {
    InputMoney
  },
  data() {
    return {
      amount: 2112341234,
      currency: "EUR"
    }
  }
}
</script>
<style lang="">

</style>

在父组件中就可以通过访问amount和currency变量,轻松初始化组件的值以及获取子组件修改后的值,实现双向绑定。

三、总结

本次复习的关键知识点为组件双向绑定,有如下两个知识点。

3.1 v-model双向绑定

默认就实现了双向绑定,无需特殊处理。子组件中需要定义value属性,与v-model对应。

  props: {
    // ... 现有的 props ...
    value: {
      type: [String, Number],
      default: ''
    },
    currency: {
      type: String,
      default: 'USD'  // 设置默认货币为美元
    }
  },
3.2 currency实现双向绑定

有两种方法,一种使用.sync语法糖实现,这种比较简单,实际使用这种也比较多。本次采用另外一种复杂的写法。 在父组件中定义:currency 以及@update:currency属性。

<input-money v-model="amount" :currency="currency" @update:currency="val => currency = val" />

在子组件中生命emit方法,通过币种下拉框的change事件,调用到emit方法。

    <el-select v-model="selectedCurrency" @change="handleCurrencyChange" class="currency-select">
      <el-option v-for="currency in currencies" :key="currency.code" :label="`${currency.code} - ${currency.name}`"
        :value="currency.code" />
    </el-select>
    
    handleCurrencyChange() {
      this.$emit('update:currency', this.selectedCurrency);
    },
3.3 夸一夸Cursor

首次使用AI进行编程,体验真的很好,好的工具真的能提升工作效率,也会帮助我们更高效的学习。Cursor有点贵,先试用两周看看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值