vue+vue-router+vuex地址管理思路
栏目: JavaScript · 发布时间: 6年前
内容简介:如何精简页面目录,在实现功能要求的同时,提高页面可维护性成为前端发展趋势。收货地址管理是电商交易必不可少模块,本篇我将通过实现地址管理的部分功能分享下构建思路。本篇会涉及到:es6、vuejs、vue-router、vuex基础知识,在讲解思路过程中,我会穿插说明,但是还是希望读者对相关知识有些了解。
一、场景描述
如何精简页面目录,在实现功能要求的同时,提高页面可维护性成为前端发展趋势。收货地址管理是电商交易必不可少模块,本篇我将通过实现地址管理的部分功能分享下构建思路。
本篇会涉及到:es6、vuejs、vue-router、vuex基础知识,在讲解思路过程中,我会穿插说明,但是还是希望读者对相关知识有些了解。
实现功能:
1、个人中心与订单确认页均可以进入地址列表页; 2、个人中心进入地址列表页,点击地址列表中地址进入地址编辑页,并带出地址相关信息; 3、订单确认页进入地址列页,点击地址列表中地址,选中地址并返回到订单确认页,并带出选中地址信息;
二、实现功能图解
三、解决该问题思路及代码
注:该篇思路分析项目Demo是使用vue-cli 3.x版本搭建。
1、Demo目录
- 在组件库中创建了appHeader.vue,用于头部的名称展示。
- “页面”库中新建了四个“页面”Home.vue(个人中心)、OrderConfirm.vue(订单确认)、AddressList.vue(地址列表)、AddressEdit.vue(地址编辑)。项目初始化时的“页面”About.vue删除。
- App.vue中路由链接改造,会在后边页面介绍中说明。
- 路由文件:Demo创建中,路由数量有限,且主要目的在功能实现,因此本次路由信息均放在了router.js文件中。
- 状态管理器:同路由文件类似,我们将状态、方法均放在store.js文件中。
2、路由匹配
在router.js文件中匹配好所有的路由信息,将本次Demo演示的四个页面的路由信息均匹配好。
import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' import OrderConfirm from './views/OrderConfirm.vue' import AddressList from './views/AddressList.vue' import AddressEdit from './views/AddressEdit.vue' Vue.use(Router) export default new Router({ routes: [{ path: '/', name: 'home', component: Home }, { path: '/orderConfirm', name: 'orderConfirm', component: OrderConfirm }, { path: '/addressList', name: 'addressList', component: AddressList }, { path: '/addressEdit', name: 'addressEdit', component: AddressEdit } ] })复制代码
3、“页面”创建及对应路由与状态管理说明
App.vue:初始化时的页面,系统入口。此处做了点修改:template内容中路由链接信息。
<template> <div id="app"> <div id="nav"> <router-link to="/">Home</router-link> || <router-link to="/orderConfirm">OrderConfirm</router-link> </div> <router-view /> </div> </template>复制代码
Home.vue:个人中心页,作为编辑地址列表的入口。
<template> <div class="home"> <router-link to='/addressList'>管理地址</router-link> </div> </template> <style scoped> a { text-decoration: none; color: black; } </style>复制代码
说明:
- Home页面在本次项目Demo就是一个链接跳转的路径,仅仅使用了我们在
router.js
中设置的地址列表路由/addressList
。
store.js:状态管理文件,为方便下边“页面”说明,提前将文件内容贴出来,后续涉及到时会进行简要说明。
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { addressList: [{ id: 1, username: "小明", phone: '15612345678', addressDetail: "某某省 某某市 某某区 110" }, { id: 2, username: "小红", phone: '13812345678', addressDetail: "某某省 某某市 某某区 110" }, { id: 3, username: "小花", phone: '18612345678', addressDetail: "某某省 某某市 某某区 110" } ] }, getters: { getAddress: (state, getters) => (id) => { return state.addressList.find(address => address.id === id) } }, mutations: { addAddress(state, address) { return state.addressList.push(address) } } })复制代码
OrderConfirm.vue:订单确认页,是选择收货地址入口,正是由于存在跟Home两个入口, AddressList.vue
中地址列表对于地址进行同一个操作,存在不同的反馈。
<template> <div> <router-link to='/addressList'> <div v-if='isAddress' class="address"> <div><span>姓名:{{username}}</span></div> <div><span>电话:{{phone}}</span></div> <div><span>地址:{{addressDetail}}</span></div> </div> <div v-else> <span>选择地址</span> </div> </router-link> </div> </template> <script> export default { name: "orderConfirm", data() { return { isAddress: false, username: "", phone: "", addressDetail: "" } }, created() { if (this.$route.query.id) { let userAddress = this.$store.getters.getAddress(this.$route.query.id) this.isAddress = true this.username = userAddress.username; this.phone = userAddress.phone; this.addressDetail = userAddress.addressDetail; } } } </script> <style> a { text-decoration: none; color: black; } .address { text-align: left; margin-left: 20PX; } </style>复制代码
说明:
- 使用
isAddress
确认是否有地址,默认为false
。当地址不存在时,显示为“选择地址”,当地址存在时,或者选择地址后,显示选中地址信息。 -
this.$route.query.id
是vue-router中query
参数,该使用是组件中获取参数query.id
方式,通过这个字段值去判断是否存在地址信息。如果存在显示地址信息,并设置isAddress
为true
,如果不存在则显示为选择地址。 -
getters
是vuex中计算属性,类似于vue中的computed
,我们可以通过getters获取vuex经过“计算”的数据。 - 视角转向store.js文件,
getters
中使用es6
的箭头函数,通过输入值,获取state中经过“计算”的数据。 -
this.$store.getters.getAddress(this.$route.query.id)
是为获取vuex中传参的getters数据。在返回选中地址时,通过向getters
传递this.$route.query.id
获取选中的数据,将返回结果赋值到初始设置字段即可。
AddressList.vue:地址列表页。该页面需要通过判别路由后初始化页面。
<template> <div> <app-header headTitle="地址列表"></app-header> <ul> <li v-for="address in addressList" :key="address.id"> <router-link :id='address.id' :to="{path:url,query:{id:address.id}}"> <div> <div> <span>姓名:{{address.username}}</span> </div> <div> <span>电话:{{address.phone}}</span> </div> <div> <span>地址:{{address.addressDetail}}</span> </div> </div> </router-link> </li> </ul> <div> <router-link to='/addressEdit'><button>新增地址</button></router-link> </div> </div> </template> <script> import appHeader from '@/components/appHeader.vue' import { mapState } from 'vuex' export default { name: "addressList", components: { appHeader: appHeader, }, data() { return { url: "" } }, computed: { ...mapState(["addressList"]) }, beforeRouteEnter(to, from, next) { if (from.name == 'orderConfirm') { next(vm => { vm.url = "/orderConfirm" }) } else { next(vm => { vm.url = "/addressEdit" }) } } } </script> <style scoped> ul li { list-style: none; text-align: left; margin-bottom: 10px; padding: 20px; } ul li:nth-child(even) { background-color: lightgrey; } a { text-decoration: none; color: black; } button { outline: none; border: none; width: 100px; height: 40px; border-radius: 10px; background-color: green; color: white; } </style>复制代码
说明:
- 页面初始化时,地址列表通过vuex辅助函数
mapState
获取state中地址列表数据,并通过v-for
指令进行列表渲染。 - 该页面进行初始渲染的关键是获取路由导航来源,通过组件内路由导航守卫
beforeRouteEnter
实现,因为无法获取组件实例this
,因此在next
方法中进行实例获取。 - 动态绑定
url
,可根据路由导航来源决定导航跳转去向,另外在url
中动态绑定query
参数。 - 在跳转过程中,带着
query.id
参数,即在本次Demo中很多‘页面’中均存在this.$route.query.id
验证。 - 另外,本页中使用了组件
app-header
,对于页面头进行简单设计。 - 最后,在页面底部添加了一个新增地址按钮,是为在演示如何在一个页面实现新增与修改地址功能。
appHeader.vue:头部样式组件,用在了地址列表页面和地址编辑页面。
<template> <div class='header'> <span>{{headTitle}}</span> </div> </template> <script> export default { name: "appHeader", props: ['headTitle'], } </script> <style> .header { width: 100%; height: 60px; text-align: center; color: white; background-color: lightblue; font-size: 20px; line-height: 60px; } </style>复制代码
说明:
- 这个组件没有太多难点,仅仅涉及到
props
的使用。
AddressEdit.vue:地址编辑页面。
<template> <div> <appHeader :headTitle="addressEdit"></appHeader> <div class='name'> <span>姓名:</span><input type="text" v-model='username'> </div> <div class='phone'> <span>电话:</span><input type="text" v-model='phone'> </div> <div class='addressDetail'> <span>地址:</span><input type="text" v-model='addressDetail'> </div> <router-link to='/addressList'><button @click='editAddress'>提交</button></router-link> </div> </template> <script> import appHeader from '@/components/appHeader.vue' import { mapGetters } from 'vuex' export default { name: "addressEdit", data() { return { addressEdit: "", username: '', phone: '', addressDetail: '' } }, components: { appHeader: appHeader }, computed: { useraddress() { return this.$store.getters.getAddress(this.$route.query.id) } }, methods: { editAddress() { let length = this.$store.state.addressList.length let address = {} address.id = length + 1 address.username = this.username address.phone = this.phone address.addressDetail = this.addressDetail this.$store.commit("addAddress", address) } }, created() { this.$route.query.id ? this.addressEdit = '编辑地址' : this.addressEdit = '新增地址'; if (this.$route.query.id) { let userAddress = this.$store.getters.getAddress(this.$route.query.id) this.username = userAddress.username || ''; this.phone = userAddress.phone || ''; this.addressDetail = userAddress.addressDetail || ''; } } } </script> <style> input { border: 1px solid lightblue; outline: none; width: 300px; height: 30px; border-radius: 5px; } .name { margin-top: 10px; } .phone { margin: 10px 0; } button { margin-top: 20px; outline: none; border: none; width: 100px; height: 40px; border-radius: 10px; background-color: green; color: white; } </style>复制代码
说明:
- 头部组件
app-header
中props
动态赋值,点击新增地址按钮,进入地址编辑页,页面头部展示“新增地址”,点击地址列表中地址,进入地址编辑页,页面头部展示为“编辑地址”。 - 地址修改时,对于输入框内容根据
this.$route.query.id
从vuex中getters
赋值并展示。 -
mutations
方法类似vue中methods
。 - 信息填写完毕后,通过
mutations
方法向vuex中state中值进行修改。在组件中methods中通过this.$store.commit("addAddress", address)
提交到mutations。 - 注意 : 在本次的Demo展示中,我针对地址修改与新增,均向state中地址列表中新增地址,另外,我们不同入口进行地址列表页面时,新增地址提交返回路径地址也应该不一样, 有兴趣的同学们可以尝试修改的方法。 鉴于是个本地展示,本次展示数据修使用的mutations,真正与后台交互中,建议使用
actions
.
四、写在后面
实际我们在做产品时,涉及到用户体验的东西很多,比如页面样式、默认地址、输入验证、验证提示、地址级联选择等等,作为一个功能实现,暂不予考虑。
以上是作为一名喜欢前端技术的产品经理实现该功能的思路及方法,相信大神们会有更简洁便利的方式。
最后,针对文中有不对的地方,或者可以再优化的点,请多多指教。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 从 dubbo zookeeper 注册地址提取 zookeeper 地址
- 以太坊中如何判断一个地址为合约账户地址
- 高性能服务器架构思路,不仅是思路
- Holer 1.1.0 发布,支持在线修改内网地址和邮箱地址
- ipv6中fe80开头的ip地址是什么类型的地址
- 闲谈IPv6-IPv6地址聚类分配原则于源地址选择的关系
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。