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 动态路由的实现详情

    下面就为大家详细讲解一下「Vue 动态路由的实现详情」。 什么是动态路由? Vue 路由是一种 URL 和组件之间的映射关系,并通过 URL 触发组件的展示。而动态路由则是在 URL 中传递参数,根据参数的不同动态匹配相应的路由。例如 /article/1 和 /article/2 都可以匹配到文章详情页路由,只不过参数不同。在 Vue 中,我们可以通过“路…

    Vue 2023年5月28日
    00
  • ant-design-vue时间线使用踩坑及解决

    ant-design-vue 时间线使用踩坑及解决 简介 ant-design-vue 是基于 Vue.js 的 UI 组件库,其中时间线组件可以方便地呈现时间序列。本文主要讲解在使用 ant-design-vue 时间线组件过程中的常见问题及解决方案。 踩坑 设置时间线节点图标为空时,图标仍然显示圆形 在 ant-design-vue 时间线组件中,可以通…

    Vue 2023年5月29日
    00
  • vue a标签点击实现赋值方式

    下面是关于“vue a标签点击实现赋值方式”的完整攻略。 思路 在Vue中,我们可以直接通过v-bind指令将数据绑定到HTML标签的属性上,然后通过v-on指令监听标签上的事件,使得在事件触发时可以改变数据的值。因此,针对“vue a标签点击实现赋值方式”的问题,我们的思路是,使用v-bind指令将需要赋值的数据绑定到a标签的属性上,然后使用v-on指令监…

    Vue 2023年5月27日
    00
  • vue cli3.x打包后如何修改生成的静态资源的目录和路径

    要修改Vue Cli 3.x生成的静态资源的目录和路径,步骤如下: 打开 vue.config.js 文件,如果没有该文件则需要手动创建,该文件需要放在项目根目录下。 在该文件中添加如下代码: module.exports = { publicPath: ‘./your-path/’ } 其中,publicPath 表示静态资源的目录和路径,./your-p…

    Vue 2023年5月27日
    00
  • vue中的vue-router query方式和params方式详解

    Vue中的Vue-Router query方式和params方式详解 前言 在线路切换时,Vue提供了Vue-Router作为前端路由。 Vue-Router更好地配合Vue完成SPA(单页应用)的构造,相信很多使用过Vue-cli的开发者都踩过Vue-Router的坑。 本文将详细介绍Vue-Router的query方式和params方式作为前端路由传参。…

    Vue 2023年5月27日
    00
  • 加快Vue项目的开发速度的方法

    下面是关于加快Vue项目开发速度的方法的完整攻略: 加快Vue项目开发速度的方法 1. 使用Vue CLI来快速创建项目 Vue CLI是Vue官方提供的脚手架工具,可以快速搭建一个Vue项目的基础结构。使用Vue CLI可以大大降低我们的开发时间和成本。按照以下步骤使用Vue CLI: 安装Vue CLI npm install -g @vue/cli 创…

    Vue 2023年5月28日
    00
  • vue实现添加与删除图书功能

    作为网站作者,我很愿意为您详细讲解“vue实现添加与删除图书功能”的完整攻略。 1.添加图书功能 首先,在vue中实现添加图书功能,需要先创建组件。接下来,我们先来看一个添加图书的示例: 1.1创建组件 我们先在src目录下创建一个名为“AddBook.vue”的组件。在这个组件中,我们需要定义一个表单,以便用户可以输入书籍信息。代码如下: <temp…

    Vue 2023年5月29日
    00
  • vue 组件使用中的一些细节点

    下面我来详细讲解一下vue组件使用中的一些细节点。 组件标签名的命名 在Vue中使用组件需要先在Vue实例中注册该组件,命名时需要注意以下几点: 组件标签名建议使用连字符形式如 <my-component></my-component>,而不是驼峰式形式如 <MyComponent></MyComponent>…

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