下面就是“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>
注意这个示例采用了响应式 API,pickers
数组中的元素改变时需要使用$set
方法来更新 DOM。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue.js实现仿原生ios时间选择组件实例代码 - Python技术站