当前位置: 首页 > news >正文

网站二维码可以做长按识别吗网站搭建公司

网站二维码可以做长按识别吗,网站搭建公司,wordpress页面构建,新疆乌鲁木齐网架公司🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…

🙈作者简介:练习时长两年半的Java up主
🙉个人主页:程序员老茶
🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎
📚系列专栏:Java全栈,计算机系列(火速更新中)
💭 格言:种一棵树最好的时间是十年前,其次是现在
🏡动动小手,点个关注不迷路,感谢宝子们一键三连

目录

  • 课程名:Vue 3
    • 内容/作用:知识点/设计/实验/作业/练习
    • 学习:Vue3+Vant开发:登录功能
    • 1、创建登录路由
    • 2、实现登录布局结构
    • 3、登录布局实现
    • 4、实现基本登录功能
    • 5、登录状态提示
    • 6、表单验证功能
    • 7、处理用户Token
    • 8、封装本地存储操作
    • 总结

课程名:Vue 3

内容/作用:知识点/设计/实验/作业/练习

学习:Vue3+Vant开发:登录功能

1、创建登录路由

npm install vue-router@4

以上安装了最新版本的vue-router.

下面在src目录下面创建router目录,在该目录下面创建index.js文件,在该文件中完成路由的配置

index.js文件中代码如下所示:()

在下面的代码中,首先从vue-router中导入createRouter以及createWebHashHistory.

createRouter用来创建路由实例

createWebHashHistory创建hash路由

Layout组件用来完成整个后台管理页面的布局。

routes数组中,定义了相应的路由规则

import { createRouter, createWebHashHistory } from "vue-router";
const routes = [{path: "/login",name: "login",component: () => import("../views/login/index.vue"),},
];
//创建路由实例
const router = createRouter({//history模式:createWebHistoryhistory: createWebHashHistory(), //使用hash模式routes,
});
export default router;

下面在src目录下面创建views目录,在该目录下面创建login目录,然后在创建index.vue.

该组件中的内容如下所示:

<template><div>登录</div>
</template><script>
export default {};
</script><style></style>

下面,返回到main.js文件中使用创建好的路由对象

import { createApp } from "vue";
import App from "./App.vue";
import Vant from "vant";
import "vant/lib/index.css";
import "amfe-flexible";
import router from "./router"; //导入路由对象
createApp(App).use(Vant).use(router).mount("#app"); //使用路由

同时在App.vue文件中,添加router-view,指定路由的出口。

<template><router-view></router-view>
</template><script setup></script><style></style>

在浏览器中输入http://localhost:3000/#/login查看效果。

2、实现登录布局结构

<template><div class="login-container"><!-- 导航栏 --><van-nav-bar title="登录" /><!-- 导航栏结束 --><!-- 登录表单 --><van-form><van-field name="userName" placeholder="请输入用户名" /><van-field name="userPwd" placeholder="请输入密码" /><div style="margin: 16px"><van-button block type="primary" native-type="submit">提交</van-button></div></van-form><!-- 登录表单结束 --></div>
</template><script>
export default {};
</script><style></style>

3、登录布局实现

这里我们首先设置一下,导航栏的样式。由于很多页面都会用到导航栏,所以可以将样式定义在全局的文件中,而不是单独的定义在登录组件中。

src目录下面创建styles目录,在该目录下面创建index.css文件,该文件中的代码如下所示:

.page-nav-bar {background-color: #3296fa;
}
.page-nav-bar .van-nav-bar__title {/* 这里的van-nav-bar__title,可以查看原有的导航栏的样式*/color: #fff;
}

在登录组件的导航栏中使用该样式。(在main.js文件中导入import "./styles/index.css";

  <van-nav-bar title="登录" class="page-nav-bar" />

下面给登录表单的文本框与密码框添加对应的图标。

对应的官网:

https://vant-contrib.gitee.io/vant/v3/#/zh-CN/field
 <van-form><van-field name="userName" placeholder="请输入用户名" left-icon="manager" /><van-field name="userPwd" placeholder="请输入密码"   left-icon="lock"/></van-field><div style="margin: 16px"><van-button block type="primary" native-type="submit"> 提交</van-button></div></van-form>

这里给手机号与验证码添加了left-icon设置了图标。同时设置了“发送验证码”的按钮

4、实现基本登录功能

注意:这里只是实现基本登录效果,把服务端返回的内容打印出来,不涉及到登录状态的提示与登录状态的存储操作。

首先在src目录下面创建api目录,在该目录下面创建user.js文件,该文件中封装了用户请求的相关处理模块。

// 封装用户相关的请求模块
import request from "../utils/request";
export const login = (data) => {return request({method: "POST",url: "/user/login",data,});
};

下面修改login.vue组件中的内容

  <div class="login-container"><!-- 导航栏 --><van-nav-bar title="登录" class="page-nav-bar" /><!-- 导航栏结束 --><!-- 登录表单 --><van-form @submit="onSubmit"><van-fieldname="userName"placeholder="请输入用户名"v-model="userName"left-icon="manager":rules="userFormRules.userName"/><van-fieldname="userPwd"placeholder="请输入密码"v-model="userPwd"left-icon="lock":rules="userFormRules.userPwd"></van-field><div style="margin: 16px"><van-button block type="primary" native-type="submit">登录</van-button></div></van-form><!-- 登录表单结束 --></div>

给每个van-field绑定了v-model,同时给van-form添加了@submit事件。

<script>
import { reactive, toRefs } from "vue";
import { login } from "../../api/user"; //导入login方法,进行请求的发送function useSubmit(user) {
const onSubmit = async () => {//1、获取表单数据//2、表单验证//3、提交表单请求Toast.loading({message: "登录中...",forbidClick: true, //禁用背景点击duration: 0, //持续时间,默认是2000毫秒,如果为0则持续展示});const res = await login(user);if (res.data.code === 0) {store.commit("setUser", res.data);Toast.success("用户登录成功");} else {Toast.fail("用户名或密码错误");}//4、根据请求响应结果处理后续操作。};return {onSubmit,};
}
export default {setup() {const user = reactive({userName: "", //用户名userPwd: "", //用户密码});return {...toRefs(user),...useSubmit(user),};},
};
</script>

setup方法中,定义user响应式对象,最后返回。同时将外部定义的useSubmit方法进行调用。

5、登录状态提示

const onSubmit = async () => {//1、获取表单数据//2、表单验证//3、提交表单请求Toast.loading({message: "登录中...",forbidClick: true, //禁用背景点击duration: 0, //持续时间,默认是2000毫秒,如果为0则持续展示});const res = await login(user);if (res.data.code === 0) {store.commit("setUser", res.data);Toast.success("用户登录成功");} else {Toast.fail("用户名或密码错误");}//4、根据请求响应结果处理后续操作。};return {onSubmit,};
}

这里使用了Toast组件,同时需要进行导入:

import { Toast } from "vant";

由于网络比较快,可能看不到登录中...这个提示,所以可以把网络设置慢一些。

可以修改NetWork中的No throttling中的Slow 3G

6、表单验证功能

setup函数中定义校验规则,并且将其返回。

setup() {const user = reactive({userName: "", //用户名userPwd: "", //用户密码});//定义校验规则const userFormRules = {userName: [{ required: true, message: "请填写用户名" }],userPwd: [{required: true,message: "请填写密码",},{pattern: /^\d{6}$/,message: "密码格式错误",},],};return {...toRefs(user),...useSubmit(user),userFormRules, //返回校验规则};},

在表单中使用校验规则:

     <van-fieldname="userName"placeholder="请输入用户名"v-model="userName"left-icon="manager":rules="userFormRules.userName"/><van-fieldname="userPwd"placeholder="请输入密码"v-model="userPwd"left-icon="lock":rules="userFormRules.userPwd"></van-field>

7、处理用户Token

用户登录成功以后,会返回token数据。

Token是用户登录成功之后服务端返回的一个身份令牌,在项目中经常要使用。

例如:访问需要授权的API接口。

校验页面的访问权限等。

同时,这里我们还需要将token数据进行存储,这样在访问其它的页面组件的时候,就可以获取token数据来进行校验。

关于token数据存储在哪儿呢?

可以存储到本地:

存储到本地的问题是,数据不是响应式的。

存储到Vuex中,获取方便,并且是响应式的。但是存储到Vuex中也是有一定的问题的,就是当我们刷新浏览器的时候,数据就会丢失,所以还是需要把token数据存放到本地,存储到本地的目的就是为了进行持久化。

所以这里我们需要在登录成功以后,把token数据存储到vuex中,这样可以实现响应式,在本地存储就是为了解决持久化的问题。

安装最新版本的Vuex

npm install vuex@next --save

下面在src目录下面创建store目录,在store目录中index.js文件,该文件中的代码如下所示:

import { createStore } from "vuex";
const store = createStore({state: {//存储当前登录用户信息,包含token等数据user: null,},mutations: {setUser(state, data) {state.user = data;},},
});
export default store;

在上面的代码中,创建了store容器,同时指定了state对象,在该对象中定义user属性存储登录用户信息。

mutations中定义setUser方法,完成用户信息的更新。

下面,要实现的就是,当登录成功以后,更新user这个状态属性。

当然,这里首先要做的就是把store注入到Vue的实例中。

import { createApp } from "vue";
import App from "./App.vue";
import Vant from "vant";
import "vant/lib/index.css";
import "amfe-flexible";
import "./styles/index.css";
import router from "./router";
import store from "./store"; //导入store
createApp(App).use(Vant).use(router).use(store).mount("#app"); //完成store的注册操作

main.js文件中,我们导入了store,并且注册到了Vue实例中。

下面返回到views/login/index.vue页面中,把登录的信息存储到store容器中。

import { reactive, toRefs, ref } from "vue";
import { login, sendSms } from "../../api/user";
import { Toast } from "vant";
import { useStore } from "vuex"; //导入useStore

在上面的代码中导入useStore.

export default {setup() {const loginForm = ref();//获取storeconst store = useStore();

setup函数中,调用useStore方法,获取store容器。

 return {...toRefs(user),...useSubmit(user, store),//在调用useSubmit方法的时候传递store容器userFormRules,loginForm,};
//用户登录
function useSubmit(user, store) {const onSubmit = async () => {//1、获取表单数据//2、表单验证//3、提交表单请求Toast.loading({message: "登录中...",forbidClick: true, //禁用背景点击duration: 0, //持续时间,默认是2000毫秒,如果为0则持续展示});const res = await login(user);if (res.data.code === 0) {store.commit("setUser", res.data);Toast.success("用户登录成功");} else {Toast.fail("用户名或密码错误");}//4、根据请求响应结果处理后续操作。};return {onSubmit,};
}

登录成功以后,获取到返回的数据,同时调用store中的commit方法完成数据的保存

现在,我们虽然把登录成功的数据,存储到Vuex中,但是当我们刷新浏览器的时候,Vuex中的数据还是会丢失的。所以这里,我们还需要将其存储到本地中。

下面修改一下store/index.js文件中的代码:

import { createStore } from "vuex";
const TOKEN_KEY = "TOUTIAO_USER";
const store = createStore({state: {//存储当前登录用户信息,包含token等数据// user: null,user: JSON.parse(window.localStorage.getItem(TOKEN_KEY)),},mutations: {setUser(state, data) {state.user = data;window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user));},},
});
export default store;

mutations中的setUser方法中,将登录成功的用户数据存储到了localStorage中,在存储的时候,将数据转成了字符串。

同时在state中获取数据的时候,就从localStorage中获取,当然获取的时候,再将其转换成对象的形式。

下面,我们可以在App.vue中做一下测试:

<template><div><router-view></router-view></div>
</template><script>
import { useStore } from "vuex";
export default {setup() {const store = useStore();console.log(store.state.user);},
};
</script><style></style>

通过查看浏览器的控制台,可以查看到对应的登录用户的token数据

8、封装本地存储操作

在我们的项目中,有很多的地方都需要获取本地存储的数据,如果每次都写:

JSON.parse(window.localStorage.getItem(TOKEN_KEY)),
window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user));

就比较麻烦了。所以这里我们建议把操作本地数据单独的封装到一个模块中。

utils目录下面创建storage.js文件,该文件中的代码如下所示:

// 存储数据
export const setItem = (key, value) => {//将数组,对象类型的数据转换为JSON格式的字符串进行存储if (typeof value === "object") {value = JSON.stringify(value);}window.localStorage.setItem(key, value);
};
//获取数据
export const getItem = (key) => {const data = window.localStorage.getItem(key);//这里使用try..catch的,而不是通过if判断一下是否为json格式的字符串,然后在通过parse进行转换呢,目的就是是为了方便处理,因为对字符串进行判断看一下是否为json格式的字符串,比较麻烦一些。还需要通过正则表达式来完成。而通过try..catch比较方便// 如果data不是一个有效的json格式字符串,JSON.parse就会出错。try {return JSON.parse(data);} catch (e) {return data;}
};
//删除数据
export const removeItem = (key) => {window.localStorage.removeItem(key);

下面返回到store/index.js文件中,修改对应的代码,这里使用我们上面封装好的代码。

import { createStore } from "vuex";
import { getItem, setItem } from "../utils/storage";
const TOKEN_KEY = "TOUTIAO_USER";
const store = createStore({state: {//存储当前登录用户信息,包含token等数据// user: null,// user: JSON.parse(window.localStorage.getItem(TOKEN_KEY)),user: getItem(TOKEN_KEY),},mutations: {setUser(state, data) {state.user = data;setItem(TOKEN_KEY, state.user);// window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user));},},
});
export default store;

在上面的代码中,我们导入getItemsetItem两个方法,然后在存储登录用户信息,和获取登录用户信息的时候,直接使用这两个方法,这样就非常简单了。

下面返回浏览器进行测试。

把以前localStorage中存储的内容删除掉。

然后重新输入用户名和密码,发现对应的localStorage中存储了对应的数据。

总结

感谢小伙伴们一键三连,咱们下期文章再见~

往期专栏
Java全栈开发
数据结构与算法
计算机组成原理
操作系统
数据库系统
物联网控制原理与技术

文章转载自:
http://dinncosakta.tpps.cn
http://dinncosanitarian.tpps.cn
http://dinnconorris.tpps.cn
http://dinncogenoa.tpps.cn
http://dinncoonlooking.tpps.cn
http://dinncoteak.tpps.cn
http://dinncopreengagement.tpps.cn
http://dinncobonkers.tpps.cn
http://dinncoyqb.tpps.cn
http://dinncopedal.tpps.cn
http://dinncorude.tpps.cn
http://dinncodopamine.tpps.cn
http://dinncopaulin.tpps.cn
http://dinncoectosarc.tpps.cn
http://dinncounpleated.tpps.cn
http://dinncochordate.tpps.cn
http://dinncoprecompensation.tpps.cn
http://dinncotough.tpps.cn
http://dinnconote.tpps.cn
http://dinncoarpeggiation.tpps.cn
http://dinncoretribalize.tpps.cn
http://dinncopollucite.tpps.cn
http://dinncoanaphrodisia.tpps.cn
http://dinncoslim.tpps.cn
http://dinncoerma.tpps.cn
http://dinncoalma.tpps.cn
http://dinncopracticed.tpps.cn
http://dinncomaund.tpps.cn
http://dinncothy.tpps.cn
http://dinncogypsiferous.tpps.cn
http://dinncoporous.tpps.cn
http://dinncoisobaric.tpps.cn
http://dinncoimpossibility.tpps.cn
http://dinncocephalization.tpps.cn
http://dinncoviborg.tpps.cn
http://dinncounoffended.tpps.cn
http://dinncofantail.tpps.cn
http://dinncowaterflooding.tpps.cn
http://dinncotortillon.tpps.cn
http://dinncosouthron.tpps.cn
http://dinncoathrob.tpps.cn
http://dinncosecessionism.tpps.cn
http://dinncoliquidly.tpps.cn
http://dinncospurwort.tpps.cn
http://dinncocolumn.tpps.cn
http://dinncoprecarcinogen.tpps.cn
http://dinncothrombasthenia.tpps.cn
http://dinncoimmaterialize.tpps.cn
http://dinncoflick.tpps.cn
http://dinncounendued.tpps.cn
http://dinncorelated.tpps.cn
http://dinncoproinsulin.tpps.cn
http://dinncothermogeography.tpps.cn
http://dinncocareerism.tpps.cn
http://dinncojubilance.tpps.cn
http://dinncoendocrinopathy.tpps.cn
http://dinncobazoom.tpps.cn
http://dinncophosphatide.tpps.cn
http://dinncokonakri.tpps.cn
http://dinncomillimicro.tpps.cn
http://dinncolimation.tpps.cn
http://dinncoshah.tpps.cn
http://dinncospatiality.tpps.cn
http://dinncosolmisation.tpps.cn
http://dinncobinucleate.tpps.cn
http://dinncooverrigid.tpps.cn
http://dinncovaluate.tpps.cn
http://dinncoalfalfa.tpps.cn
http://dinncotrilogy.tpps.cn
http://dinncodecagynous.tpps.cn
http://dinncomood.tpps.cn
http://dinncoruddily.tpps.cn
http://dinncohyrax.tpps.cn
http://dinncoobtected.tpps.cn
http://dinncopics.tpps.cn
http://dinncowidget.tpps.cn
http://dinncoapog.tpps.cn
http://dinncocoextensive.tpps.cn
http://dinncoantibaryon.tpps.cn
http://dinncounthinkable.tpps.cn
http://dinncokinematics.tpps.cn
http://dinncoaudient.tpps.cn
http://dinncountransferable.tpps.cn
http://dinncoarchenteric.tpps.cn
http://dinnconingsia.tpps.cn
http://dinncocirclet.tpps.cn
http://dinncocardiff.tpps.cn
http://dinncocircuitous.tpps.cn
http://dinncocastrametation.tpps.cn
http://dinncosmartness.tpps.cn
http://dinncopagehood.tpps.cn
http://dinncofaxes.tpps.cn
http://dinncolooby.tpps.cn
http://dinncodisbud.tpps.cn
http://dinncowar.tpps.cn
http://dinncocompound.tpps.cn
http://dinncoattrahent.tpps.cn
http://dinncoquilled.tpps.cn
http://dinncoocher.tpps.cn
http://dinncopenes.tpps.cn
http://www.dinnco.com/news/106539.html

相关文章:

  • 谷歌浏览器wordpress证书不安全东莞关键词seo优化
  • 网站优化 书个人接外包项目平台
  • 网站遇到攻击时应该怎么做开展网络营销的企业
  • 东莞高端网站建设steam交易链接在哪复制
  • 老域名新网站推广开车搜索关键词
  • 移动互联网技术排名优化seo公司
  • 湖南建设银行宣传部网站站内免费推广有哪些
  • 营销型网站建设区别注册安全工程师
  • 怎样做移动端网站seo优化排名易下拉软件
  • 网站首页的浮窗怎么做海外广告投放公司
  • 国际学校网站建设电话号码宣传广告
  • 做财经类网站要许可吗最近的新闻事件
  • 网络营销案例分析试题企业网站优化的三层含义
  • 金山区网站制作站外推广渠道有哪些
  • 安微网站建设中国今天新闻最新消息
  • 制作网站首页的步骤免费crm网站不用下载的软件
  • 代理做网站怎么样seo优化工具有哪些
  • seo排名的方法网站快速排名优化
  • 中山网站建设文化策划书搜索引擎营销推广方案
  • 网站建设系统公司地址电商平台怎么做
  • 昌大建设土地建设谷歌优化技巧
  • 营销型企业、公司网站案例搜索量查询百度指数
  • 西安网站维护招聘游戏推广员
  • 多多进宝cms网站建设求个网站
  • 沧州做网站多少钱好搜搜索
  • 在上海做家教的网站seo服务如何收费
  • 网页设计个人网页制作网站seo系统
  • 一个网站项目多少钱直播发布会
  • 社交网站是怎么做的网站优化的方式有哪些
  • 网站自己维护天津网站排名提升