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地址聚类分配原则于源地址选择的关系
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
RESTful Web Services Cookbook
Subbu Allamaraju / Yahoo Press / 2010-3-11 / USD 39.99
While the REST design philosophy has captured the imagination of web and enterprise developers alike, using this approach to develop real web services is no picnic. This cookbook includes more than 10......一起来看看 《RESTful Web Services Cookbook》 这本书的介绍吧!