Pārlūkot izejas kodu

feat(邀请用户活动注册页): upd

曾志翔 3 gadi atpakaļ
vecāks
revīzija
d41584af4d

+ 30 - 0
modules/vee-validate/index.js

@@ -0,0 +1,30 @@
+import path from 'path';
+import unpluginVueComponents from 'unplugin-vue-components/webpack';
+export default function (c, i) {
+  this.nuxt.hook('build:before', (nuxt, buildOptions) => {
+    buildOptions.plugins.push(
+      unpluginVueComponents({
+        resolvers: [
+          {
+            type: 'component',
+            resolve(componentName) {
+              if (componentName.startsWith('Validation')) {
+                // console.log(
+                //   '🚀 ~ file: nuxt.config.js ~ line 230 ~ resolve ~ componentName',
+                //   componentName,
+                // );
+                return {
+                  name: componentName,
+                  from: 'vee-validate',
+                  // sideEffects: getSideEffects(importName, options),
+                };
+              }
+            },
+          },
+        ],
+      }),
+    );
+  });
+
+  this.addPlugin(path.resolve(__dirname, 'plugin.js'));
+}

+ 9 - 0
modules/vee-validate/plugin.js

@@ -0,0 +1,9 @@
+import { extend, localize } from 'vee-validate';
+import * as rules from 'vee-validate/dist/rules';
+import zhCN from 'vee-validate/dist/locale/zh_CN';
+
+// localize({ zhCN });
+localize('zhCN', zhCN);
+Object.entries(rules).forEach(([name, value]) => {
+  extend(name, value);
+});

+ 27 - 2
nuxt.config.js

@@ -1,3 +1,4 @@
+import unpluginVueComponents from 'unplugin-vue-components/webpack';
 // import colors from 'vuetify/es5/util/colors'
 import zhHans from 'vuetify/lib/locale/zh-Hans';
 import dotenv from 'dotenv';
@@ -86,6 +87,7 @@ export default {
   // Auto import components: https://go.nuxtjs.dev/config-components
   components: [
     '~/components',
+
     // {
     //   path: 'vant/es',
     //   level: 1,
@@ -110,6 +112,7 @@ export default {
     // https://go.nuxtjs.dev/vuetify
     '@nuxtjs/vuetify',
     '@unocss/nuxt',
+    '~/modules/vee-validate',
     // '@nuxtjs/composition-api/module',
   ],
 
@@ -141,7 +144,7 @@ export default {
         process.env.API_HOST
       }:${process.env.API_PORT}`,
       pathRewrite: {
-        // '^/api/': ''
+        // '^/api': ''
       },
     },
     '/file': {
@@ -149,7 +152,7 @@ export default {
         process.env.FILE_HOST
       }:${process.env.FILE_PORT}`,
       pathRewrite: {
-        '^/file/': '',
+        '^/file': '',
       },
     },
   },
@@ -219,6 +222,28 @@ export default {
     //     },
     //   };
     // },
+    plugins: [
+      // unpluginVueComponents({
+      //   resolvers: [
+      //     {
+      //       type: 'component',
+      //       resolve(componentName) {
+      //         if (componentName.startsWith('Validation')) {
+      //           console.log(
+      //             '🚀 ~ file: nuxt.config.js ~ line 230 ~ resolve ~ componentName',
+      //             componentName,
+      //           );
+      //           return {
+      //             name: componentName,
+      //             from: 'vee-validate',
+      //             // sideEffects: getSideEffects(importName, options),
+      //           };
+      //         }
+      //       },
+      //     },
+      //   ],
+      // }),
+    ],
     babel: {
       plugins: [],
     },

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 15 - 5227
package-lock.json


+ 1 - 0
package.json

@@ -35,6 +35,7 @@
     "numeral": "^2.0.6",
     "nuxt": "^2.15.8",
     "vant": "^2.12.47",
+    "vee-validate": "^3.4.14",
     "vue": "^2.6.14",
     "vue-data-dict": "^1.0.6",
     "vue-server-renderer": "^2.6.14",

+ 7 - 7
pages/activity/invite-user.vue

@@ -136,7 +136,7 @@ export default {
   mounted() {},
   methods: {
     async share() {
-      console.log(this);
+      // console.log(this);
       this.$tongji.trackEvent('活动', '分享', '', 0);
 
       const url =
@@ -166,9 +166,9 @@ export default {
         });
       } else {
         // 浏览器环境
-        // await clipboard.write(url);
-        throw new Error('1231');
-        // this.$toast.success('链接复制成功');
+        await clipboard.write(url);
+        // throw new Error('1231');
+        this.$toast.success('链接复制成功');
       }
     },
     share2() {
@@ -251,8 +251,8 @@ export default {
   .share-button {
     display: block;
     margin: auto;
-    width: 302px;
-    height: 62px;
+    width: 302px !important;
+    height: 62px !important;
     background-image: url('~/assets/image/activity/invite-user/share-button@2x.png');
     background-size: 100% 100%;
     margin-top: 24px;
@@ -275,7 +275,7 @@ export default {
 .box4 {
   .box-main {
     // padding-left: 20px;
-    padding-top: 0;
+    // padding-top: 0;
   }
 }
 </style>

+ 88 - 20
pages/register-for-invite.vue

@@ -1,15 +1,60 @@
 <template>
-  <div class="register-for-invite">
+  <v-container class="register-for-invite" fluid>
     <div class="">注册</div>
-    <form @submit.prevent>
-      <input v-model="form.phone" label="phone" name="phone" />
-      <input v-model="form.code" label="code" name="code" maxlength="6" />
-      <div class="">
-        <button @click="register()">注册</button>
-        <button @click="sendSmsCode()">发送验证码</button>
-      </div>
-    </form>
-  </div>
+    <validation-observer ref="observer" v-slot="{ invalid }" slim>
+      <v-form @submit.prevent="submit()">
+        <validation-provider
+          v-slot="{ errors }"
+          name="手机号码"
+          rules="required|min:11|max:11"
+          slim
+        >
+          <v-text-field
+            v-model="form.phone"
+            label="手机号码"
+            name="phone"
+            required
+            :error-messages="errors"
+            maxlength="11"
+            type="tel"
+          />
+        </validation-provider>
+        <validation-provider
+          v-slot="{ errors }"
+          name="验证码"
+          rules="required|min:6|max:6"
+          slim
+        >
+          <v-text-field
+            v-model="form.code"
+            label="验证码"
+            :error-messages="errors"
+            name="code"
+            maxlength="6"
+            required
+          >
+            <template #append-outer>
+              <v-btn
+                :loading="codeSending"
+                :disabled="codeTime > 0"
+                small
+                @click="sendSmsCode()"
+              >
+                <template v-if="codeTime > 0">{{ codeTime }}s</template>
+                <template v-else>发送验证码</template>
+              </v-btn>
+            </template>
+          </v-text-field>
+        </validation-provider>
+
+        <div class="">
+          <v-btn type="submit" :disabled="invalid" :loading="submitting"
+            >注册并下载app</v-btn
+          >
+        </div>
+      </v-form>
+    </validation-observer>
+  </v-container>
 </template>
 
 <script>
@@ -26,6 +71,9 @@ export default {
         invitationUserName: null,
         activityId: null,
       },
+      codeSending: false,
+      codeTime: 0,
+      submitting: false,
     };
   },
   fetch() {
@@ -35,19 +83,39 @@ export default {
   head: {
     title: '注册',
   },
+  watch: {},
   methods: {
-    async register() {
-      this.$tongji.trackEvent('活动', '注册', '', 0);
-      await registerForInvite(this, this.form);
+    async submit() {
+      try {
+        this.submitting = true;
+        this.$tongji.trackEvent('活动', '注册', '', 0);
+        const validationResult = await this.$refs.observer.validate();
+        if (validationResult) {
+          await registerForInvite(this, this.form);
+        }
+      } finally {
+        this.submitting = false;
+      }
     },
     async sendSmsCode() {
-      this.$tongji.trackEvent('活动', '发送短信', '', 0);
-      const res = await sendSmsCode(this, {
-        type: 'common',
-        authorizationType: 4,
-        phone: this.form.phone,
-      });
-      this.$message({ content: res.msg });
+      try {
+        this.codeSending = true;
+        this.$tongji.trackEvent('活动', '发送短信', '', 0);
+        const res = await sendSmsCode(this, {
+          type: 'common',
+          authorizationType: 4,
+          phone: this.form.phone,
+        });
+        this.codeTime = 60;
+        this.codeInterval = setInterval(() => {
+          if (--this.codeTime <= 0) {
+            clearInterval(this.codeInterval);
+          }
+        }, 1000);
+        this.$toast.success(res.msg);
+      } finally {
+        this.codeSending = false;
+      }
     },
   },
 };