Vue全栈开发旅游网项目(9)-用户登录/注册及主页页面开发

1.用户登录页面开发

1.查询vant组件 2.实现组件模板部分 3.模型层准备 4.数据上传

1.1 创建版权声明组件Copyright

新建文件:src\components\common\Copyright.vue

<template>
    <!-- 版权声明 -->
     <div class="copyright">
        copyright xxx旅游网&copy;2024
     </div>
</template>
<style lang="less">
.copyright{
    position: fixed;
    bottom: 0;
    padding: 10px;
    color:#999;
    width: 100%;
    text-align: center;
    font-size: 12px;
}
</style>

1.2 登录页面Login

新建文件:src\views\accounts\Login.vue

1.2.1 脚本script:

<script setup>
import Copyright from '@/components/common/Copyright.vue';
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import TripFooter from '@/components/common/Footer.vue';

const route = useRoute() //获得属性
const router = useRouter()  //获取地址

const username = ref('')
const password = ref('')

//用户名的验证规则
const rulename = ref([{
    required: true,//用户名组件中通过该属性开启必填验证
    message: '请填写用户名'
}, {
    pattern: /1\d{10}/,//用户名组件中,通过该属性开启正则表达式验证
    message: '请填写正确的手机号'
}])

const goBack = () => {
    router.go(-1)
}
</script>

1.2.2 模板template 

<template>
    <div class="page-account-login">
        <!-- 导航条 -->
        <van-nav-bar title="用户登录" left-text="返回" @click-left="goBack"></van-nav-bar>
        <!-- 表单输入 -->
        <van-form>
            <!-- 文本框 -->
            <van-field v-model="username" label="用户名" placeholder="用户名" maxlength="11" :rules="rulename" clearable />
            <!-- 密码框 -->
            <van-field v-model="password" type="password" label="密码" placeholder="密码" :rules="[{ required: true }]" autocomplete="off"/>
            <div>
                <van-button square type="primary" native-type="submit" color="green">提交</van-button>
            </div>
        </van-form>
        <!-- 文字提示 -->
        <div>
            登录表示同意<a href="#">用户使用协议</a>及<a href="#">隐私条款</a>
        </div>
        <div>
            没有账户?<RouterLink :to="{name:'AccountRegister'}">点击注册</RouterLink>
        </div>
        <!-- 版权信息 -->
        <Copyright />
        <TripFooter/>
    </div>
</template>

1.2.3 配置路由:

文件地址:src\router\index.js

import AccountLogin from '@/views/accounts/Login.vue'
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path:'/account/login',
      name:'AccountLogin',
      component:AccountLogin
    }
  ]
})

2.用户注册界面开发

2.1 封装短信验证组件SendSmscode

新建文件:src\components\common\SendSmsCode.vue

2.1.1 脚本script

<script setup>
//defineProps用于父子组件通信
import { ref, onMounted, computed, defineProps } from 'vue'
import { useRoute, useRouter } from 'vue-router'//用于控制页面跳转工具,传值工具
import { ajax } from '@/utils/ajax';
import { SightApis } from '@/utils/apis';
import { showToast } from 'vant';

const router = useRouter()
const route = useRoute()

const goBack = () => {
    router.go(-1)//跳转至上一页(1:跳转至下一页)
}
const props = defineProps({
    phoneNum: String
})
//存放验证信息(响应式数据)
const isSmsSend = ref(false)
const sendBtnText = ref('点击发送验证码')
const timer = ref(null)
const counter = ref(60)

//清空验证码计时
const reset = () => {
    isSmsSend.value = false
    sendBtnText.value = '点击发送验证码'
    if (timer.value) {
        clearInterval(timer.value)//停止回调函数
        counter.value = 60
        timer.value = null
    }
}
//倒计时
const countDown = () => {
    //回调函数,重复调用
    timer.value = setInterval(() => {
        sendBtnText.value = `(${counter.value}秒)后重新发送`
        counter.value--
        if (counter.value < 0) {
            reset()
        }
    }, 1000)
}
//发送验证码
const sendSmsCode = () => {
    //判断手机号是否输入
    if (!props.phoneNum) {
        showToast('请输入手机号码')
        return false
    }
    isSmsSend.value = true    //调用接口,发送短息
    countDown()    //开始倒计时
}
defineExpose({//向父级暴露函数
    reset
})
</script>

2.1.2 模板template:

<template>
    <!-- 短信验证码发送相关逻辑 -->
    <van-button size="small" type="primary" @click.prevent="sendSmsCode()" :disabled="isSmsSend">
        {{ sendBtnText }}
    </van-button>
</template>

2.2 注册页面Register

新建文件:src\views\accounts\Register.vue

2.2.1 脚本script:

<script setup>
import Copyright from '@/components/common/Copyright.vue'
import SendSmsCode from '@/components/common/SendSmsCode.vue'
import { ref, toRef } from 'vue';
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter();
// 用户名的验证规则
const ruleName = ref([{
    required: true,
    message: '请填写用户名'
}, {
    pattern: /1\d{10}/,
    message: '请填写正确的手机号'
}])
// 重复密码验证
const rulePassword = ref([
    {
        required: true,
        message: '请重复一次密码'
    }, {
        validator: () => form.value.password === form.value.passwordRepeat,
        message: '两次密码输入不一致'
    }])
const form = ref({
    username: '',
    nickname: '',
    sms_code: '',
    password: '',
    passwordRepeat: ''
})
//手机号变化时,重置验证码组件状态
const refSms = ref({})
const onPhoneChange = () => {
    //调用验证码组件中reset函数,重置验证码
    refSms.value.reset()
}
const onSubmit = () => {
    // 提交表单
}
const goBack = () => {
    router.go(-1)
}
</script>

2.2.2 模板template


<template>
    <!-- 用户注册 -->
    <div class="page-account-register">
        <!-- 导航条 -->
        <van-nav-bar title="用户注册" left-text="返回" left-arrow @click-left="goBack" />
        <!-- 表单输入 -->
        <van-form @submit="onSubmit">
            <van-field v-model="form.username" label="手机号码" placeholder="手机号码" type="tel" maxlength="11" clearable
                :rules="ruleName" @input="onPhoneChange" />
            <van-field v-model="form.sms_code" center clearable label="短信验证码" placeholder="短信验证码"
                :rules="[{ required: true, message: '请输入短信验证码' }]">
                <template #button>
                    <SendSmsCode ref="refSms" :phoneNum="form.username" />
                </template>
            </van-field>
            <van-field v-model="form.nickname" label="用户昵称" placeholder="用户昵称" maxlength="32" clearable
                :rules="[{ required: true, message: '请输入用户昵称' }]" />
            <van-field v-model="form.password" type="password" label="密码" placeholder="密码"
                :rules="[{ required: true, message: '请填写密码' }]" autocomplete="off"/>
            <van-field v-model="form.passwordRepeat" type="password" label="确认密码" placeholder="确认密码"
                :rules="rulePassword" autocomplete="off" />
            <div style="margin: 16px;">
                <van-button round block type="info" native-type="submit">
                    提交
                </van-button>
            </div>
        </van-form>
        <!-- //表单输入 -->
        <!-- 文字提示 -->
        <div class="tips">
            注册表示同意 <a href="#">用户使用协议</a>及<a href="#">隐私条款</a>
        </div>
        <div class="tips">
            已有账号? <router-link :to="{ name: 'AccountLogin' }">点击登录>></router-link>
        </div>
        <!-- 版权信息 -->
        <Copyright />
    </div>
</template>

2.2.3 配置路由:

文件地址:src\router\index.js

import AccountRegister from '@/views/accounts/Register.vue'
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {//用户注册
      path: '/account/register',
      name: 'AccountRegister',
      component: AccountRegister
    }
  ]
})

3.个人主页界面开发Mine

新建文件:src\views\Mine.vue

3.1 脚本script

import TripFooter from '@/components/common/Footer.vue'

3.2 模板template


<template>
    <div class="page-mine">
        <!-- 标题栏 -->
        <van-nav-bar title="个人中心" />
        <!-- 用户基本信息(头像/昵称) -->
        <div class="user-header">
            <div class="avatar">
                <img src="/static/mine/avatar.png">
            </div>
            <div>
                <p>Welcome,Adela</p>
                <a class="btn-link" href="#">退出登录</a>
            </div>
        </div>
        <!-- 订单菜单列表 -->
        <van-row>
            <van-col span="6">
                <RouterLink to="/">
                    <van-icon name="records" />
                    <span>全部订单</span>
                </RouterLink>
            </van-col>
            <van-col span="6">
                <RouterLink to="/">
                    <van-icon name="pending-payment" />
                    <span>待支付</span>
                </RouterLink>
            </van-col>
            <van-col span="6">
                <RouterLink to="/">
                    <van-icon name="tosend" />
                    <span>已完成</span>
                </RouterLink>
            </van-col>
            <van-col span="6">
                <RouterLink to="/">
                    <van-icon name="logistics" />
                    <span>已取消</span>
                </RouterLink>
            </van-col>
        </van-row>
        <!-- 底部导航 -->
        <TripFooter />
    </div>
</template>

3.3 样式style(范例)

<style lang="less">
.page-mine {
  font-family: 'Arial', sans-serif;
  color: #333;
  background-color: #f7f7f7;

  .van-nav-bar {
    background-color: #07c; //
    color: #fff;

    .van-nav-bar__title {
      color: #fff;
      text-align: center;
    }
  }

  // 用户头部区域样式
  .user-header {
    background: url(/static/mine/bg.jpg) no-repeat center;
    background-size: cover;
    color: #fff;
    height: 200px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 200px; // 确保有足够的高度
    .avatar {
      margin-bottom: 20px;
      img {
        width: 60px;
        height: 60px;
        border-radius: 50%;
      }
    }
    p {
      font-size: 18px;
    }
    .btn-link {
      margin-top: 10px; // 添加顶部外边距以在垂直方向上居中
      margin-left: 25px; 
    }
  }

  // 订单菜单列表样式
  .van-row {
    .van-col {
      a {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-decoration: none;
        color: #333;
        padding: 10px;

        .van-icon {
          font-size: 24px;
          margin-bottom: 5px;
        }

        span {
          font-size: 14px;
        }
      }

      &:not(:last-child) {
        border-right: 1px solid #eee;
      }
    }
  }

  // 底部导航样式
  .trip-footer {
    background-color: #fff;
    box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
    position: fixed;
    bottom: 0;
    width: 100%;
  }
}
</style>

3.4 配置路由

文件地址:src\router\index.js

import Mine from '@/views/Mine.vue'
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {//个人中心
      path: '/mine',
      name: 'Mine',
      component: Mine
    }
  ]
})

3.5 图示效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/913216.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

后台管理系统窗体程序:文章管理 > 文章列表

目录 文章列表的的功能介绍&#xff1a; 1、进入页面 2、页面内的各种功能设计 &#xff08;1&#xff09;文章表格 &#xff08;2&#xff09;删除按钮 &#xff08;3&#xff09;编辑按钮 &#xff08;4&#xff09;发表文章按钮 &#xff08;5&#xff09;所有分类下拉框 &a…

【万字详解】如何在微信小程序的 Taro 框架中设置静态图片 assets/image 的 Base64 转换上限值

设置方法 mini 中提供了 imageUrlLoaderOption 和 postcss.url 。 其中&#xff1a; config.limit 和 imageUrlLoaderOption.limit 服务于 Taro 的 MiniWebpackModule.js &#xff0c; 值的写法要 &#xff08;&#xff09;KB * 1024。 config.maxSize 服务于 postcss-url 的…

基于STM32通过TM1637驱动4位数码管详细解析(可直接移植使用)

目录 1. 单位数码管概述 2. 对应编码 2.1 共阳数码管 2.2 共阴数码管 3. TM1637驱动数码管 3.1 工作原理 3.1.1 读键扫数据 3.1.2 显示器寄存器地址和显示模式 3.2 时序 3.2.1 指令数据传输过程&#xff08;读案件数据时序&#xff09; 3.2.2 写SRAM数据…

数字信号处理Python示例(11)生成非平稳正弦信号

文章目录 前言一、生成非平稳正弦信号的实验设计二、生成非平稳正弦信号的Python代码三、仿真结果及分析写在后面的话 前言 本文继续给出非平稳信号的Python示例&#xff0c;所给出的示例是非平稳正弦信号&#xff0c;在介绍了实验设计之后给出Python代码&#xff0c;最后给出…

Linux 系统结构

Linux系统一般有4个主要部分&#xff1a;内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构&#xff0c;它们使得用户可以运行程序、管理文件并使用系统。 1. linux内核 内核是操作系统的核心&#xff0c;具有很多最基本功能&#xff0c;它…

网络安全之SQL初步注入

一.字符型 平台使用pikachu $name$_GET[name]; ​ $query"select id,email from member where username$name"; 用户输入的数据会被替换到SQL语句中的$name位置 查询1的时候&#xff0c;会展示username1的用户数据&#xff0c;可以测试是否有注入点&#xff08;闭…

【IEEE/EI会议】第八届先进电子材料、计算机与软件工程国际学术会议(AEMCSE 2025)

会议通知 会议时间&#xff1a;2025年4月25-27日 会议地点&#xff1a;中国南京 会议官网&#xff1a;www.aemcse.org 会议简介 第八届先进电子材料、计算机与软件工程国际学术会议&#xff08;AEMCSE 2025&#xff09;由南京信息工程大学主办&#xff0c;将于2025年4月25日…

华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)

华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目分享——共九套&#xff08;每套四十题&#xff09; 岗位——芯片与器件设计工程师 岗位意向——模拟芯片 真题题目分享&#xff0c;完整题目&#xff0c;无答案&#xff08;共8套&#xff09; 实习岗位…

Python——数列1/2,2/3,3/4,···,n/(n+1)···的一般项为Xn=n/(n+1),当n—>∞时,判断数列{Xn}是否收敛

没注释的源代码 from sympy import * n symbols(n) s n/(n1) print(数列的极限为&#xff1a;,limit(s,n,oo))

104、Python并发编程:基于事件Event实现多线程间的同步

引言 继续介绍关于多线程同步的实现方式&#xff0c;本文将介绍基于Event的线程同步方式。 本文的主要内容有&#xff1a; 1、什么是Event 2、Event的使用场景 3、Event的代码实例 4、Event与Condition的比较 什么是Event 在Python的多线程编程中&#xff0c;Event是一个…

首次超越扩散模型和非自回归Transformer模型!字节开源RAR:自回归生成最新SOTA!

文章链接&#xff1a;https://arxiv.org/pdf/2411.00776 项目链接&#xff1a;https://yucornetto.github.io/projects/rar.html 代码&模型链接&#xff1a;https://github.com/bytedance/1d-tokenizer 亮点直击 RAR&#xff08;随机排列自回归训练策略&#xff09;&#x…

IDEA在编译时: java: 找不到符号符号: 变量 log

一、问题 IDEA在编译的时候报Error:(30, 17) java: 找不到符号符号: 变量 log Error:(30, 17) java: 找不到符号 符号: 变量 log 位置: 类 com.mokerson.rabbitmq.config.RabbitMqConfig 二、解决方案 背景&#xff1a;下载其他同事代码时&#xff0c;第一次运行&#xff0c…

【Hadoop实训】Hive 数据操作②

延续上一篇文章&#xff0c;不懂的宝子们请看以下链接&#xff1a; 【Hadoop实训】Hive 数据操作①-CSDN博客 目录 一、Group by 语句 (1)、计算emp表每个部门的平均工资 (2)、计算emp表每个部门中每个岗位的最高工资 二、Having 语句 (1)、求每个部门的平均工资 (2)、求每个…

nginx的相关命令

nginx的启用和停止有多种方式1、nginx服务的信号控制&#xff1b;2、nginx的命令行控制。 1、信号控制 ps -ef | grep nginx 可以查询跟nginx有关的所有线程。 有一个master进程和worker进程 我们作为管理员&#xff0c;只需要通过master进程发送信号来控制nginx&#xff0c…

【SpringMVC】——Cookie和Session机制

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;实践 1&#xff1a;获取URL中的参数 &#xff08;1&#xff09;PathVariable 2&…

31.校园志愿者管理系统(基于springboot和vue的Java项目)

目录 1.系统的受众说明 2.开发技术与环境配置 2.1 SpringBoot框架 2.2Java语言简介 2.3 MySQL环境配置 2.4 MyEclipse环境配置 2.5 mysql数据库介绍 2.6 B/S架构 3.系统分析与设计 3.1 可行性分析 3.1.1 技术可行性 3.1.2 操作可行性 3.1.3经济可行性 3.4.1 …

Android下的系统调用 (syscall),内联汇编syscall

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 什么是系统调用 (syscall) 系统调用是操作系统提供给应用程序的一组接口&#xff0c;允许用户空间程序与内核进行交互。 在 Android&#xff08;基于 Linux …

linux-vlan

# VLAN # 1.topo # 2.创建命名空间 ip netns add ns1 ip netns add ns2 ip netns add ns3 # 3.创建veth设备 ip link add ns1-veth0 type veth peer name ns21-veth0 ip link add ns3-veth0 type veth peer name ns23-veth0 # 4.veth设备放入命名空间,启动接口 ip link set n…

浙江大学高等数学研究所已变样

跟我199X年春季到访相比&#xff0c;现改名为“研究院”&#xff0c;说是2017年建立的&#xff0c;刘克峰&#xff08;1965-&#xff0c;研究黎曼几何&#xff0c;加州洛杉矶大学教授&#xff09;已退位&#xff0c;励建书&#xff08;1959-&#xff0c;香港科技大学教授&#…

使用 AMD GPU 上的 Whisper 进行语音转文字

Speech-to-Text on an AMD GPU with Whisper — ROCm Blogs 2024年4月16日&#xff0c;作者&#xff1a;Clint Greene. 介绍 Whisper是由 OpenAI 开发的高级自动语音识别&#xff08;ASR&#xff09;系统。它采用了一个简单的编码器-解码器 Transformer 架构&#xff0c;其中…