vue项目 移动端沃尔玛手机商城

设计稿

设计稿地址: http://129.226.179.254/cos/%E4%BA%AC%E4%B8%9C%E9%A1%B9%E7%9B%AE%E8%AE%BE%E8%AE%A1%E7%A8%BF.zip

使用脚手架创建项目

选择要写项目的文件夹位置, 运行如下命令

vue create jd

image-20220218143020235

image-20220218143025524

image-20220218143046223

image-20220218143052320

image-20220218143100900

image-20220218143109567

image-20220218143117571

image-20220218143126483

image-20220218143134829

image-20220218143150716

把项目导入到 vscode, 运行项目进行测试

image-20220218143316356

image-20220218143353679

安装插件

我们需要安装三个插件, 一个是 eslint(代码规范化校验), 一个是 vetur(识别.vue 文件), 一个是prettier eslint(自动把你的代码格式化成符合eslint规范的代码)

image-20220218143908138

image-20220319214829101

项目目录结构

image-20220218144255221

image-20220218144205817

image-20220218144543595

image-20220218144350780

image-20220218144432238

image-20220218144702272

image-20220218144926883

image-20220218144627020

image-20220218145030623

image-20220218145243357

image-20220218145849404

设置项目基础 CSS

我们知道, 不同的浏览器, 有些默认样式是不同的, 比如 padding, margin, 为了抹平各个浏览器之间的差异, 我们通常会写reset.css, 类似于下面这样

* {
   
	margin: 0;
	padding: 0;
}

我们还有另外一个办法, 就是安装一个normalize.css

介绍: https://www.oschina.net/p/normalize-css?hmsr=aladdin1e1

安装的命令如下:

npm install normalize.css

在 main.js 中引入

// src\main.js
// ...
import "normalize.css";

createApp(App).use(store).use(router).mount("#app");

接下来创建 base.scss

// src\style\base.scss
html {
	font-size: 1px;
}

body {
	font-size: 12rem;
}

我们使用 rem 进行布局, 所以需要设置 html 的字体大小, 同时需要设置 body 的字体大小, 不然其他元素会继承 html 的字体大小

然后在 main.js 中引入

// src\main.js
// ...
import "./style/base.scss";
createApp(App).use(store).use(router).mount("#app");

我们修改一下 App.vue, 看一下基础样式是否能正常使用

<template>hello world</template>

经过测试, 发现样式可以正常生效, 如果不确定, 可以给字体加个颜色即可

CSS 的 BEM 命名法

随着项目越来越大, css 的代码量水涨船高, 随着代码量上升, css 变的越来越不好维护, 这时候我们针对 css 类名的命名就需要有一定的规范, 方便我们更好的维护代码, BEM 命名法是其中的一种, BEM 代表 block, element, modifier

img

img

img

示例代码

<form action="">
	username: <input type="text" /> password: <input type="text" />
	<button>submit</button>
</form>

BEM 命名示例

<form action="" class="login-form">
	username: <input type="text" class="login-form__input login-form__input_success" /> password:
	<input type="text" class="login-form__input login-form__input_fail" />
	<button>submit</button>
</form>

开发首页 docker

image-20220218153941945

编写 html 代码

<template>
	<!-- src\App.vue -->
	<div class="docker"></div>
</template>

根据设计稿编写 scss 代码

// src\App.vue
.docker {
	width: 375rem;
	height: 49rem;
	position: fixed;
	bottom: 0;
	left: 0;
	background: #ffffff;
	box-shadow: 0 -1rem 1rem 0 #f1f1f1;
}

这样就有一个最基本的效果

image-20220218154545791

继续编写 html

<!-- src\App.vue -->
<div class="docker">
	<span class="docker__item">
		<span class="docker__item__iconfont iconfont"> </span>
		<span class="docker__item__text"> 首页 </span>
	</span>
	<span class="docker__item">
		<span class="docker__item__iconfont iconfont"> </span>
		<span class="docker__item__text"> 购物车 </span>
	</span>
	<span class="docker__item">
		<span class="docker__item__iconfont iconfont"> </span>
		<span class="docker__item__text"> 订单 </span>
	</span>
	<span class="docker__item">
		<span class="docker__item__iconfont iconfont"> </span>
		<span class="docker__item__text"> 我的 </span>
	</span>
</div>

阶段性效果

image-20220218163147626

我们还需要字体图标

image-20220218163221874

阿里图标库: https://www.iconfont.cn/

我们根据效果图自己搜索类似的图标即可

image-20220218163832872

image-20220218163817645

把线上的 css 代码, 复制到 base.scss

// src\style\base.scss
@font-face {
	font-family: "iconfont"; /* project id 3191519 */
	src: url("");
	src: url("?#iefix") format("embedded-opentype"), url("//at.alicdn.com/t/font_3191519_p8n7uk5xa7d.woff2") format("woff2"),
		url("//at.alicdn.com/t/font_3191519_p8n7uk5xa7d.woff") format("woff"), url("//at.alicdn.com/t/font_3191519_p8n7uk5xa7d.ttf")
			format("truetype"), url("#iconfont") format("svg");
}
html {
	font-size: 1px;
}
body {
	font-size: 12rem;
}

修改 html 代码, 主要是添加字体对应的 unicode

image-20220218165753218

image-20220218165541189

查看页面, 发现并没有生效

image-20220218165628148

需要修改 css 代码

image-20220218165726095

image-20220218165805889

接下来, 我们就可编写底部 docker 的 css 样式了

// src\App.vue
.docker {
	width: 375rem;
	height: 49rem;
	position: fixed;
	bottom: 0;
	left: 0;
	background: #ffffff;
	box-shadow: 0 -1rem 1rem 0 #f1f1f1;
	display: flex;
	justify-content: space-evenly;
	align-items: center;
	padding-top: 10px;
}
.docker__item {
	display: flex;
	flex-direction: column;
	align-items: center;
}
.docker__item__iconfont {
	font-size: 20px;
}
.docker__item__text {
	margin-top: 2px;
	font-family: PingFangSC-Regular;
	font-size: 20px;
	color: #333333;
	transform: scale(0.5, 0.5);
	transform-origin: center top;
}

我们可以根据 scss 语法进行一定的修改

// src\App.vue
.docker {
	width: 375rem;
	height: 49rem;
	position: fixed;
	bottom: 0;
	left: 0;
	background: #ffffff;
	box-shadow: 0 -1rem 1rem 0 #f1f1f1;
	display: flex;
	justify-content: space-evenly;
	align-items: center;
	padding-top: 10px;
	&__item {
		display: flex;
		flex-direction: column;
		align-items: center;
		&__iconfont {
			font-size: 20px;
		}
		&__text {
			margin-top: 2px;
			font-family: PingFangSC-Regular;
			font-size: 20px;
			color: #333333;
			transform: scale(0.5, 0.5);
			transform-origin: center top;
		}
	}
}

image-20220218173306112

我们再来做一下选中高亮的效果

// src\App.vue
.docker {
	// ...
	&__item {
		// ...
		&__iconfont {
			// ...
		}
		&__text {
			// ...
		}
		&_active {
			color: #1fa4fc;
		}
	}
}

经过测试, 我们发现文字颜色还是黑的, 因为蓝色是继承, 优先级低

image-20220218173006948

解决方案是把黑色的代码, 写在 docker__item 里面

// src\App.vue
.docker {
	// ...
	&__item {
		// ...
		color: #333333;
		&__iconfont {
			// ...
		}
		&__text {
			// ...
		}
		&_active {
			color: #1fa4fc;
		}
	}
}

这样效果就出来了

image-20220218173111334

最后, 记得把所有的 px 改成 rem

image-20220218182401379

开发首页 header

先确定首页的轮廓, 处理底部的 docker, 所有的内容都是首页的区域

<!-- src\App.vue -->
<div class="container"></div>
<!-- ... -->
// src\App.vue
.container {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	bottom: 49rem;
	background-color: olivedrab;
}
.docker {
	// ...
}
image-20220219125926432

轮廓确定后, 就可以着手开发 header 了

image-20220219124524726

先写 html 代码

image-20220219130736590

image-20220219130759996

我们需要添加字体图标, 搜索关键字 position 和 notice, 可以找到对应图标

image-20220219131605585

更新字体代码

image-20220219131658352

把字体图标的 unicode 加入到项目里面去

image-20220219131905970

我们可以看到字体图标了

image-20220219131830209

接下来编写 css

// src\App.vue
.container {
	// ...
	&__header {
		display: flex;
		justify-content: space-between;
		padding: 16px 19.2px;
		&__left__position-iconfont {
			font-size: 16px;
			margin-right: 9.7px;
		}
		&__left__position-text {
			font-family: PingFangSC-Regular;
			font-size: 16px;
			color: #333333;
		}
		&__right__notice-iconfont {
			font-size: 18px;
		}
	}
}

.docker {
	// ...
}

最终效果

image-20220219133421834

有个小细节, 如果地址过长的话, 页面样式会比较丑

image-20220219133707724

我们可以设置, 如果字体过长, 显示省略号

// src\App.vue
&__header {
	// ...
	&__left {
		width: 310px;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		&__position-iconfont {
			// ...
		}
		&__position-text {
			// ...
		}
	}
	&__right__notice-iconfont {
		// ...
	}
}

因为我们在用 scss, 所以我们可以把超出部分省略隐藏的代码做成 mixin

// src\style\mixins.scss
@mixin ellipsis {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

image-20220219144400916

我们也可以把颜色做成变量, 起到复用的效果

// src\style\variables.scss
$content-fontcolor: #333;

image-20220219150355522

首页搜索区域

image-20220219150429700

首先编写 html 代码

image-20220219152632524

我们需要字体图标, 去阿里图标库搜索 search

image-20220219152811159

image-20220219153009686

复制 unicode 到 html

image-20220219153034718

image-20220219153046626

接下来编写样式

// src\App.vue
// ...
.container {
	position: absolute;
	// ...
	&__header {
		// ...
	}
	&__search {
		text-align: center;
		position: relative;
		color: #b7b7b7;
		&__input {
			background: #f5f5f5;
			border-radius: 16px;
			width: 339px;
			height: 32px;
			padding-left: 44px;
			box-sizing: border-box;
			&::-webkit-input-placeholder {
				font-family: PingFangSC-Regular;
				font-size: 14px;
				line-height: 16px;
			}
			&:-moz-placeholder {
				font-family: PingFangSC-Regular;
				font-size: 14px;
				line-height: 16px;
			}
			&::-moz-placeholder {
				font-family: PingFangSC-Regular;
				font-size: 14px;
				line-height: 16px;
			}
			&:-ms-input-placeholder {
				font-family: PingFangSC-Regular;
				font-size: 14px;
				line-height: 16px;
			}
		}
		&__iconfont {
			position: absolute;
			left: 34px;
			top: 6px;
			font-size: 16px;
		}
	}
}

.docker {
	// ...
}

最终效果

image-20220219160244130

首页 banner 区

image-20220219160353172

图片地址: https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202191609589.png

我们先编写 html 代码

image-20220219161827713

image-20220219161854920

接下来编写 css

image-20220219162027756

image-20220219162038217

有个小细节, 如果网速比较慢, 图片没有加载出来的时候, 下面的内容会挤上来, 为了解决这个问题, 可以给 banner 设置一个高度, 保证下面的内容位置不会因为图片没有加载出来而发生变化

image-20220219162920251

首页快捷导航

image-20220219163040851

首先编写 html, 需要的图标地址如下:

http://129.226.179.254/cos/%E5%AF%BC%E8%88%AA%E5%9B%BE%E6%A0%87.zip

我们先下载图标, 把图标移动到src/assets/index里面

image-20220219171451940

html 代码如下

image-20220219171904393

image-20220219171828085

接下来编写 css 样式

image-20220219172730845

image-20220219172901466

我们可以优化一下代码, 之前定义的变量可以用上

image-20220219173015289

首页内容间缝隙

image-20220219173328319

编写 html

image-20220219173401722

编写 css

image-20220219173458065

导航区的背景色去除后, 可以看到最终的效果

image-20220219173539236

记得把所有的 px 改成 rem

把页面布局做成自动适应

我们发现, iphone6/7/8 的页面没有问题, 但是换成其他机型, 页面就会出问题

image-20220219174031157

原因是我们虽然以 rem 为单位, 但是 html 的字体大小还是写到 1px, 我们需要把 px 换成 vw

image-20220219174214322

image-20220219174323724

首页附近店铺

image-20220221134141868

首先编写 html 代码

图片路径: https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211407079.png

image-20220221140953201

接下来编写 css

image-20220221142306337

我们可以多复制几份, 看看效果

image-20220221142406423

发现两个问题, 一个是各个 item 挨得太近, 一个是最后一个 item 被 docker 盖住了

image-20220221144518153

解决方案如下

image-20220221144458544

image-20220221144533429

记得把#333333改成$content-fontcolor, 把px改成rem

首页代码合理拆分

我们发现, 首页的代码量越来越大, 代码越来越难以维护, 所以我们需要把首页拆成组件

先新建src\views\home\Home.vue, 把原来src\App.vue的代码拷贝进去

然后注意修改路径

image-20220221163432625

src\App.vue中引入Home.vue

<template>
	<Home />
</template>

<script>
import Home from "./views/home/Home.vue";
export default {
	name: "App",
	components: { Home },
};
</script>

注意修改路由src\router\index.js

image-20220221163550709

拆分之后, 没有 bug, 我们就可以继续拆分src\views\home\Home.vue

我们把页面的每一块都进行拆分, 新建对应的 vue 文件, 填写基本的代码

src\views\home\Banner.vue
src\views\home\Docker.vue
src\views\home\Gap.vue
src\views\home\Header.vue
src\views\home\Nav.vue
src\views\home\Nearby.vue
src\views\home\Search.vue
<template>
	<div></div>
</template>
<script>
export default {};
</script>
<style lang="scss"></style>

拆分代码到src\views\home\Header.vue, 完善代码

image-20220221170653478

src\views\home\Home.vue中使用 header 组件

image-20220221171143154

查看页面, 发现没有什么问题, 其他组件同理, 不再赘述

docker 代码精简

docker 的 html 代码有大量重复的部分, 可以做一个精简, 定义一个数组, 使用v-for

image-20220221174348993

image-20220221174403618

效果如下, 发现全部高亮, 并且字体图标的 unicode 被转义了

image-20220221174333237

解决方案, 使用v-html

image-20220221174540783

image-20220221174523756

高亮是因为所有的 span 都有类docker__item_active, 解决方案是, 可以把 class 变成对象形式

image-20220221174906752

image-20220221174920425

附近商铺代码精简

附近商铺的 html 代码有大量重复的部分, 可以做一个精简, 定义一个数组, 使用v-for

image-20220221180743260

遍历数据

image-20220221181143544

最终效果:

image-20220221181121188

导航精简

导航的 html 代码有大量重复的部分, 可以做一个精简, 定义一个数组, 使用v-for

因为抽离数据, 是为了将来的 ajax, 所以图标的路径, 我们换成线上的

https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211843776.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211843550.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211843505.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211843412.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211844276.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211844145.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211844545.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211844072.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211844735.png
https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202211844286.png

抽离数据

image-20220221184640658

展示数据

image-20220221184701334

css 作用域约束

我们之前测试过, 默认情况下, 各组件之间的 css 会互相影响

image-20220221185731868

如果我们想让的 css 只对当前组件生效, 可以使用 scoped

image-20220221185846679

可以使用 vscode 的批量替换功能

image-20220221190014541

eslint 格式化插件

image-20220222142323468

这个插件可以把代码按照 eslint 的标准进行格式化

登录页面

我们的逻辑是, 用户只有登录了才能访问首页, 所以我们接下来做登录页

image-20220222140744833

先修改src\App.vue

<template>
	<Login />
</template>

<script>
// import Home from './views/home/Home.vue'
import Login from "./views/login/Login.vue";
export default {
	name: "App",
	components: { Login },
};
</script>

然后新建src\views\login\Login.vue

<template>
	<div>hello world</div>
</template>
<script>
export default {
	name: "Login",
};
</script>
<style lang="scss" scoped></style>

看一下效果, 代码能不能跑通

image-20220222142517763

编写 html 代码

图片地址: https://markdown-1253389072.cos.ap-nanjing.myqcloud.com/202202221429453.png

image-20220222145641491

image-20220222145709545

接下来编写 css

image-20220222152834286

button 去除边框和轮廓的代码可以和 input 放在一起

image-20220222152932771

最终效果

image-20220222152800726

路由设置

配置一下路由, 让http://localhost:8080/#/跳到首页, 让http://localhost:8080/#/login跳到登录页

image-20220222153134596

需要修改src\App.vue

<template>
	<router-view></router-view>
</template>

<script>
export default {
	name: "App",
};
</script>

登录校验

逻辑如下:

如果没有登录, 访问首页或者其他任何页面, 都会跳到登录页

如果已经登录, 访问登录页面会跳到首页

点击登录按钮, 登录成功, 自动跳转到首页

我们可以使用localStorage.isLogin来存储登录状态

首先修改src\router\index.js

// to 跳到哪里去
// from 从哪里跳过来
// next 继续执行
router.beforeEach((to, from, next) => {
   
	console.log(to, from);
	next();
});
export default router;

next 的用法next({name:'Login'})跳转到 Login 路由

我们可以做如下判断

// src\router\index.js
// to 跳到哪里去
// from 从哪里跳过来
// next 继续执行
router.beforeEach((to, from, next) => {
   
	if (localStorage.isLogin === "true" || to.name === "Login") {
   
		next();
	} else {
   
		next({
    name: "Login" });
	}
});
export default router;

点击登录, 保存登录状态, 跳到首页, 页面跳转可以使用 router.push

// src\views\login\Login.vue
import {
    useRouter } from "vue-router";
export default {
   
	name: "Login",
	setup() {
   
		const router = useRouter();
		const handleLogin = () => {
   
			localStorage.setItem("isLogin", "true");
			router.push({
    name: "Home" });
		};
		return {
    handleLogin };
	},
};

如果已经登录, 访问登录页面的时候, 应该跳回到首页

const routes = [
	{
   
		path: "/",
		name: "Home",
		component: Home,
	},
	{
   
		path: "/login",
		name: "Login",
		component: Login,
		// src\router\index.js
		// 访问login页面之前执行
		beforeEnter: (to, from, next) => {
   
			if (localStorage.isLogin === "true") {
   
				next({
    name: "Home" });
			} else {
   
				next();
			}
		},
	},
];

注册页面

注册页面和登录页面很像, 我们可以复制代码, 稍作修改

image-20220222170749223

image-20220222171505193

我们需要配置路由

image-20220222171911412

这样我们就可以调效果了

image-20220222172313000

image-20220222172334757

image-20220222172249596

登录注册的跳转逻辑

  1. 如果已经登录, 跳到注册页面会跳回首页
  2. 如果没有登录, 可以正常跳转到注册页
  3. 登录页可以跳转到注册页
  4. 注册页可以跳转到登录页

image-20220222190441245

注意设置 a 标签的跳转路径

image-20220222190328101

image-20220222190255799

修改 vue 文件

image-20220222190158852

调用后台接口实现登录功能

我们需要接口的时候, 可能后台还没有把接口写好, 这个时候, 后台往往会借助 mock 平台, 做一个假的接口给我们, 让我们能够正常书写 ajax 的逻辑

所谓假的接口, 只是说没有内部验证逻辑, 接口地址是最终的地址不会变

到最后, 我们把 mock 平台的域名改成自己项目的域名即可

比较好用的 mock 平台 https://www.fastmock.site

之前因为有用户做的接口涉嫌诈骗, 网站被关停了一段时间, 现已恢复

接下来我们创建一个用户登录的接口

image-20220223105904348

/*
输入: 
content-type: json
body{
  phone: '15639878900',
  password: '123456'
}
*/

{
   
	"code": "0000",
	"desc": "登录成功!!!"
}

调用 ajax, 我们需要 axios, 运行如下命令安装

npm install axios

安装完检查一下 package.json

image-20220223110304366

说明安装成功, 可以编写 ajax 代码了

文档地址: http://www.axios-js.com/zh-cn/docs/

image-20220223111529880

输出测试后, 可以得到结果, 继续编写后面的逻辑

image-20220223111647054

image-20220223111806428

现在的数据是写死的, 我们需要获取 input 框的数据, 传给接口

src\views\login\Login.vue

image-20220223113100720

image-20220223113105323

image-20220223113121905

image-20220223113141833

另外, 接口文档上说, 需要content-type:json

image-20220223113335645

image-20220223113627330

image-20220223113747634

async 和 await 的用法

async 是一个修饰符,被它定义的函数会默认的返回一个 Promise 的 resolve 的值。

因此对 async 函数可以直接进行 then 操作,返回的值即为 then() 方法的传入函数。

async function demo() {
	console.log("a");
	return 123;
}
demo().then((res) => {
	console.log(res);
});

await 同 async 一样,作为修饰符,但是它只能放在 async 内部使用。

它是获取 Promise 中返回的内容, 即这个 Promise 函数中 resolve 或者 reject 的值。

所以,async 用于声明一个 function 是异步的,而 await 用于等待一个异步方法执行完成

const myFun = function () {
	return "test";
};

async function myFun2() {
	const a = await 1;
	const b = await new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve("wait");
		}, 3000);
	});
	const c = await myFun();
	console.log(a, b, c);
}

myFun2();

比如说,等待三个数据结果都返回,计算它们的和

function doubleAfter2seconds(num) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve(2 * num);
		}, 1000);
	});
}
async function testResult() {
	let first = await doubleAfter2seconds(1);
	let second = await doubleAfter2seconds(2);
	let third = await doubleAfter2seconds(3);
	console.log(first + second + third);
}
testResult();

封装请求函数

我们可以对 axios 请求数据的代码进行一个封装

首先使用 await 和 try catch, 改变一下代码

image-20220223151550909

try catch 用来捕获异常, 如果 try 里面的代码存在异常, 就会执行 catch 里面的代码

接下来新建src\utils\request.js, 我们对请求进行封装

// src\utils\request.js
import axios from "axios";
axios.defaults.headers.post["Content-Type"] = "application/json";
axios.defaults.baseURL = "https://www.fastmock111.site/mock/e764a900fc6cdbc199fb33651082d60f/weixin";
const post = (url, data = {
    }) => {
   
	return new Promise((resolve, reject) => {
   
		axios.post(url, data).then(
			(response) => {
   
				resolve(response);
			},
			(error) => {
   
				reject(error);
			}
		);
	});
};
export {
    post };

src\views\login\Login.vue中使用

image-20220223154815544

弹框组件

我们做一个自定义的弹框组件, 来替换掉浏览器默认的弹框

这是一个公共组件

<template>
	<!-- src\components\Toast.vue -->
	<div class="toast">这是弹框</div>
</template>
<script>
export default {
	name: "Toast",
};
</script>
<style lang="scss" scoped></style>

我们给一些样式

.toast {
   
	position: fixed;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	background-color: rgba(0, 0, 0, 0.35);
	padding: 10rem;
	border-radius: 5rem;
	color: #fff;
}

尝试在src\views\login\Login.vue中使用

image-20220223161000406

image-20220223161018071

使用 v-if 来控制显示和隐藏

image-20220223163417520

自定义展示的信息

image-20220223163719959

需要在组件里面使用toastMessage

image-20220223163839951

image-20220223163858751

设置 2 秒之后自动消失

image-20220223164020798

定义 showToast, 对代码进行封装

image-20220223164430937

通过代码拆分增加逻辑可维护性

引用时, 全局的放到上面, 自定义的写在下面

image-20220223165219231

把 showToast 相关的逻辑, 进行拆分

image-20220223170000193

因为弹框的逻辑, 其他页面也要使用, 所以可以把相关的逻辑代码, 放到src\components\Toast.vue 里面去

image-20220223170815183

我们可以继续拆分, 尽量做到 setup 中逻辑更加清晰

首先可以把 data 进行一个结构

image-20220223182341036

toastData, 也可以进行解构

image-20220223182942942

image-20220223183114223

我们也可以把登录的逻辑抽象出来

// src\views\login\Login.vue
const userLoginEffect = (showToast) => {
   
	const data = reactive({
   
		phone: "",
		password: "",
	});
	const router = useRouter();
	// src\views\login\Login.vue
	const handleLogin = async () => {
   
		// 调用接口
		try {
   
			const result = await post("/api/user/login", {
   
				phone: data.phone,
				password: data.password,
			});
			if (result.data.code === "0000") {
   
				localStorage.setItem("isLogin", "true");
				router.push({
    name: "Home" });
			} else {
   
				showToast("登录失败, 用户名或密码不正确...");
			}
		} catch (error) {
   
			showToast("发送请求失败!");
		}
	};
	// 返回数据
	const {
    phone, password } = toRefs(data);
	return {
   
		phone,
		password,
		handleLogin,
	};
};

继续拆离用户注册跳转的相关逻辑


                
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bscfrwx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值