vue.js实现仿原生ios时间选择组件实例代码

下面就是“vue.js实现仿原生ios时间选择组件实例代码”的完整攻略。

一、需求分析

首先,我们需要明确该时间选择组件的需求。该组件应该具有以下几个特点:

  • 类似原生 iOS 的时间选择器的样式;
  • 可以选择小时、分钟;
  • 通过点击取消和确认按钮,可以改变选择的时间;
  • 可以通过外部传入初始时间;
  • 选择时间后,应该将选择的时间通过事件回传给外部。

二、实现思路

经过需求分析,我们可以确定该选择器需要至少两个组件:一个是显示时间的组件,另一个是选择时间的组件。

我们可以先实现一个选择时间的组件,在组件内,使用 Range Slider 实现选择小时和分钟的功能。然后,使用 Vue 的路由功能,在主页上添加一个按钮,点击该按钮,页面跳转到选择器页面,并加载时间选择器组件。

在选择器页面中,将选择器组件和确认、取消按钮放在一个模拟的 iPhone 工具条中,通过该工具条向上滑动时显示。选择器组件接收外部传入的时间参数,并可通过 emit 方法向外部回传选择的时间。

三、代码实现

1. 选择器组件

选择器组件需要有以下功能:

  • 根据外部传入的时间参数初始化显示时间;
  • 使用 Range Slider 组件实现选择小时和分钟的功能;
  • 点击取消和确认按钮时,返回选择的时间。

代码如下:

<template>
  <div class="picker-container">
    <div class="picker-mask"></div>
    <div class="picker">
      <div class="picker-header">
        <button class="cancel-button" @click="cancel">取消</button>
        <button class="confirm-button" @click="confirm">确定</button>
      </div>
      <div class="picker-body">
        <div class="picker-column">
          <div class="picker-label">{{ "0" + hour }}</div>
          <input type="range" min="1" max="24" class="picker-range" @input="setHour" v-model="hour" />
        </div>
        <div class="picker-divider"></div>
        <div class="picker-column">
          <div class="picker-label">{{ "0" + minute }}</div>
          <input type="range" min="0" max="59" class="picker-range" @input="setMinute" v-model="minute" />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    // 初始化时间
    time: {
      type: String,
      default: "00:00",
    },
  },
  data() {
    const [hour, minute] = this.time.split(":");
    return {
      hour,
      minute,
    };
  },
  methods: {
    // 设置小时
    setHour(event) {
      this.hour = event.target.value.padStart(2, "0");
    },
    // 设置分钟
    setMinute(event) {
      this.minute = event.target.value.padStart(2, "0");
    },
    // 确定按钮点击事件
    confirm() {
      this.$emit("pick", `${this.hour}:${this.minute}`);
    },
    // 取消按钮点击事件
    cancel() {
      this.$emit("cancel");
    },
  },
};
</script>

<style scoped>
.picker-container {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.picker-mask {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}
.picker {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 500px;
  height: 200px;
  margin: 0 20px;
  background-color: #f5f5f5;
  border-radius: 5px;
  overflow: hidden;
}
.picker-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 40px;
  padding: 0 10px;
  background-color: #eee;
}
.picker-header button {
  font-size: 16px;
  font-weight: bold;
  color: #007aff;
  background: none;
  border: none;
  outline: none;
  cursor: pointer;
}
.picker-body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  padding: 20px;
}
.picker-column {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.picker-label {
  font-size: 36px;
  font-weight: bold;
}
.picker-range {
  width: 100%;
  margin-top: 10px;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}
.picker-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  background-color: #007aff;
  border-radius: 50%;
  cursor: pointer;
}
.picker-range::-moz-range-thumb {
  -moz-appearance: none;
  width: 16px;
  height: 16px;
  background-color: #007aff;
  border-radius: 50%;
  cursor: pointer;
}
.picker-divider {
  margin: 0 20px;
  border-right: 1px solid #ccc;
}
</style>

2. 主页

在主页中添加一个按钮,点击该按钮,跳转到选择器页面。代码如下:

<template>
  <div>
    <button class="show-picker-button" @click="showPicker">显示时间选择器</button>
  </div>
</template>

<script>
export default {
  methods: {
    showPicker() {
      this.$router.push("/picker");
    },
  },
};
</script>

<style scoped>
.show-picker-button {
  background-color: #007aff;
  color: #fff;
  font-size: 16px;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
</style>

3. 选择器页面

在选择器页面中,将选择器组件、确认、取消按钮放在一个模拟的 iPhone 工具条中。代码如下:

<template>
  <div class="picker-page">
    <comp-iphonetoolbar>
      <h1 slot="title">时间选择器</h1>
      <span slot="left" @click="cancel">取消</span>
      <span slot="right" @click="confirm">确定</span>
    </comp-iphonetoolbar>
    <picker :time="time" @pick="pick" @cancel="cancel" />
  </div>
</template>

<script>
import CompIphoneToolbar from "@/components/CompIphoneToolbar";
import Picker from "@/components/Picker";

export default {
  components: {
    CompIphoneToolbar,
    Picker,
  },
  data() {
    return {
      time: "12:00",
    };
  },
  methods: {
    // 确定按钮点击事件,将选择的时间保存
    confirm(time) {
      this.time = time;
      this.$router.go(-1);
    },
    // 取消按钮点击事件,返回上一页
    cancel() {
      this.$router.go(-1);
    },
    // 接收选择器组件发出的时间事件
    pick(time) {
      this.time = time;
    },
  },
};
</script>

<style scoped>
.picker-page {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

到这里,可以启动项目,点击主页上的按钮,跳转到选择器页面,并显示时间选择器。选择时间后,点击确认按钮,返回主页,显示选择的时间。

4. 示例说明

示例1:在主页上添加两个按钮

在主页上,添加一个按钮,点击该按钮显示时间选择器,并将选择的时间保存。再添加一个按钮,点击该按钮显示上次保存的时间。

代码如下:

<template>
  <div>
    <button @click="showPickerAndSave">选择时间并保存</button>
    <button @click="showPickerWithLastSavedTime">显示上次保存的时间</button>
    <div v-if="!!lastSavedTime">上次保存的时间是{{ lastSavedTime }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      lastSavedTime: "",
    };
  },
  methods: {
    async showPickerAndSave() {
      const { default: Picker } = await import("../components/Picker");

      const time = await new Promise((resolve) => {
        const PickerView = Vue.extend(Picker);
        const vm = new PickerView({
          propsData: {
            time: this.lastSavedTime || "12:00",
          },
          methods: {
            pick(time) {
              resolve(time);
            },
            cancel() {
              resolve(false);
            },
          },
        }).$mount();

        document.querySelector("body").appendChild(vm.$el);
      });

      if (time !== false) {
        this.lastSavedTime = time;
      }
    },
    async showPickerWithLastSavedTime() {
      const { default: Picker } = await import("../components/Picker");

      await new Promise((resolve) => {
        const PickerView = Vue.extend(Picker);
        const vm = new PickerView({
          propsData: {
            time: this.lastSavedTime || "12:00",
          },
          methods: {
            pick(time) {
              resolve(time);
            },
            cancel() {
              resolve(false);
            },
          },
        }).$mount();

        document.querySelector("body").appendChild(vm.$el);
      });
    },
  },
};
</script>

示例2:支持多个时间选择器

该示例需要在主页添加一个按钮,点击该按钮可以添加一个时间选择器组件。每个时间选择器组件都可以选择不同的时间,并可以通过事件回传选择的时间。

代码如下:

<template>
  <div>
    <button @click="addPicker">添加时间选择器</button>
    <comp-iphonetoolbar v-if="pickers.length">
      <h1 slot="title">选择时间</h1>
      <span slot="left" @click="cancel">取消</span>
      <span slot="right" @click="confirm">确定</span>
    </comp-iphonetoolbar>
    <picker v-for="(picker, index) in pickers" :key="index" :time="picker" @pick="pick(index)" />
  </div>
</template>

<script>
import CompIphoneToolbar from "@/components/CompIphoneToolbar";
import Picker from "@/components/Picker";

export default {
  components: {
    CompIphoneToolbar,
    Picker,
  },
  data() {
    return {
      pickers: ["12:00"],
    };
  },
  methods: {
    // 添加时间选择器
    addPicker() {
      this.pickers.push("12:00");
    },
    // 接收选择器组件发出的时间事件
    pick(index) {
      return (time) => {
        this.$set(this.pickers, index, time);
      };
    },
    // 确定按钮点击事件,将选择的时间保存
    confirm() {
      console.log(this.pickers);
      this.$router.go(-1);
    },
    // 取消按钮点击事件,返回上一页
    cancel() {
      this.$router.go(-1);
    },
  },
};
</script>

<style scoped>
.picker-page {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

注意这个示例采用了响应式 APIpickers数组中的元素改变时需要使用$set方法来更新 DOM。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue.js实现仿原生ios时间选择组件实例代码 - Python技术站

(0)
上一篇 2023年5月29日
下一篇 2023年5月29日

相关文章

  • vue中对象的赋值Object.assign({}, row)方式

    在Vue中,我们经常需要对对象进行赋值。而Object.assign()是一个常用的对象赋值操作,尤其常用于实现浅拷贝。在Vue中,我们可以使用Object.assign({}, row)来实现浅拷贝,将row对象的所有属性和方法赋值给一个空对象。 以下是Object.assign()的基本语法: Object.assign(target, source1,…

    Vue 2023年5月28日
    00
  • vue 实现强制类型转换 数字类型转为字符串

    要在 Vue 中实现数字类型转为字符串的强制类型转换,可以通过以下两种方式实现: 1. 使用 JavaScript 中的 toString() 方法 JavaScript 中的 toString() 方法可将数字类型转为字符串。在Vue模板中,可以在绑定表达式时使用toString()方法强制类型转换。 示例如下: <template> <…

    Vue 2023年5月27日
    00
  • vue中$nextTick的用法讲解

    关于“vue中$nextTick的用法讲解”的完整攻略,我会从以下几个方面详细讲解: $nextTick的概念及作用 $nextTick的基本用法 $nextTick的示例说明 1. $nextTick的概念及作用 在Vue.js中,异步更新DOM是一个核心特性。当我们对一个Vue实例的数据进行修改时,Vue会在内部进行异步更新DOM的操作,而不是直接同步更…

    Vue 2023年5月29日
    00
  • vue开发chrome插件,实现获取界面数据和保存到数据库功能

    准备工作 在开发vue开发chrome插件前,我们需要先安装vue-cli脚手架和Chrome浏览器。 安装命令: npm install -g vue-cli 创建新项目 通过vue-cli脚手架创建新项目,并选择webpack模板。 vue init webpack my-project 安装依赖: cd my-project && np…

    Vue 2023年5月28日
    00
  • vue-cli3.0如何修改端口号

    要修改Vue-CLI 3.0项目的端口号,可按照以下步骤进行操作: 打开package.json文件,找到scripts字段下的serve属性。 在serve属性中添加一个”–port”参数并设置一个新的端口号。例如,要将端口号修改为3002,可修改成如下代码: "scripts": { "serve": &quot…

    Vue 2023年5月28日
    00
  • laravel 解决Validator使用中出现的问题

    下面我来给您详细讲解“laravel 解决Validator使用中出现的问题”的完整攻略。 1. Validator 概述 Laravel 的 Validator 是一个非常实用的功能,用于验证用户提交的数据是否符合规范。使用 Validator 可以快速轻松地实现表单验证和数据验证功能。但是在使用 Validator 的过程中,可能会遇到一些问题,本篇攻略…

    Vue 2023年5月28日
    00
  • vue中计算属性和方法的区别及说明

    Vue中计算属性和方法是两种常用的方式来处理数据的操作和计算。它们有不同的特点和用途,下面就具体说一下它们在使用中的区别及说明。 计算属性 计算属性是Vue中用于动态计算和返回结果的属性。计算属性会根据响应式数据的变化自动更新计算结果。计算属性有以下几个特点: 计算属性会缓存计算结果,只有在响应式数据发生变化时才会重新计算。这种缓存主要是为了避免重复计算和提…

    Vue 2023年5月27日
    00
  • Vue防抖与节流的使用介绍

    我来为你详细讲解“Vue防抖与节流的使用介绍”的完整攻略,请仔细阅读以下内容: 什么是防抖和节流 在介绍防抖和节流之前,我们先来了解一下两个重要概念: 函数调用频率:函数被调用的次数。比如说,你在搜索框中输入关键字,搜索框会实时检索结果,此时,输入的操作就是函数,它被调用的频率就是你输入的频率。 函数执行时间:函数运行所需的时间。比如说,你在网页上点击一个按…

    Vue 2023年5月29日
    00
合作推广
合作推广
分享本页
返回顶部