收货地址主要包括收货地址页面、新增收货地址、修改收货地址、删除收货地址、保存收货地址和显示收货地址等功能,下面通过代码完成收货地址的功能。
收货地址页面展示了用户的收货地址信息,当用户单击底部Tab栏中的“我的”选项,此时,页面会跳转到“我的”页面,在我的页面中找到收货地址选项,此时,单击“收货地址”选项,页面会跳转到“收货地址”的页面,下面通过代码实现收货地址页面的效果。
(1)打开src\pages\User.vue文件,编写代码,具体代码如下。
<router-link :to="{ name: 'address' }" class="mui-navigate-right">
<img class="mui-media-object mui-pull-left" src="../assets/images/avatar_default.png">
<div class="mui-media-body">收货地址div>
router-link>
上述代码中,将页面中原来的类名为.mui-navigate-right的div元素改为router-link,并通过:to的方式设置目标地址为“{name:'address'}”表示当单击router-link标签时让页面跳转到路由名称为address的页面,img标签中的src属性的值为加载图片路径。
(2)打开src\router.js文件,首先导入组件,编写代码如下。
import Address from './pages/user/Address.vue'
import AddressEdit from './pages/user/AddressEdit.vue'
上述代码中,通过import…from…的方式,导入页面组件Address.vue和AddressEdit.vue组件,其中Address表示收货地址页面,AddressEdit表示编辑收货地址页面。
(3)在src\router.js文件中,配置路由,编写代码如下。
routes: [
……(原有代码)
{ path: '/user/address', component: Address, name: 'address', meta: { title: '收货地址' } },
{ path: '/user/address/add', component: AddressEdit, name: 'address_add', meta: { title: '新增收货地址' } },
],
上述代码中,在routes中,配置路由对象,每个对象表示一条路由,其中path表示路由地址,component的属性值为导入的页面组件名称,name表示路由名称,meta表示设置网页的标题为收货地址。
在实现了收货地址页面效果之后,当单击页面中的“新增收货地址”按钮,让页面跳转到“新增收货地址页面”,然后,填写收货地址信息,例如收件人、联系方式、所在地区和详细地址选项,填写完成之后单击“确认”按钮,完成收货地址的添加功能,下面通过代码实现新增收货地址功能。
(1)打开src\pages\user\AddressEdit.vue文件,编写HTML代码,具体代码如下。
<template>
<div class="address_edit">
<form class="mui-input-group">
<div class="mui-input-row">
<label>收件人label>
<input
v-model="form.name"
type="text"
class="mui-input-clear"
placeholder="请输入收件人姓名"
/>
div>
<div class="mui-input-row">
<label>联系方式label>
<input
v-model="form.tel"
type="text"
class="mui-input-clear"
placeholder="请输入手机号"
/>
div>
<div class="mui-input-row">
<label>所在地区label>
<input
type="text"
v-model="form.area"
class="mui-input-clear"
placeholder="所在地区"
@click="choose"
/>
<div class="divwrap">
<div class="mask" @click="choose" v-show="show">div>
<v-distpicker
v-show="show"
type="mobile"
@province="onChangeProvince"
@city="onChangeCity"
@area="onChangeArea"
:province="newInfo.province"
:city="newInfo.city"
:area="newInfo.district"
>
v-distpicker>
div>
div>
<div class="mui-input-row">
<label>详细地址label>
<input
v-model="form.detail"
type="text"
class="mui-input-clear"
placeholder="请输入详细地址"
/>
div>
<div class="mui-button-row">
<button
size="small"
@click="save"
type="button"
class="mui-btn mui-btn-primary mui-btn-block"
>确认button>
div>
<div class="mui-button-row">
<button
size="small"
v-show="id"
@click="del"
type="button"
class="mui-btn mui-btn-danger mui-btn-block"
>删除button>
div>
form>
div>
template>
上述代码中,在template标签中,编写HTML结构代码,其中主要包括收件人姓名、联系方式、所在地区和详细地址等表单结构,使用.mui-input-group、.mui-input-row等类名实现表单结构的样式,而.mui-button-row设置“确认”按钮的样式,使用v-model指令分别将收件人姓名、联系方式、所在地区和详细地址与form表单对象绑定,并且给“确认”按钮绑定单击事件,当单击“确认”按钮时触发save事件处理函数,save()事件处理函数会在“保存收货地址”的内容中讲解。
(2)在src\pages\user\AddressEdit.vue文件中,编写逻辑代码,具体代码如下。
<script>
export default {
data() {
return {
form: {
name: '',
tel: '',
area: '',
detail: ''
},
show: false,
newInfo: {
province: '',
city: '',
area: ''
}
}
},
methods: {
save () {
window.console.log('确认')
}
}
}
</script>
上述代码中,在data中定义初始数据form对象,其中name表示收件人姓名、tel表示联系方式、area表示所在地区和detail表示详细地址。在methods中定义事件处理函数save,并在浏览器控制台打印“确认”。
(3)在src\pages\user\AddressEdit.vue文件中,编写CSS代码,具体代码如下。
v-distpicker V - Distpicker 是一个简单易用的地区选择器灵活的,高度可用的区域选择器,可用于选择中国的省,市和地区。下面通过v-distpicker实现所在地区填写功能模块。
(1)打开vue_shop项目目录,执行命令如下。
npm install v-distpicker@1.2 --save
上述命令中,使用npm包管理工具,install表示安装,[email protected]表示地区选择器安装包以及版本号为1.2,--save表示运行时需要的包。
(2)打开src\pages\user\AddressEdit.vue文件,导入v-distpicker,具体代码如下。
import VDistpicker from 'v-distpicker'
上述代码中,需要使用import…from…的方式,导入v-distpicker安装包,并命名为VDistpicker。
在src\pages\user\AddressEdit.vue文件,注册v-distpicker组件,具体代码如下。
export default {
……(原有代码)
components: {
'v-distpicker': VDistpicker
}
}
上述代码中,在components中,定义v-distpicker组件,组件名称为v-distpicker,其值为VDistpicker。
(3)在src\pages\user\AddressEdit.vue文件,编写逻辑代码,具体代码如下。
<label class="tit">所在地区label>
<input v-model="form.area" type="text" class="mui-input-clear" placeholder="所在地区" @click="choose">
<div class="divwrap">
<div class="mask" @click="choose" v-show="show">div>
<v-distpicker
v-show="show"
type="mobile"
@province="onChangeProvince"
@city="onChangeCity"
@area="onChangeArea"
:province="newInfo.province"
:city="newInfo.city"
:area="newInfo.district"
>
v-distpicker>
div>
上述代码中,给所在地区input表单元素绑定单击事件,当单击鼠标时触发事件处理函数choose,choose事件处理函数会在下面的代码中完成,定义类名为.divwrap 的div元素表示外层容器,在容器中定义.mask的div元素表示遮罩层,为遮罩层绑定单击事件,当单击鼠标也会触发choose事件处理函数,并且通过v-show指令控制遮罩层的显示和隐藏。
在页面中定义v-distpicker组件,并通过v-show指令绑定show属性控制组件的显示和隐藏,设置type的值为“mobile”表示适用移动端, 设置@province的值为onChangeProvince表示当省份选项发生变化时触发,同理,通过适用@city和@area监听城市和区的变化。
(4)在src\pages\user\AddressEdit.vue文件,定义初始数据,具体代码如下。
data () {
return {
……(原有代码)
show: false, // 是否显示遮罩层
newInfo: {
province: '', // 省
city: '', // 市
area: '', // 区
}
}
}
上述代码中,定义初始数据show,默认值为false,隐藏地区选择器组件,newInfo对象中province表示省份、city表示城市和area表示区。
(5)在src\pages\user\AddressEdit.vue文件,定义方法,具体代码如下。
methods: {
……(原有代码)
choose () {
this.show = !this.show
},
onChangeProvince (data) {
this.newInfo.province = data.value
},
onChangeCity (data) {
this.newInfo.city = data.value
},
onChangeArea (data) {
this.newInfo.area = data.value
this.form.area = this.newInfo.province + '-' + this.newInfo.city + '-' + this.newInfo.area
this.show = false
}
},
上述代码中,在methods中,定义choose事件处理函数,使show的值取非,当单击所在区域input表单元素时执行choose()事件处理函数,设置show的值为true,此时显示地区选择器和遮罩层,定义onChangeProvince()事件处理函数,当省份选项发生变化时,将变化后的值赋值给this.newInfo.province。同理,获取到城市和区,需要注意的是,在区获取完成之后,将数据以“省份-城市-区”的格式展示到所在地区中,最后隐藏地区选择器和遮罩层。
(6)在src\pages\user\AddressEdit.vue文件,编写CSS代码,具体代码如下。
.divwrap > .mask {
background: #000;
opacity: 0.3;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.divwrap > .distpicker-address-wrapper {
color: #999;
background: #fff;
border-top: 1px solid #ccc;
z-index: 1;
height: 300px;
overflow-y: auto;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
}
上述代码中,.divwrap > .mask设置遮罩层的样式,其中背景颜色为黑色,透明度为0.3,设置position的值为fixed表示固定定位,到顶部、底部、左侧和右侧的距离分别为0;.divwrap > .distpicker-address-wrapper设置地区选择器最外层容器样式,其中字体颜色为“#999”,背景颜色为白色,border-top设置顶部边框,z-index设置元素的层级,高度为300px,设置overflow-y的值表示如果溢出框,则应该提供滚动机制等。
在收货地址信息填写完毕之后,单击页面中的“确认”按钮,将数据保存下来,前面已经实现了页面结构,下面主要是通过代码实现保存收货地址的功能。
(1)打开src\pages\user\AddressEdit.vue文件,编写逻辑代码,具体代码如下。
save() {
this.$indicator.open({
text: '提交中'
})
this.form.id = this.id
this.$http.post('address/save', this.form).then((res) => {
this.$indicator.close()
if (res.data.code === 0) {
this.$toast(res.data.msg)
} else if (res.data.code === 1) {
this.$toast(res.data.msg)
this.$router.back()
} else if (res.data.code === 2) {
this.$router.push({ name: 'login' })
}
})
},
(2)在浏览器中,通过添加收货地址信息测试程序,运行结果如下。
在保存收货地址信息完成之后,那么,需要将保存的收货地址信息成功的渲染到页面中,下面通过通过代码实现显示收货地址信息页面效果。
(1)打开src\pages\user\Address.vue文件,编写逻辑代码,具体代码如下。
<script>
export default {
data() {
return {
addressList: [],
showAdd: false
}
},
created() {
this.getAddressList()
},
mounted() {},
methods: {
getAddressList() {
this.$indicator.open({ text: '加载中' })
this.$http.get('address').then((res) => {
this.$indicator.close()
this.showAdd = true
this.addressList = res.data.data // 将从后台得到的值赋给addressList
})
}
}
}
</script>
上述代码中,在data中定义addressList初始数据,主要用来保存收货地址信息列表。
(2)在src\pages\user\Address.vue文件中,编写结构代码展示收货地址信息列表,代码如下。
<div class="address-container">
<div>
<div class="mui-card" v-for="item in addressList" :key="item.id">
<ul class="selected">
<li class="title">
<strong>{{ item.name }}strong>
<strong>{{ item.tel }}strong>
li>
<li>{{ item.area }} {{ item.detail }}li>
<li>
<a class="edit">编辑a>
li>
ul>
div>
div>
……(原有代码)
div>
上述代码中,通过v-for指令实现列表渲染,其中item表示数组中的每一项,:key绑定每一项的id值,item.name表示收件人、item.tel表示联系方式、item.area表示所在地区和item.detail表示详细地址。
(3)在src\pages\user\Address.vue文件中,编写样式代码,具体代码如下。
.address {
background: #fff;
height: 100%;
overflow: hidden;
.jd {
min-height: 200px;
.address-info {
text-align: center;
line-height: 200px;
font-size: 14px;
color: #999;
}
}
.mod_btn {
font-size: 14px;
line-height: 44px;
width: 69%;
height: 44px;
text-align: center;
background: #006965;
flex: 1;
display: block;
color: #fff;
margin: 0 auto;
border-radius: 8px;
}
.mod_btn .fixed {
display: flex;
overflow: hidden;
}
.card {
padding: 15px;
position: relative;
overflow: hidden;
color: #666;
border-bottom: 1px solid #ececec;
.selected {
list-style: none;
margin: 0;
padding: 0;
padding-right: 50px;
font-size: 14px;
.title {
font-size: 15px;
span {
background-color: #ada9a9;
color: #fff;
padding: 2px 6px;
font-size: 12px;
margin-right: 5px;
border-radius: 3px;
}
}
.edit {
color: rgb(26, 26, 26);
width: 50px;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
}
}
}
}
上图中,已经成功展示了收货地址信息列表,但是,需要注意的是,由于新增按钮显示在收货地址列表的下面,在收货地址列表加载前后,“新增收货地址”按钮会发生上下跳动,这样会影响用户体验,那么,此时需要对程序进行细节优化,为了解决这个问题,可以在加载完成前,把按钮隐藏起来,直到加载完成后,再显示“新增收货地址”按钮。下面通过代码进行细节优化。
(5)打开src\pages\user\Address.vue文件,编写代码,具体代码如下。
this.$http.get('address').then(res => {
this.$indicator.close()
this.showAdd = true
……(原有代码)
})
上述代码中,在数据请求成功之后,修改this.showAdd的值为true。
(6)在src\pages\user\Address.vue文件中,定义初始数据showAdd,具体代码如下。
data () {
return {
addressList: [],
showAdd: false
}
},
上述代码中,定义初始数据的值为false,表示隐藏收货地址信息列表。
(7)打开src\pages\user\Address.vue文件,编写代码,具体代码如下。
<div v-show="showAdd" class="mod_btns fixed">
<router-link :to="{ name: 'address_add' }" class="mod_btn">新增收货地址router-link>
div>
上述代码中,通过v-show指令实现“新增收货地址”的显示和隐藏。只有当“收货地址”信息加载完成之后才显示“新增收货地址”按钮。因此,解决了“新增收货地址”按钮的上下跳动问题。
在实现了显示收货地址列表效果之后,当用户单击页面中的“编辑”按钮时,可以实现“收货地址”信息的修改。下面通过代码实现修改收货地址信息功能。
(1)打开src\pages\user\Address.vue文件,编写代码,具体代码如下。
<router-link class="edit" :to="{name: 'address_edit', params: {id: item.id}}">编辑router-link>
上述代码中 ,定义router-link标签,设置:to的值为“{name:'address_edit'}”表示当单击“编辑”时页面跳转到路由名称为“address_edit”的路由页面,并且传递当前编辑的收货地址信息的id值。
(2)打开src\router.js文件,配置routes路由,具体代码如下。
routes: [
……(原有代码)
{ path: '/user/address/edit/:id', component: AddressEdit, props: true, name: 'address_edit', meta: { title: '编辑收货地址' } },
],
上述代码中,商品收货地址的“编辑”和“新增收货地址”其实是复用了同一个组件“AddressEdit”,与“新增收货地址”不同的是,在“/user/address/edit/”路由地址后面,通过:id的方式获取到当前收货地址信息的id值,id是一个数字,表示待修改的记录的唯一标识。在组件里通过判断是否传入参数id来区分当前是修改还是新增。
(3)打开src\pages\user\AddressEdit.vue文件,接收一下路由传过来的id,具体代码如下。
props: ['id'],
created () {
this.getAddress()
},
methods: {
getAddress () {
if (!this.id) {
return
}
this.$indicator.open({
text: '加载中'
})
var params = { id: this.id }
this.$http.get('address/edit', { params: params }).then(res => {
this.$indicator.close()
window.console.log(res.data)
})
},
……(原有代码)
},
上述代码中,定义props属性的值为“['id']”用来接受id值,在created()生命周期函数中调用getAddress()事件处理函数,在methods中定义事件处理函数getAddress(),其中,判断this.id值是否存在,如果不存在就停止代码向下执行,如果this.id存在就展示“加载中”信息提示,定义params变量,其值为保存了当前收货地址信息的id值。然后请求后台接口地址“address/edit”,并且传递params对象参数。
(4)打开src\pages\user\AddressEdit.vue文件,编写代码,具体代码下。
this.$http.get('address/edit', { params: params }).then(res => {
this.$indicator.close()
if (res.data.code === 0) {
this.$toast(res.data.msg)
} else if (res.data.code === 1) {
this.form = res.data.data
} else if (res.data.code === 2) {
this.$router.push({ name: 'login' })
}
})
上述代码中,请求接口地址“address/edit”,并传递参数“{params:params}”,请求成功之后,关闭“加载中”信息提示,判断code值,如果code值为0,提示“获取失败”,如果code值为1,就将res.data.data的值赋值给this.form,如果code值为2,就跳转到登录页面。
(6)在src\pages\user\AddressEdit.vue文件中,编写代码,具体代码下。
save () {
this.$indicator.open({
text: '提交中'
})
this.form.id = this.id
……(原有代码)
}
上述代码中,修改save()方法,将当收货地址信息id值放入表单中。
(7)测试程序,观察修改是否会生效。
在实现我的收货地址功能模块时,除了显示收货地址、新增收货地址和编辑收货地址外,还有删除收货地址的功能,下面通过代码实现。
打开src\pages\user\AddressEdit.vue文件,编写HTML结构代码,具体代码如下。
<template>
<form class="mui-input-group">
……(原有代码)
<div class="mui-button-row">
……(原有代码)
<button v-show="id" @click="del" type="button" class="mui-btn mui-btn-danger mui-btn-block">删除button>
div>
form>
template>
上述代码中,v-show的作用是控制“删除”按钮的显示和隐藏,只有传入了id参数的时候,显示“删除”按钮。并且绑定单击事件,当当单击鼠标时,触发del()事件处理函数。
在methods中定义del()事件处理函数,具体代码如下。
methods: {
……(原有代码)
del () {
this.$indicator.open({
text: '删除中'
})
this.form.id = this.id
this.$http.post('address/del', this.form).then(res => {
this.$indicator.close()
window.console.log(res.data)
})
}
},
上述代码中,在del()中,首先实现“删除中”提示信息的功能,然后请求后台数据接口地址“address/del”,并且传递this.form表单对象,请求成功之后,关闭“删除中”信息提示功能,然后,在浏览器控制台打印返回的数据信息。
打开src\pages\user\AddressEdit.vue文件,处理服务器返回的结果,具体代码如下。
this.$http.post('address/del', this.form).then(res => {
this.$indicator.close()
if (res.data.code === 0) {
this.$toast(res.data.msg)
} else if (res.data.code === 1) {
this.$toast(res.data.msg)
this.$router.go(-1)
} else if (res.data.code === 2) {
this.$router.push({ name: 'login' })
}
})
上述代码中,请求成功之后,关闭“删除中”信息提示,判断code值,如果code值为0,提示“删除失败”,如果code值为1,就跳转到上一个页面,即“新增收货地址”页面,如果code值为2,就跳转到登录页面。