如何精簡頁面目錄,在實現功能要求的同時,提升頁面可維護性成爲前端發展趨勢。收貨地址管理是電商交易必不可少模塊,本篇我將經過實現地址管理的部分功能分享下構建思路。
前端
本篇會涉及到:es六、vuejs、vue-router、vuex基礎知識,在講解思路過程當中,我會穿插說明,可是仍是但願讀者對相關知識有些瞭解。
vue
一、我的中心與訂單確認頁都可以進入地址列表頁;
es6二、我的中心進入地址列表頁,點擊地址列表中地址進入地址編輯頁,並帶出地址相關信息;
vue-router三、訂單確認頁進入地址列頁,點擊地址列表中地址,選中地址並返回到訂單確認頁,並帶出選中地址信息;
vuex
注:該篇思路分析項目Demo是使用vue-cli 3.x版本搭建。
vue-cli
在router.js文件中匹配好全部的路由信息,將本次Demo演示的四個頁面的路由信息均匹配好。bash
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
}
]
})複製代碼
App.vue:初始化時的頁面,系統入口。此處作了點修改:template內容中路由連接信息。app
<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>複製代碼
說明:
router.js
中設置的地址列表路由/addressList
。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通過「計算」的數據。getters
中使用es6
的箭頭函數,經過輸入值,獲取state中通過「計算」的數據。this.$store.getters.getAddress(this.$route.query.id)
是爲獲取vuex中傳參的getters數據。在返回選中地址時,經過向getters
傳遞this.$route.query.id
獲取選中的數據,將返回結果賦值到初始設置字段便可。<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>複製代碼
說明:
mapState
獲取state中地址列表數據,並經過v-for
指令進行列表渲染。beforeRouteEnter
實現,由於沒法獲取組件實例this
,所以在next
方法中進行實例獲取。url
,可根據路由導航來源決定導航跳轉去向,另外在url
中動態綁定query
參數。query.id
參數,即在本次Demo中不少‘頁面’中均存在this.$route.query.id
驗證。app-header
,對於頁面頭進行簡單設計。<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
的使用。<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。actions
.實際咱們在作產品時,涉及到用戶體驗的東西不少,好比頁面樣式、默認地址、輸入驗證、驗證提示、地址級聯選擇等等,做爲一個功能實現,暫不予考慮。
以上是做爲一名喜歡前端技術的產品經理實現該功能的思路及方法,相信大神們會有更簡潔便利的方式。
最後,針對文中有不對的地方,或者能夠再優化的點,請多多指教。