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

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

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

实现步骤

在父组件声明变量

c 复制代码
export default {
  data() {
    return {
		startTime:"",
		......
	},
	......
  }
}

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

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

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

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

以上步骤只是逻辑步骤和部分代码,以下有完整代码:

父组件

html 复制代码
<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:时间组件只能选择日期,不能选择时间,
		particle:"1",
		startTime:"",
		endTime:"",
	},
	methods: {
		editStartTime(val){
			this.startTime=val;
		},
		editEndTime(val){
			this.endTime=val;
		},
	}
  }
}
</script>

子组件

html 复制代码
<template>
  <div>
    <!-- 开始时间-------------------------------------  -->
    <el-time-select
      v-model="startTime"
      style="width: 135px"
      :picker-options="startTimeOptions"
      placeholder=""
      prefix-icon="false"
      @change="startTimeChange"
      ref="startTime"
    >
    </el-time-select>
	<!-- 开始日期 -->
    <el-date-picker
      v-model="startDate"
      type="date"
      ref="startDate"
      placeholder=""
      style="width: 135px; margin-left: -135px"
      :picker-options="startDateOptions"
      @change="startDateChange"
      value-format="yyyy-MM-dd"
    >
    </el-date-picker>
	
	<!-- 选中的开始日期和开始时间展示 -->
    <div
      @click="handleClickStart"
      style="width: 200px; margin-left: -135px; 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: 135px"
      :picker-options="endTimeOptions"
      placeholder=""
      prefix-icon="false"
      @change="endTimeChange"
      ref="endTime"
    >
    </el-time-select>
	<!-- 结束日期 -->
    <el-date-picker
      v-model="endDate"
      type="date"
      ref="endDate"
      placeholder=""
      style="width: 135px; margin-left: -135px"
      :picker-options="endDateOptions"
      @change="endDateChange"
      value-format="yyyy-MM-dd"
    >
    </el-date-picker>

	<!-- 选中的结束日期和结束时间展示 -->
    <div
      @click="handleClickEnd"
      style="width: 200px; margin-left: -135px; 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) {
      this.startInput = "";
      this.endInput = "";
      (this.startDate = ""),
        (this.startTime = ""),
        (this.endDate = ""),
        (this.endTime = "");
    },
  },
  created(){
  	//页面创建时判断父组件是否传入默认值(格式:yyyy-MM-dd hh:mm:ss),传入时给日期和时间赋值
    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):""
  },
  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):"",
      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") {
        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 {
        this.startDate = this.startInput;
      }
      this.$refs.startDate.focus();
    },
    //结束输入框点击事件
    handleClickEnd() {
      if (this.endInput.length == 19) {
        this.endDate = this.endInput.substring(0, 11);
      } else {
        this.endDate = this.endInput;
      }
      this.$refs.endDate.focus();
    },
    //选择开始日期后调出开始时间
    startDateChange() {
      if (this.startTime === "") {
        this.startInput = this.startDate + " 00:00:00";
      } else {
        this.startInput = this.startDate + " " + this.startTime + ":00";
      }
      this.editStartValue();
      if (this.particle != "3") {
        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;
        }
        this.$refs.startTime.focus();
      }
    },
    //选择开始时间后赋值给开始输入框
    startTimeChange() {
      this.startInput = this.startDate + " " + this.startTime + ":00";
      this.editStartValue();
    },
    //将值传给父组件
    editStartValue() {
      this.$emit("editStartValue", this.startInput);
    },

    //选择结束日期后调出结束时间
    endDateChange() {
      if (this.endTime === "") {
        this.endInput = this.endDate + " 00:00:00";
      } else {
        this.endInput = this.endDate + " " + this.endTime + ":00";
      }
      this.editEndValue();
      if (this.particle != "3") {
        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;
        }
        this.$refs.endTime.focus();
      }
    },
    //选择结束时间后赋值给结束输入框
    endTimeChange() {
      this.endInput = this.endDate + " " + this.endTime + ":00";
      this.editEndValue();
    },
    //将值传给父组件
    editEndValue() {
      this.$emit("editEndValue", this.endInput);
    },
  },
};
</script>
相关推荐
_斯洛伐克1 小时前
下降npm版本
前端·vue.js
苏十八2 小时前
前端进阶:Vue.js
前端·javascript·vue.js·前端框架·npm·node.js·ecmascript
st紫月2 小时前
用MySQL+node+vue做一个学生信息管理系统(四):制作增加、删除、修改的组件和对应的路由
前端·vue.js·mysql
乐容3 小时前
vue3使用pinia中的actions,需要调用接口的话
前端·javascript·vue.js
似水明俊德3 小时前
ASP.NET Core Blazor 5:Blazor表单和数据
java·前端·javascript·html·asp.net
至天4 小时前
UniApp 中 Web/H5 正确使用反向代理解决跨域问题
前端·uni-app·vue3·vue2·vite·反向代理
与墨学长4 小时前
Rust破界:前端革新与Vite重构的深度透视(中)
开发语言·前端·rust·前端框架·wasm
H-J-L5 小时前
Web基础与HTTP协议
前端·http·php
Amore05255 小时前
React+TS前台项目实战(二十三)-- 基于属性自定义数值显示组件Decimal封装
前端·react.js·typescript·前端框架
friklogff5 小时前
【JavaScript脚本宇宙】美化网格布局:Isotope和Masonry让你的网页焕然一新
开发语言·前端·javascript