60 订单页选择收货地址

我们将订单页面一些内容算是修正了,然后接下来我们要点击提交订单了,我们去src/views/Order.vue添加如下内容
复制代码
template:
1,点击 '提交订单' 可以进入到支付页面
<div class="order-topay" @click="goPayment">提交订单</div>

2,点击收货人信息的任何以项都可以进入到收货地址页面
<div class="path">
    <h3 class="path-title">收货信息:</h3>
    <!-- {{path}} -->
    <div class="path-content"  @click="goPath">
        <div>
            <span>{{path.name}}</span>
            <span>{{path.tel}}</span>
            <!-- <span>张三</span>
            <span>18017927192</span> -->
        </div>
        <div>
            <span>{{path.province}}</span>
            <span>{{path.city}}</span>
            <span>{{path.county}}</span>
            <span>{{path.addressDetail}}</span>
            <!-- <span>省</span>
            <span>市</span>
            <span>区县</span>
            <span>详细地址</span> -->
        </div>
    </div>
</div>

script:
1, 引入
import {Toast} from 'vant';

2,点击 '收货人信息的任何以项' 进入到 '/path' 页面,根据传入的参数 'query',再次跳转到 src/views/path/Path-Index.vue 页面,进行地址选择
// 选择收货地址	src/views/Order.vue 页面添加如下代码
goPath() {
    this.$router.push({
        path: '/path',
        query: {
            type: 'select'
        }
    });
},


3,去 src/views/path/Path-Index.vue 页面,找到 created() {}添加如下代码来判断选择收货地址。
1). 记录数据
data() {
    return {
        pathStatus: false
    }
},


2) 判断
created() {
    // 从订单页面进来的 判断
    if (this.$route.query.type == 'select') {
        // 只要是从订单页进入,就将 pathStatus 的值设置为 true
        this.pathStatus = true;
    }

    this.getData();
},


3)选择
goList(option) {
    // this.pathStatus为 true,代表从订单页面进入的:选择状态
    if (this.pathStatus) {
        this.$router.back();
        return;
    }

    // console.log(option);

    // 两种实现跳转方式都可以 根据名称和路径
    // this.$router.push('/path/path-list');
    this.$router.push({
        name: 'Path-List',
        params: {
            // key: option
            key: JSON.stringify(option)
        }
    })
}
对src/views/Order.vue添加keep-Alive才可以使用activated() {}生命周期函数 代码如下
复制代码
1, 在 src/router/index.js 中添加如下内容
{
    path: "/order",
    name: "Order",
    meta: {
        keepAlive: true, // 此组件需要被缓存
    },
    component: () =>
        import("../views/Order.vue"),
}

2,使用activated() {}生命周期函数 代码如下
// 使用了 keep-Alive时出现的生命周期函数 activated() {}
activated() {
    // 接收 src/views/path/Path-Index.vue 传值
    bus.$on('selectPath', function(data) {
        this.path = JSON.parse(data);

        // console.log(this.path, "xxx");
        // console.log(JSON.parse(data), "data");
    }.bind(this));
    // console.log(this.path, "yyy");


    // 查询到地址了
    // 选中的商品的id号  转换  接收也要显式
    this.item = JSON.parse(this.$route.query.detail); // 显式
    // this.item = JSON.parse(this.$route.params.detail); // 隐式

    // 接收从 Cart.vue 文件中传递的 goodsList
    this.goodsList = JSON.parse(this.$route.query.goodsList);


    // 调用 查询订单
    this.selectOrder();
},
订单页选择收货地址 实现代码如下
复制代码
1, src/common/bus.js
import Vue from 'vue';
export default new Vue;


2, src/views/Order.vue
<template>
	<div class="order container">
		<header>
			<i class="iconfont icon-a-huaban1fuben44" @click="$router.back()"></i>
			<span>提交订单</span>
			<i class="iconfont icon-kefu"></i>
		</header>
		<section>
			<div class="path">
				<h3 class="path-title">收货信息:</h3>
				<!-- {{path}} -->
				<div class="path-content" @click="goPath">
					<div>
						<span>{{path.name}}</span>
						<span>{{path.tel}}</span>
						<!-- <span>张三</span>
						<span>18017927192</span> -->
					</div>
					<div>
						<span>{{path.province}}</span>
						<span>{{path.city}}</span>
						<span>{{path.county}}</span>
						<span>{{path.addressDetail}}</span>
						<!-- <span>省</span>
						<span>市</span>
						<span>区县</span>
						<span>详细地址</span> -->
					</div>
				</div>
			</div>
			<div class="payment">
				<!-- {{radioPayment}} -->
				<div class="payment-title">支付方式:</div>
				<van-radio-group v-model="radioPayment">
					<van-radio name="wx">微信支付</van-radio>
					<van-radio name="ali">支付宝支付</van-radio>
				</van-radio-group>
			</div>
			<div class="goods">
				<!-- {{goodsList}} -->
				<ul>
					<li v-for="(item,index) in goodsList" :key="index">
						<div>
							<img :src="item.goods_imgUrl" alt="" />
						</div>
						<div class="goods-content">
							<h4>{{item.goods_name}}</h4>
							<div>规格: 暂无</div>
							<div class="goods-total">
								<span class="goods-price">¥{{item.goods_price}}</span>
								<span>x{{item.goods_num}}</span>
							</div>
						</div>
					</li>
				</ul>
			</div>
		</section>
		<footer>
			<div class="order-total">
				<span>共</span>
				<b>{{total.num}}</b>
				<span>件,</span>
				<span>总金额:</span>
				<em>¥{{total.price}}</em>
			</div>
			<div class="order-topay" @click="goPayment">
				提交订单
			</div>
		</footer>
	</div>
</template>

<script>
	import http from '@/common/api/request.js'
	import {
		mapState,
		mapGetters,
		mapMutations
	} from 'vuex';
	import {
		Toast
	} from 'vant';
	import bus from '@/common/bus.js'
	export default {
		data() {
			return {
				radioPayment: 'wx',
				path: {},
				item: [],
				total: {
					price: 0,
					num: 0
				}
			}
		},
		computed: {
			...mapState({
				// list: state => state.cart.list
				// list: state => state.order.list
				order_id: state => state.order.order_id
			}),
			...mapGetters(['defaultPath'])
			// ...mapGetters(['total', 'defaultPath']),
			// console.log(this.list); // 空值
		},
		created() {
			this.goodsList = JSON.parse(this.$route.query.goodsList);

			// 调用 查询地址
			this.selectAddress();

			// 查询订单号
			// console.log(this.order_id);

			// 读取存储值->订单号  20210709145102260155
			// console.log(localStorage.getItem('tea_orderId'));

			// Cart.vue 传值到这里 打印一下
			// console.log(this.$route.query.detail);		
		},
		// 使用了 keep-Alive时出现的生命周期函数 activated() {}
		activated() {
			// 接收 src/views/path/Path-Index.vue 传值
			bus.$on('selectPath', function(data) {
				this.path = JSON.parse(data);

				// console.log(this.path, "xxx");
				// console.log(JSON.parse(data), "data");
			}.bind(this));
			// console.log(this.path, "yyy");


			// 查询到地址了
			// 选中的商品的id号  转换  接收也要显式
			this.item = JSON.parse(this.$route.query.detail); // 显式
			// this.item = JSON.parse(this.$route.params.detail); // 隐式

			// 接收从 Cart.vue 文件中传递的 goodsList
			this.goodsList = JSON.parse(this.$route.query.goodsList);


			// 调用 查询订单
			this.selectOrder();
		},
		methods: {
			...mapMutations(['initData', 'initOrder']),

			// 查询地址 封装
			selectAddress() {


				// 请求收货地址
				http.$axios({
					url: '/api/selectAddress',
					method: 'post',
					headers: { // 哪个用户新增地址
						token: true
					}
				}).then(res => {
					// 将数据存储到 vuex 中
					this.initData(res.data);

					// 有默认收货地址
					if (this.defaultPath.length) {
						this.path = this.defaultPath[0];
					} else {
						this.path = res.data[0];
					}
				});
			},

			// 查询订单 封装
			selectOrder() {
				// 查询订单(前端)
				http.$axios({
					url: '/api/selectOrder',
					method: 'post',
					headers: { // 哪个用户新增地址
						token: true
					},
					data: {
						// 前端给后端传递的订单号
						orderId: this.order_id
					}
				}).then(res => {
					// 将数据存储到 vuex 中
					this.initOrder(res.data);

					this.total = {
						price: res.data[0].goods_price,
						num: res.data[0].goods_num
					}
				});
			},


			// 选择收货地址
			goPath() {
				this.$router.push({
					path: '/path',
					query: {
						type: 'select'
					}
				});
			},

			// 提交订单
			goPayment() {
				// 判断是否选择了收货地址
				if (!this.path) return Toast('请填写收货地址');
			}
		}
	}
</script>

<style scoped lang="scss">
	header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		width: 100%;
		height: 44px;
		color: #fff;
		background-color: #b0352f;



		i {
			padding: 0 18px;
			font-size: 24px;
		}

		span {
			font-size: 18px;
			font-weight: 300;
		}
	}

	section {
		background-color: #f7f7f7;

		.path-title {
			padding: 6px 15px;
			font-size: 20px;
			// color: dimgray;
		}

		.path-content {
			padding: 6px 15px;
			font-size: 18px;
			background-color: #FFFFFF;

			span {
				padding-right: 6px;
			}
		}

		.payment {
			padding: 6px 15px;
			margin-top: 15px;
			font-size: 16px;
			background-color: #FFFFFF;

			.van-radio-group {
				display: flex;
				padding: 10px 0;

				.van-radio {
					padding-right: 10px;
				}
			}
		}

		.goods {
			padding: 6px 15px;
			margin-top: 15px;
			font-size: 16px;
			background-color: #FFFFFF;

			ul {
				width: 100%;

				li {
					display: flex;
					width: 100%;

					img {
						width: 74px;
						height: 74px;
					}

					.goods-content {
						display: flex;
						flex: 1;
						flex-direction: column;
						justify-content: space-between;
						padding-left: 15px;

						.goods-total {
							display: flex;
							justify-content: space-between;

							.goods-price {
								font-size: 18px;
								color: #b0352f;
							}
						}
					}
				}
			}
		}
	}

	footer {
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		line-height: 50px;
		border-top: 1px solid #CCC;

		.order-total {
			font-size: 20px;

			span {
				padding: 0 6px;
			}

			b {
				color: #b0352f;
			}

			em {
				font-size: 22px;
				color: #b0352f;
			}
		}



		.order-topay {
			width: 120px;
			line-height: 50px;
			text-align: center;
			color: #fff;
			background-color: #b0352f;
			font-size: 18px;
		}

	}
</style>





3, src/views/path/Path-Index.vue
<template>
	<div class="path-index container">
		<Header>
			<span>我的地址</span>
		</Header>
		<section>
			<ul v-if="list.length">
				<li @click="goList(item)" v-for="(item,index) in list" :key="index">
					<div>
						<span>{{item.name}}</span>
						<span>{{item.tel}}</span>
					</div>
					<div class="city">
						<span class="active" v-if="item.isDefault==1">[默认]</span>
						<span>{{item.province}}</span>
						<span>{{item.city}}</span>
						<span>{{item.county}}</span>
						<span>{{item.addressDetail}}</span>
					</div>
				</li>
			</ul>
			<h1 v-else>暂无数据,请添加地址</h1>
			<div class="add-path" @click="goList(add)">添加地址</div>
		</section>
		<Tabbar></Tabbar>
	</div>
</template>

<script>
	import http from '@/common/api/request.js'
	import Header from '@/components/path/Header.vue'
	import Tabbar from '@/components/common/Tabbar.vue'
	import {
		mapState,
		mapMutations
	} from 'vuex'
	import bus from '@/common/bus.js'

	export default {
		name: "Path-Index",
		data() {
			return {
				pathStatus: false
			}
		},
		components: {
			Header,
			Tabbar
		},
		created() {
			// 从订单页面进来的 判断
			if (this.$route.query.type == 'select') {
				// 只要是从订单页进入,就将 pathStatus 的值设置为 true
				this.pathStatus = true;
			}

			this.getData();
		},
		computed: {
			...mapState({
				list: state => state.path.list
			})
		},
		methods: {
			...mapMutations(['initData']),

			// 发送请求
			getData() {
				// 请求收货地址
				http.$axios({
					url: '/api/selectAddress',
					method: 'post',
					headers: { // 哪个用户新增地址
						token: true
					}
				}).then(res => {
					// 将数据存储到 vuex 中
					this.initData(res.data);
					// console.log(res.data);
				});
			},
			// 点击进入的地方进行判断
			goList(option) {
				console.log(option);
				// this.pathStatus为 true,代表从订单页面进入的:选择状态
				if (this.pathStatus) {
					// this.$router.back();
					// 传值 => src/views/Order.vue 
					bus.$emit('selectPath', JSON.stringify(item));
					this.$router.back();
					// this.$router.back({
					// 	name: 'Order'
					// });
					return;
				}

				// console.log(option);

				// 两种实现跳转方式都可以 根据名称和路径
				// this.$router.push('/path/path-list');
				this.$router.push({
					name: 'Path-List',
					params: {
						// key: option
						key: JSON.stringify(option)
					}
				})
			}
		}
	}
</script>

<style scoped lang="scss">
	section {
		display: flex;
		flex-direction: column;
		align-items: center;
		background-color: #f7f7f7;

		ul {
			width: 100%;

			li {
				padding: 10px 15px;
				width: 100%;
				margin: 6px 0;
				background-color: #FFFFFF;

				span {
					padding-right: 15px;
					font-size: 18px;
				}

				.active {
					color: #b0353f;
				}

				.city {
					span {
						padding-right: 6px;
					}
				}
			}
		}

		.add-path {
			margin-top: 30px;
			width: 150px;
			line-height: 40px;
			font-size: 18px;
			text-align: center;
			color: #fff;
			background-color: #b0352f;
			border-radius: 6px;
		}
	}

	::v-deep .tabbar {
		border-top: 2px solid #ccc;
	}
</style>





import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";

Vue.use(VueRouter);

const routes = [{
		path: "/home",
		name: "Home",
		component: Home,
	},
	{
		path: "/",
		redirect: "/home", // 重定向
	}, {
		path: "/list",
		name: "List",
		component: () =>
			import("../views/List.vue"),
	}, {
		path: "/cart",
		name: "Cart",
		meta: {
			keepAlive: true, // 此组件需要被缓存
		},
		component: () =>
			import("../views/Cart.vue"),
	}, {
		path: "/my",
		name: "My",
		component: () =>
			import("../views/My.vue"),
	},
	{
		path: "/search",
		children: [{
			path: "/",
			name: "index",
			component: () =>
				import("../views/search/Search-index.vue"),
		}, {
			path: "/search/list",
			name: "Search-list",
			component: () =>
				import("../views/search/Search-list.vue"),
		}],
		component: () =>
			import("../views/Search.vue"),
	},
	{
		path: "/detail",
		name: "Detail",
		meta: {
			keepAlive: true, // 此组件需要被缓存
		},
		component: () =>
			import("../views/Detail.vue"),
	},
	{
		path: "/login",
		name: "Login",
		component: () =>
			import("../views/login/Login.vue"),
	},
	{
		path: "/userLogin",
		name: "UserLogin",
		component: () =>
			import("../views/login/UserLogin.vue"),
	},
	{
		path: "/register",
		name: "Register",
		component: () =>
			import("../views/login/Register.vue"),
	},
	{
		path: "/recovery",
		children: [{
			path: "/",
			name: "RecoveryIndex",
			component: () =>
				import("../views/recovery/RecoveryIndex.vue"),
		}, {
			path: "/recovery/btn",
			name: "RecoveryBtn",
			component: () =>
				import("../views/recovery/RecoveryBtn.vue"),
		}],
		component: () =>
			import("../views/recovery/Recovery.vue"),
	},
	{
		path: "/path",
		children: [{
			path: "/",
			name: "Path-Index",
			component: () =>
				import("../views/path/Path-Index.vue"),
		}, {
			path: "/path/path-list",
			name: "Path-List",
			component: () =>
				import("../views/path/Path-List.vue"),
		}, {
			path: "/path/path-province-city",
			name: "Path-Province-City",
			component: () =>
				import("../views/path/Path-Province-City_bak.vue"),
		}, {
			path: "/path/path-address",
			name: "Path-Address",
			component: () =>
				import("../views/path/Path-Address_bak.vue"),
		}],
		component: () =>
			import("../views/Path.vue"),
	},
	{
		path: "/order",
		name: "Order",
		meta: {
			keepAlive: true, // 此组件需要被缓存
		},
		component: () =>
			import("../views/Order.vue"),
	}
];

const router = new VueRouter({
	mode: "history",
	base: process.env.BASE_URL,
	routes,
});

export default router;4, src/router/index.js
相关推荐
陈随易19 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
Dream-Y.ocean21 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Csvn1 天前
性能监控
前端
Highcharts.js1 天前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
Csvn1 天前
构建工具
前端
FRing031 天前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Java小卷1 天前
JuanForm vs FormCreate!Vue3 表单引擎联动配置 PK!
vue.js·低代码
kyriewen1 天前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
IT_陈寒1 天前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
工控丫丫1 天前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库