index.vue
4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<template>
<view class="min-h-screen flex flex-col bg-white">
<AppHeader title="加入家庭" />
<view class="flex-1 px-4 py-6 flex flex-col">
<!-- Title -->
<h2 class="text-xl font-bold text-center mb-2 mt-4">
输入家训口令
</h2>
<!-- Description -->
<p class="text-gray-600 text-center text-sm mb-6">
请输入家人提供的家训口令,加入家庭一起参与健康挑战
</p>
<!-- Input boxes -->
<view class="flex justify-center gap-3 w-full mb-6">
<view v-for="(char, index) in mottoChars" :key="index" class="w-16 h-16">
<input
:ref="(el) => (inputRefs[index] = el)"
type="text"
v-model="mottoChars[index]"
@input="(e) => handleInputChange(index, e.target.value)"
@keydown="(e) => handleKeyDown(index, e)"
maxlength="1"
class="w-full h-full text-center text-xl border border-gray-300 rounded-md focus:border-blue-500 focus:outline-none"
/>
</view>
</view>
<!-- Help text -->
<p class="text-gray-500 text-center text-sm mb-8">
没有口令?请联系您的大家长获取
</p>
<!-- Role selection -->
<view class="mb-6">
<h3 class="text-base font-medium mb-4 border-t pt-4">
选择您的身份
</h3>
<view class="grid grid-cols-2 gap-3">
<button
v-for="role in familyRoles"
:key="role.id"
:class="[
'flex items-center justify-center p-3 border rounded-md',
selectedRole === role.id
? 'border-blue-500 bg-blue-50'
: 'border-gray-200'
]"
@click="selectedRole = role.id"
>
<view class="flex flex-col items-center">
<My
size="20"
:class="[
'mb-1',
selectedRole === role.id ? 'text-blue-500' : 'text-gray-400'
]"
/>
<span
:class="[
selectedRole === role.id ? 'text-blue-500' : 'text-gray-600'
]"
>
{{ role.label }}
</span>
</view>
</button>
</view>
</view>
<!-- Submit Button -->
<button
@click="handleJoinFamily"
:disabled="!isComplete"
:class="[
'w-full py-4 text-white text-lg font-medium rounded-lg mt-auto',
isComplete ? 'bg-blue-500' : 'bg-gray-300'
]"
>
加入家庭
</button>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue';
import Taro from '@tarojs/taro';
import { My } from '@nutui/icons-vue-taro';
import AppHeader from '../../components/AppHeader.vue';
const mottoChars = ref(['', '', '', '']);
const selectedRole = ref('');
const inputRefs = ref([]);
const handleInputChange = (index, value) => {
if (value && !/^[\u4e00-\u9fa5]$/.test(value)) {
return;
}
mottoChars.value[index] = value;
if (value && index < 3) {
// Taro中无法直接操作DOM进行focus,这里仅保留逻辑
// 在小程序中,可以通过设置 `focus` 属性来控制
}
};
const handleKeyDown = (index, e) => {
if (e.key === 'Backspace' && !mottoChars.value[index] && index > 0) {
// 同样,在Taro中处理光标移动需要不同的方式
}
};
const familyRoles = [
{ id: 'husband', label: '丈夫' },
{ id: 'wife', label: '妻子' },
{ id: 'son', label: '儿子' },
{ id: 'daughter-in-law', label: '儿媳' },
{ id: 'son-in-law', label: '女婿' },
{ id: 'daughter', label: '女儿' },
{ id: 'grandson', label: '孙子' },
{ id: 'maternal-grandson', label: '外孙' },
{ id: 'granddaughter', label: '孙女' },
{ id: 'maternal-granddaughter', label: '外孙女' }
];
const isComplete = computed(() => {
return mottoChars.value.every((char) => char) && selectedRole.value;
});
const handleJoinFamily = () => {
if (isComplete.value) {
Taro.navigateTo({
url: '/pages/Dashboard/index'
});
}
};
</script>