vue子组件修改父组件传递的变量(自定义日期时间组件,通过粒度控制时间控件的时间间隔为15分钟或者一个小时,天,月)

文章讲述了在Vue应用中,如何让子组件通过调用父组件的方法来修改从父组件传递的数据,包括在父组件中声明变量,使用props接收和@emit触发父组件方法的详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue子组件修改父组件传递的变量

子组件不能直接修改父组件变量的值,但是可以通过调用父组件的方法来修改。

实现步骤

在父组件声明变量

export default {
  data() {
    return {
		startTime:"",
		......
	},
	......
  }
}

在父组件使用子组件并传递数据,修改变量

......
<!-- :startValue传值,@editStartValue修改父组件变量方法editStartTime -->
<date-time-picker 
	:startValue="startTime" 
	@editStartValue="editStartTime">
</date-time-picker>
......
export default {
  ......
  methods: {
		editStartTime(val){
			this.startTime=val;
		}
  }
}

在子组件中接收值,并调用父组件方法修改父组件的变量

//接收变量值
props: {
    startValue: {
      type: String,
      default: "",
    },
    ......
}
//调用父组件方法将值传给父组件
editStartValue() {
	this.$emit("editStartValue", '2023-08-02 00:00:00');
},

以上步骤只是逻辑步骤和部分代码,以下有完整代码:
我的这个自定义时间控件,可选择范围:
粒度为1时:时间组件的时间间隔为15分钟。
粒度为2时:时间组件的时间间隔为1小时。
粒度为3时:时间组件只能选择日期,不能选择时间。
粒度为4时:时间组件只能选择月份。

父组件

<template>
  <div>
  	<!-- 自定义时间组件 -->
  	<date-time-picker 
  		:particle="particle" 
  		:startValue="startTime" 
  		:endValue="endTime" 
  		@editStartValue="editStartTime" 
  		@editEndValue="editEndTime">
    </date-time-picker>
  </div>
</template>

<script>
//引入子组件
import dateTimePicker from './date-time-picker.vue';
export default {
  components: { dateTimePicker },
  data() {
    return {
    	//1:时间组件的时间间隔为15分钟,
    	//2:时间组件的时间间隔为1小时,
    	//3:时间组件只能选择日期,不能选择时间,
    	//4:时间组件只能选择月份
		particle:"1",
		startTime:"",
		endTime:"",
	},
	methods: {
		editStartTime(val){
			this.startTime=val;
		},
		editEndTime(val){
			this.endTime=val;
		},
	}
  }
}
</script>

子组件

<template>
  <div>
    <!-- 开始时间 -->
    <el-time-select
      v-model="startTime"
      style="width: 120px"
      :picker-options="startTimeOptions"
      placeholder=""
      prefix-icon="false"
      @change="startTimeChange"
      ref="startTime"
    >
    </el-time-select>

    <el-date-picker
      v-model="startDate"
      :type="dateType"
      ref="startDate"
      placeholder=""
      style="width: 120px; margin-left: -120px"
      :picker-options="startDateOptions"
      @change="startDateChange"
      value-format="yyyy-MM-dd"
    >
    </el-date-picker>

    <div
      @click="handleClickStart"
      style="width: 180px; margin-left: -120px; display: inline-block"
    >
      <el-input
        v-model="startInput"
        size="small"
        ref="startInput"
        :placeholder="placeholderStart"
        prefix-icon="el-icon-date"
      >
      </el-input>
    </div>

    <!-- 结束时间 -->
    <el-time-select
      v-model="endTime"
      style="width: 120px"
      :picker-options="endTimeOptions"
      placeholder=""
      prefix-icon="false"
      @change="endTimeChange"
      ref="endTime"
    >
    </el-time-select>

    <el-date-picker
      v-model="endDate"
      :type="dateType"
      ref="endDate"
      placeholder=""
      style="width: 120px; margin-left: -120px"
      :picker-options="endDateOptions"
      @change="endDateChange"
      value-format="yyyy-MM-dd"
    >
    </el-date-picker>

    <div
      @click="handleClickEnd"
      style="width: 180px; margin-left: -120px; display: inline-block"
    >
      <el-input
        v-model="endInput"
        size="small"
        ref="endInput"
        :placeholder="placeholderEnd"
        prefix-icon="el-icon-date"
      >
      </el-input>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    //particle为1时间间隔15分钟,为2时间间隔1小时,为3只能选择日期不能选择时间
    particle: {
      type: String,
      default: "",
    },
    startValue: {
      type: String,
      default: "",
    },
    endValue: {
      type: String,
      default: "",
    },
    placeholderStart: {
      type: String,
      default: "开始时间",
    },
    placeholderEnd: {
      type: String,
      default: "结束时间",
    },
  },
  watch: {
    particle(newVal, oldVal) {
      //月粒度时,日期类型为month,其他粒度时日期类型为date
      if(newVal==="4"){
        this.dateType="month";
      }else{
        this.dateType="date";
      }
      this.startInput = "";
      this.endInput = "";
      (this.startDate = ""),
        (this.startTime = ""),
        (this.endDate = ""),
        (this.endTime = "");
    },
  },
  created(){
    this.startDate= (this.startInput!=""&&this.startInput.length===19)?this.startInput.substring(0,11):"",
    this.startTime= (this.startInput!=""&&this.startInput.length===19)?this.startInput.substring(11,16):"",
    this.endDate= (this.endInput!=""&&this.endInput.length===19)?this.endInput.substring(0,11):"",
    this.endTime= (this.endInput!=""&&this.endInput.length===19)?this.endInput.substring(11,16):""
    this.editStartValue();
    this.editEndValue();
    // console.log("-----"+this.startInput+"-----");
    // console.log("-----"+this.endInput+"-----");
    // console.log("-----"+this.startDate+"-----");
    // console.log("-----"+this.startTime+"-----");
    // console.log("-----"+this.endDate+"-----");
    // console.log("-----"+this.endTime+"-----");
  },
  data() {
    return {
      startInput:(this.startValue!=null&&this.startValue!=undefined&&this.startValue.length===19)?this.timeFormat(this.startValue,this.particle):"",
      endInput:(this.endValue!=null&&this.endValue!=undefined&&this.endValue.length===19)?this.timeFormat(this.endValue,this.particle):"",
      dateType: "date",
      startDate: "",
      startTime: "",
      endDate: "",
      endTime: "",
      startTimeOptions: {
        start: "00:00",
        step: "01:00",
        end: "23:59",
        maxTime: "",
      },
      endTimeOptions: {
        start: "00:00",
        step: "01:00",
        end: "23:59",
        minTime: "",
      },
      startDateOptions: {
        disabledDate: (time) => {
          if (this.endDate != "") {
            var now = new Date(this.endDate + " 00:00:00");
            return time.getTime() > now.getTime();
          } else {
            return false;
          }
        },
      },
      endDateOptions: {
        disabledDate: (time) => {
          if (this.startDate != "") {
            var now = new Date(this.startDate + " 00:00:00");
            return time.getTime() < now.getTime();
          } else {
            return false;
          }
        },
      },
    };
  },
  methods: {
    //将传入的时间字符串改为
    timeFormat(val,particle) {
      var str="";
      if (particle === "3"||particle === "4") {
        str = val.substring(0, 13);
        var date = new Date(val);
        var minutes = date.getMinutes();
        if (minutes / 15 === 0) {
          str = str + ":00:00";
        }
        if (minutes / 15 === 1) {
          str = str + ":15:00";
        }
        if (minutes / 15 === 2) {
          str = str + ":30:00";
        }
        if (minutes / 15 === 3) {
          str = str + ":45:00";
        }
      }
      if (particle === "2") {
        str = val.substring(0, 13);
        str = str + ":00:00";
      }
      if (particle === "1") {
        str = val.substring(0, 11);
        str = str + "00:00:00"; 
      }
      return str;
    },

    //开始输入框点击事件
    handleClickStart() { 
      if (this.startInput.length == 19) {
        this.startDate = this.startInput.substring(0, 11);
      } else {
        if(this.particle==="4"&&this.startInput!=""){
          this.startDate = this.startInput+"-01";
        }else{
          this.startDate = this.startInput;
        }
      }
      this.$refs.startDate.focus();
    },
    //结束输入框点击事件
    handleClickEnd() {
      if (this.endInput.length == 19) {
        this.endDate = this.endInput.substring(0, 11);
      } else {
        if(this.particle==="4"&&this.endInput!=""){
          this.endDate = this.endInput+"-01";
        }else{
          this.endDate = this.endInput;
        }
      }
      this.$refs.endDate.focus();
    },
    //选择开始日期后调出开始时间
    startDateChange() {
      if (this.startTime === "") {
        //this.startTime="00:00";
        this.startInput = this.startDate + " 00:00:00";
      } else {
        this.startInput = this.startDate + " " + this.startTime + ":00";
      }

      //月粒度展示YYYY-MM-DD,其余粒度展示YYYY-MM-DD HH:MM:SS
      if(this.particle==="4"||this.particle==="3"){
        this.startInput=this.startInput.substring(0,10)+" 00:00:00";
      }

      this.editStartValue();
      if (this.particle != "3"&&this.particle != "4") {
        if (this.particle === "1") {
          this.startTimeOptions.step = "00:15";
        }
        if (this.particle === "2") {
          this.startTimeOptions.step = "01:00";
        }
        if (this.endInput.includes(this.startDate) && this.endTime != "") {
          this.startTimeOptions.maxTime = this.endTime;
        }else{
          this.startTimeOptions.maxTime ="";
        }
        this.$refs.startTime.focus();
      }
    },
    //选择开始时间后赋值给开始输入框
    startTimeChange() {
      this.startInput = this.startDate + " " + this.startTime + ":00";
      this.editStartValue();
    },
    //将值传给父组件
    editStartValue() {
      this.$emit("editStartValue", this.startInput);
      if(this.particle==="4"){
        this.startInput=this.startInput.substring(0,7);
      }else if(this.particle==="3"){
        this.startInput=this.startInput.substring(0,10);
      }
      
    },

    //选择结束日期后调出结束时间
    endDateChange() {
      if (this.endTime === "") {
        //this.endTime="00:00";
        this.endInput = this.endDate + " 00:00:00";
      } else {
        this.endInput = this.endDate + " " + this.endTime + ":00";
      }

      //月粒度展示YYYY-MM-DD,其余粒度展示YYYY-MM-DD HH:MM:SS
      if(this.particle==="4"){
        this.endInput=this.$util.getEndOfMonth(this.endInput.substring(0,10))+" 23:59:59";
      }
      if(this.particle==="3"){
        this.endInput=this.endInput.substring(0,10)+" 23:59:59";
      }

      this.editEndValue();
      if (this.particle != "3"&&this.particle != "4") {
        if (this.particle === "1") {
          this.endTimeOptions.step = "00:15";
        }
        if (this.particle === "2") {
          this.endTimeOptions.step = "01:00";
        }
        if (this.startInput.includes(this.endDate) && this.startTime != "") {
          this.endTimeOptions.minTime = this.startTime;
        }else{
          this.endTimeOptions.minTime = "";
        }
        this.$refs.endTime.focus();
      }
    },
    //选择结束时间后赋值给结束输入框
    endTimeChange() {
      this.endInput = this.endDate + " " + this.endTime + ":00";
      this.editEndValue();
    },
    //将值传给父组件
    editEndValue() {
      this.$emit("editEndValue", this.endInput);
      if(this.particle==="4"){
        this.endInput=this.endInput.substring(0,7);
      }else if(this.particle==="3"){
        this.endInput=this.endInput.substring(0,10);
      }
    },
  },
};
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值