OnboardingGuide.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <template>
  2. <view class="onboarding-overlay" v-if="show">
  3. <view class="onboarding-card">
  4. <!-- 顶部品牌条 -->
  5. <view class="onboarding-topbar"></view>
  6. <!-- 步骤内容 -->
  7. <view class="onboarding-content" :key="currentStep">
  8. <text class="onboarding-icon">{{ steps[currentStep].icon }}</text>
  9. <text class="onboarding-title">{{ steps[currentStep].title }}</text>
  10. <text class="onboarding-desc">{{ steps[currentStep].desc }}</text>
  11. </view>
  12. <!-- 步进器 -->
  13. <view class="onboarding-dots">
  14. <view
  15. v-for="(s, i) in steps"
  16. :key="i"
  17. class="dot"
  18. :class="{ active: i === currentStep }">
  19. </view>
  20. </view>
  21. <!-- 按钮 -->
  22. <view class="onboarding-action">
  23. <view
  24. class="onboarding-btn"
  25. :class="{ 'onboarding-btn--last': currentStep === steps.length - 1 }"
  26. @click="handleNext">
  27. <text>{{ currentStep < steps.length - 1 ? '下一步' : '开始体验!' }}</text>
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. </template>
  33. <script>
  34. var PARENT_STEPS = [
  35. {
  36. icon: '🌏',
  37. title: '五维能量沙盘',
  38. desc: '这是你家的五维全景图,身·心·智·行·富,每个维度一目了然,帮你全面掌握家庭成长状态'
  39. },
  40. {
  41. icon: '📋',
  42. title: '任务激励系统',
  43. desc: '给孩子布置小任务,完成后获得星星积分,养成好习惯就这么简单'
  44. },
  45. {
  46. icon: '🎁',
  47. title: '心愿兑换',
  48. desc: '孩子用积分兑换心愿,努力就有回报,培养目标感和延迟满足能力'
  49. }
  50. ]
  51. var CHILD_STEPS = [
  52. {
  53. icon: '🌟',
  54. title: '赚星星',
  55. desc: '完成爸爸妈妈布置的任务,就能获得星星积分,越努力越多!'
  56. },
  57. {
  58. icon: '🎮',
  59. title: '玩中学',
  60. desc: '完成任务后可以玩小游戏、兑换心愿,学习和快乐两不误!'
  61. },
  62. {
  63. icon: '🏆',
  64. title: '升级挑战',
  65. desc: '从星星宝宝到宇宙小英雄,一步步升级,看看你能走多远!'
  66. }
  67. ]
  68. export default {
  69. name: 'OnboardingGuide',
  70. props: {
  71. role: { type: String, default: 'parent' },
  72. show: { type: Boolean, default: false }
  73. },
  74. data() {
  75. return {
  76. currentStep: 0
  77. }
  78. },
  79. computed: {
  80. steps() {
  81. if (this.role === 'child') return CHILD_STEPS
  82. return PARENT_STEPS
  83. }
  84. },
  85. watch: {
  86. show(val) {
  87. if (val) {
  88. this.currentStep = 0
  89. }
  90. }
  91. },
  92. methods: {
  93. handleNext() {
  94. if (this.currentStep < this.steps.length - 1) {
  95. this.currentStep++
  96. } else {
  97. uni.setStorageSync('_onboardingDone', true)
  98. this.$emit('close')
  99. }
  100. }
  101. }
  102. }
  103. </script>
  104. <style scoped>
  105. /* ============================================================
  106. OnboardingGuide — 首次登录引导浮层
  107. 设计体系:统一使用 uni.scss design tokens
  108. ============================================================ */
  109. .onboarding-overlay {
  110. position: fixed;
  111. top: 0;
  112. left: 0;
  113. width: 100%;
  114. height: 100%;
  115. background: rgba(0, 0, 0, 0.5);
  116. display: flex;
  117. align-items: center;
  118. justify-content: center;
  119. z-index: 9998;
  120. animation: fadeIn 0.25s ease;
  121. }
  122. .onboarding-card {
  123. width: 640rpx;
  124. min-height: 680rpx;
  125. background: var(--surface, #FFFFFF);
  126. border-radius: var(--radius-xl, 32rpx);
  127. display: flex;
  128. flex-direction: column;
  129. align-items: center;
  130. overflow: hidden;
  131. box-shadow: var(--shadow-lg, 0 8rpx 32rpx rgba(91, 155, 213, 0.10));
  132. animation: scaleIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  133. }
  134. /* 顶部品牌装饰条 — 暖珊瑚色 */
  135. .onboarding-topbar {
  136. width: 100%;
  137. height: 12rpx;
  138. background: var(--color-primary, #F97316);
  139. flex-shrink: 0;
  140. }
  141. /* ============================================================
  142. 内容区 — flex 居中,带淡入动画
  143. ============================================================ */
  144. .onboarding-content {
  145. flex: 1;
  146. display: flex;
  147. flex-direction: column;
  148. align-items: center;
  149. justify-content: center;
  150. padding: 80rpx 56rpx 48rpx;
  151. animation: fadeIn 0.3s ease;
  152. }
  153. .onboarding-icon {
  154. font-size: 80rpx;
  155. margin-bottom: 32rpx;
  156. display: block;
  157. }
  158. .onboarding-title {
  159. font-size: 36rpx;
  160. font-weight: 700;
  161. color: var(--text, #1E293B);
  162. text-align: center;
  163. margin-bottom: 20rpx;
  164. display: block;
  165. line-height: 1.3;
  166. }
  167. .onboarding-desc {
  168. font-size: 28rpx;
  169. color: var(--text-secondary, #64748B);
  170. text-align: center;
  171. line-height: 1.6;
  172. display: block;
  173. padding: 0 16rpx;
  174. }
  175. /* ============================================================
  176. 步进器圆点
  177. ============================================================ */
  178. .onboarding-dots {
  179. display: flex;
  180. align-items: center;
  181. justify-content: center;
  182. gap: 16rpx;
  183. padding: 0 56rpx 40rpx;
  184. flex-shrink: 0;
  185. }
  186. .dot {
  187. width: 14rpx;
  188. height: 14rpx;
  189. border-radius: 50%;
  190. background: var(--border, #CBD5E1);
  191. transition: background 0.3s ease, transform 0.3s ease;
  192. }
  193. .dot.active {
  194. background: var(--color-primary, #F97316);
  195. transform: scale(1.3);
  196. }
  197. /* ============================================================
  198. 底部按钮
  199. ============================================================ */
  200. .onboarding-action {
  201. width: 100%;
  202. padding: 0 56rpx 48rpx;
  203. flex-shrink: 0;
  204. box-sizing: border-box;
  205. }
  206. .onboarding-btn {
  207. width: 100%;
  208. height: 88rpx;
  209. border-radius: 999rpx;
  210. background: var(--color-primary, #5B9BD5);
  211. color: #FFFFFF;
  212. font-size: 32rpx;
  213. font-weight: 700;
  214. display: flex;
  215. align-items: center;
  216. justify-content: center;
  217. transition: opacity 0.2s ease, transform 0.15s ease;
  218. box-shadow: 0 4rpx 16rpx rgba(91, 155, 213, 0.25);
  219. }
  220. .onboarding-btn:active {
  221. opacity: 0.85;
  222. transform: scale(0.97);
  223. }
  224. /* 最后一步:暖珊瑚色按钮 */
  225. .onboarding-btn--last {
  226. background: var(--color-primary, #F97316);
  227. box-shadow: 0 4rpx 16rpx rgba(249, 115, 22, 0.30);
  228. }
  229. </style>