Commit 81dee50e by fanx

用户中心页面制作

1 parent 170f49ef
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<slot name="left" /> <slot name="left" />
</div> </div>
<!-- 左侧 默认 箭头以及文字描述 --> <!-- 左侧 默认 箭头以及文字描述 -->
<div class="nav_left" v-else @click="onBack"> <div class="nav_left" v-else @click="handleBack">
<i v-if="navObj.barLeftArrow" class="iconfont iconpreviewleft"></i> <i v-if="navObj.barLeftArrow" class="iconfont iconpreviewleft"></i>
{{navObj.barLeftText}} {{navObj.barLeftText}}
</div> </div>
...@@ -43,9 +43,12 @@ export default { ...@@ -43,9 +43,12 @@ export default {
title: { title: {
type: String type: String
}, },
showBack: {
type: Boolean,
default: false
},
onBack: { onBack: {
type: Function, type: Function,
default: () => false
} }
}, },
computed: { computed: {
...@@ -69,6 +72,15 @@ export default { ...@@ -69,6 +72,15 @@ export default {
} }
}, },
}, },
methods: {
handleBack() {
if (this.showBack) {
this.onBack()
} else {
this.$router.back()
}
}
}
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
...@@ -96,7 +108,7 @@ section { ...@@ -96,7 +108,7 @@ section {
:active { :active {
opacity: 0.5; opacity: 0.5;
} }
.iconpreviewleft{ .iconpreviewleft {
font-size: 50px; font-size: 50px;
} }
img { img {
......
...@@ -21,8 +21,12 @@ const router = new VueRouter({ ...@@ -21,8 +21,12 @@ const router = new VueRouter({
}) })
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
next() next()
}) })
// router后置守卫
router.afterEach((to, from) => {
})
export default router export default router
...@@ -20,6 +20,14 @@ const userRouter = [ ...@@ -20,6 +20,14 @@ const userRouter = [
}], }],
}, },
{ {
path: '/user/resetPassword',
name: 'ResetPassword',
meta: {
title: '重置密码'
},
component: () => import(/* webpackChunkName: "center" */ '@/views/user/resetPassword.vue') // 重置密码
},
{
path: '/user/center', path: '/user/center',
name: 'Center', name: 'Center',
meta: { meta: {
...@@ -36,12 +44,44 @@ const userRouter = [ ...@@ -36,12 +44,44 @@ const userRouter = [
component: () => import(/* webpackChunkName: "message" */ '@/views/user/message/list.vue') // 消息 component: () => import(/* webpackChunkName: "message" */ '@/views/user/message/list.vue') // 消息
}, },
{ {
path: '/user/collect',
name: 'Collect',
meta: {
title: '我的收藏'
},
component: () => import(/* webpackChunkName: "collect" */ '@/views/user/collect.vue') // 我的收藏
},
{
path: '/user/study', path: '/user/study',
name: 'Study', name: 'Study',
meta: { meta: {
title: '我的学习' title: '我的学习'
}, },
component: () => import(/* webpackChunkName: "study" */ '@/views/user/message/list.vue') // 消息 component: () => import(/* webpackChunkName: "study" */ '@/views/user/study.vue') // 我到学习
},
{
path: '/user/question',
name: 'Question',
meta: {
title: '常见问题'
},
component: () => import(/* webpackChunkName: "question" */ '@/views/user/question/list.vue') // 常见问题列表
},
{
path: '/user/questionDetail',
name: 'QuestionDetail',
meta: {
title: '常见问题'
},
component: () => import(/* webpackChunkName: "questionDetail" */ '@/views/user/question/detail.vue') // 常见问题详情
},
{
path: '/user/feedback',
name: 'FeedBack',
meta: {
title: '意见反馈'
},
component: () => import(/* webpackChunkName: "feedback" */ '@/views/user/feedback.vue') // 意见反馈
}, },
{ {
path: '/user/about', path: '/user/about',
...@@ -57,9 +97,24 @@ const userRouter = [ ...@@ -57,9 +97,24 @@ const userRouter = [
meta: { meta: {
title: '设置' title: '设置'
}, },
component: () => import(/* webpackChunkName: "setting" */ '@/views/setting/index.vue') // 设置 component: () => import(/* webpackChunkName: "setting" */ '@/views/user/setting/index.vue') // 设置
},
{
path: '/user/privacy',
name: 'Privacy',
meta: {
title: '隐私协议'
},
component: () => import(/* webpackChunkName: "privacy" */ '@/views/user/privacy.vue') // 隐私协议
},
{
path: '/user/service',
name: 'Service',
meta: {
title: '服务协议'
},
component: () => import(/* webpackChunkName: "service" */ '@/views/user/service.vue') // 服务协议
}, },
] ]
export default userRouter export default userRouter
\ No newline at end of file \ No newline at end of file
...@@ -3,18 +3,20 @@ import Vuex from 'vuex' ...@@ -3,18 +3,20 @@ import Vuex from 'vuex'
import VuexPersistence from 'vuex-persist' import VuexPersistence from 'vuex-persist'
import createLogger from 'vuex/dist/logger' import createLogger from 'vuex/dist/logger'
import home from './modules/home' import home from './modules/home'
import user from './modules/user'
// vuex 数据存储 进行本地存储操作 // vuex 数据存储 进行本地存储操作
const vuexLocal = new VuexPersistence({ const vuexLocal = new VuexPersistence({
storage: window.localStorage, storage: window.localStorage,
modules: ["home"] modules: ["user"]
}) })
Vue.use(Vuex) Vue.use(Vuex)
const store= new Vuex.Store({ const store = new Vuex.Store({
strict: process.env.NODE_ENV !== 'production', strict: process.env.NODE_ENV !== 'production',
modules: { modules: {
home home,
user
}, },
plugins: [vuexLocal.plugin, createLogger()] plugins: [vuexLocal.plugin, createLogger()]
}) })
......
export default {
namespaced: true,
state: {
userId: '1'
},
mutations: {
MStoreUserId(state, data) {
Object.assign(state, data)
},
},
actions: {
AStoreUserInfo({ commit }, userInfo) {
commit("MStoreUserId", userInfo)
}
},
getters: {
// 是否登录
GIsLogin(state) {
return state.userId ? true : false
}
}
}
import Vue from 'vue' import Vue from 'vue'
import { Loading, Lazyload, Tab, Tabs, Toast, Dialog, Icon, Field, Switch, Overlay } from 'vant' import { Loading, Lazyload, Tab, Tabs, Toast, Dialog, Icon, Field, Switch, Overlay, Cell, CellGroup, ActionSheet, Button } from 'vant'
import NafmHeader from '@/components/NafmHeader' import NafmHeader from '@/components/NafmHeader'
...@@ -7,7 +7,7 @@ import NafmHeader from '@/components/NafmHeader' ...@@ -7,7 +7,7 @@ import NafmHeader from '@/components/NafmHeader'
[NafmHeader].forEach(item => Vue.component(item.name, item)); [NafmHeader].forEach(item => Vue.component(item.name, item));
// 默认vant组件 // 默认vant组件
[Loading, Lazyload, Tab, Tabs, Toast, Dialog, Icon, Field, Switch, Overlay].forEach(item => Vue.use(item)) [Loading, Lazyload, Tab, Tabs, Toast, Dialog, Icon, Field, Switch, Overlay, Cell, CellGroup, ActionSheet, Button].forEach(item => Vue.use(item))
// 先预制,后期做统一调整 // 先预制,后期做统一调整
Object.assign(window, { Object.assign(window, {
......
<template>
<div class="setting_container">
<NafmHeader />
<div class="setting_list">
<div class="li">
<div class="menu_left">{{$t("setting.newMsgTip")}}</div>
<van-switch v-model="msgChecked" @click="changeMsgStatus" />
</div>
<div class="li">
<div class="menu_left">多语言</div>
<div class="menu_right" @click="popZhEn">
<div class="text">{{$t("lang")}}</div>
<div class="iconfont iconright"></div>
</div>
</div>
</div>
<van-overlay :show="showZhEn" z-index="10" @click="showZhEn = false">
<div class="footer">
<!-- <div class="btn"> -->
<div class="btn_zh item" @click="changeLang('zh')">中文</div>
<div class="btn_en item" @click="changeLang('en')">英文</div>
<div class="cancel item">取消</div>
<!-- </div> -->
</div>
</van-overlay>
</div>
</template>
<script>
import { setLocalStorage } from '@/utils/LocalStorage'
export default {
name: 'Setting',
data() {
return {
msgChecked: false,
showZhEn: false
}
},
mounted() {
this.msgChecked = true
},
methods: {
// 切换消息操作
changeMsgStatus() {
this.msgChecked = !this.msgChecked
},
// 弹出 设置中英文框
popZhEn() {
this.showZhEn = true
},
changeLang(val) {
console.log('val', val)
setLocalStorage('lang', val)
this.$i18n.locale = val
}
}
}
</script>
<style lang="less" scoped>
.setting_container {
background-color: #efefef;
height: 100vh;
}
.setting_list {
.li {
padding: 0 25px;
background-color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ccc;
height: 95px;
.menu_left {
color: #333;
display: flex;
justify-content: space-between;
align-items: center;
}
.menu_right {
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
.text {
color: #333;
}
.iconfont {
color: #ccc;
}
}
}
}
.footer {
position: fixed;
bottom: 20px;
display: flex;
width: 100%;
justify-content: center;
flex-direction: column;
align-items: center;
.item {
background-color: #fff;
height: 80px;
line-height: 80px;
width: 90%;
text-align: center;
}
.btn_zh {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
border-bottom: 1px solid #efefef;
}
.btn_en {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
margin-bottom: 10px;
}
.cancel {
border-radius: 10px;
}
}
</style>
\ No newline at end of file \ No newline at end of file
<template> <template>
<div> <div>
<NafmHeader/>
关于协会 关于协会
</div> </div>
</template> </template>
\ No newline at end of file \ No newline at end of file
...@@ -11,27 +11,35 @@ ...@@ -11,27 +11,35 @@
</div> </div>
</div> </div>
<div class="center_menu_list"> <div class="center_menu_list">
<router-link :to="item.url" class="li" v-for="(item,key) in menuList" :key="key"> <van-cell title="我的消息" center is-link to="/user/message" :icon="imgList.user" value-class="right_content">
<div class="menu_left"> <template #default>
<img :src="item.icon" alt="" /> <div class="dot" v-if="GIsLogin"></div>
<span>{{item.title}}</span> </template>
</div> </van-cell>
<div class="menu_right iconfont iconright"></div> <van-cell title="我的收藏" center is-link to="/user/collect" :icon="imgList.user" />
</router-link> <van-cell title="我的学习" center is-link @click="jumpStudyPage" :icon="imgList.user" value-class="right_content" />
<van-cell title="常见问题" center is-link to="/user/question" :icon="imgList.user" />
<van-cell title="意见反馈" center is-link to="/user/feedback" :icon="imgList.user" />
<van-cell title="关于协会" center is-link to="/user/about" :icon="imgList.user" value-class="right_content">
<template #default>
<div v-if="GIsLogin">版本2.1</div>
</template>
</van-cell>
<van-cell title="设置" center is-link to="/user/setting" :icon="imgList.user" />
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'
export default { export default {
name: 'Center', name: 'Center',
data() { data() {
return { return {
menuList: [ imgList: {
{ user: require('@/assets/icon/user_question.png')
icon: require('@/assets/icon/user_question.png'),
title: '我的消息',
url: '/user/message'
}, },
menuList: [
{ {
icon: require('@/assets/icon/user_question.png'), icon: require('@/assets/icon/user_question.png'),
title: '我的收藏', title: '我的收藏',
...@@ -64,11 +72,24 @@ export default { ...@@ -64,11 +72,24 @@ export default {
}, },
] ]
} }
},
methods: {
// 跳转到我到学习页面
jumpStudyPage() {
}
},
computed: {
...mapGetters('user', ['GIsLogin'])
} }
} }
</script> </script>
<style lang="less"> <style lang="less">
@import "~@/assets/css/variable.less"; @import "~@/assets/css/variable.less";
.user_center {
background-color: #fafafa;
height: 100vh;
}
.header { .header {
background: @theme; background: @theme;
padding: 60px 25px; padding: 60px 25px;
...@@ -94,27 +115,45 @@ export default { ...@@ -94,27 +115,45 @@ export default {
} }
} }
.center_menu_list { .center_menu_list {
padding: 0 25px; background-color: #fff;
.li { .right_content {
display: flex; display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ccc;
height: 95px;
.menu_left {
color: #333;
display: flex;
justify-content: space-between;
align-items: center; align-items: center;
img { justify-content: flex-end;
margin-right: 20px;
width: 35px;
height: 35px;
}
}
.menu_right {
color: #ccc;
} }
.dot {
width: 15px;
height: 15px;
background: #ff4038;
border-radius: 50%;
} }
} }
.van-cell:not(:last-child)::after {
right: 16px;
}
// .center_menu_list {
// padding: 0 25px;
// .li {
// display: flex;
// justify-content: space-between;
// align-items: center;
// border-bottom: 1px solid #ccc;
// height: 95px;
// .menu_left {
// color: #333;
// display: flex;
// justify-content: space-between;
// align-items: center;
// img {
// margin-right: 20px;
// width: 35px;
// height: 35px;
// }
// }
// .menu_right {
// color: #ccc;
// }
// }
// }
</style> </style>
\ No newline at end of file \ No newline at end of file
<template>
<div>
<NafmHeader/>
</div>
</template>
\ No newline at end of file \ No newline at end of file
<template>
<div>
<NafmHeader/>
建议反馈
</div>
</template>
\ No newline at end of file \ No newline at end of file
<template>
<div class="privacy_container">
<NafmHeader />
</div>
</template>
\ No newline at end of file \ No newline at end of file
<template>
<div class="question_detail">
<NafmHeader/>
</div>
</template>
\ No newline at end of file \ No newline at end of file
<template>
<div class="question_list">
<NafmHeader/>
</div>
</template>
\ No newline at end of file \ No newline at end of file
<template>
<div>
<NafmHeader />
</div>
</template>
\ No newline at end of file \ No newline at end of file
<template>
<div class="service_container">
<NafmHeader />
</div>
</template>
\ No newline at end of file \ No newline at end of file
<template>
<div class="setting_container">
<NafmHeader />
<div class="setting_list">
<van-cell :title="$t('setting.newMsgTip')" center value-class="right_content">
<template #default>
<van-switch v-model="msgChecked" @click="changeMsgStatus" size="20px" />
</template>
</van-cell>
<van-cell title="多语言" center is-link @click="controllZhEn(true)" value-class="right_content">
<template #default>
{{$t("lang")}}
</template>
</van-cell>
<van-cell title="微信绑定" center is-link @click="unbundling" value-class="right_content">
<template #default>
含笑一过
</template>
</van-cell>
<van-cell title="重置密码" center is-link @click="jumpResetPage" value-class="right_content" />
<van-cell title="指纹ID解锁" center value-class="right_content">
<template #default>
<van-switch v-model="fingerprintChecked" @click="changeFingerprintStatus" size="20px" />
</template>
</van-cell>
<van-cell title="面容ID解锁" center value-class="right_content">
<template #default>
<van-switch v-model="faceIdChecked" @click="changeFaceIdStatus" size="20px" />
</template>
</van-cell>
</div>
<div class="agreement_list">
<van-cell title="隐私协议" center is-link @click="jumpPrivacyPage" value-class="right_content" />
<van-cell title="服务协议" center is-link @click="jumpServicePage" value-class="right_content" />
</div>
<van-button type="primary" plain color="#a4a4a4" class="logout_btn">退出登录</van-button>
<van-action-sheet v-model="showZhEn" :actions="actions" cancel-text="取消" close-on-click-action @cancel="controllZhEn(false)" @select="changeLang" />
</div>
</template>
<script>
import { setLocalStorage } from '@/utils/LocalStorage'
export default {
name: 'Setting',
data() {
return {
msgChecked: false, //新消息提醒
showZhEn: false, // 弹出中英文设置
actions: [{ name: '中文', key: 'zh' }, { name: '英文', key: 'en' }], // 中英文切换选项
fingerprintChecked: false, // 指纹ID解锁状态
faceIdChecked: false, // 面容ID解锁状态
}
},
mounted() {
this.msgChecked = true
},
methods: {
// 切换消息操作
changeMsgStatus() {
this.msgChecked = !this.msgChecked
},
// 弹出/关闭 设置中英文框
controllZhEn(value) {
this.showZhEn = value
},
// 切换语言
changeLang(value) {
console.log('val', value.key)
setLocalStorage('lang', value.key)
this.$i18n.locale = value.key
},
// 解绑微信
unbundling() {
Dialog.confirm({
title: '友情提示',
message: '解除微信绑定后,将无法使用微信快速登录,你确定解除吗?',
cancelButtonText: '点错了',
// cancelButtonColor: '',
confirmButtonText: '确定解除',
// confirmButtonColor:''
})
.then(() => {
// on confirm 调取后端接口
Toast('解绑成功');
})
.catch(() => {
// on cancel
});
},
// 跳转到 重制密码页面
jumpResetPage() {
},
// 更改 指纹ID状态
changeFingerprintStatus() {
this.fingerprintChecked = !this.fingerprintChecked
},
// 更改 面容ID状态
changeFaceIdStatus() {
this.faceIdChecked = !this.faceIdChecked
},
// 跳转到隐私协议页面
jumpPrivacyPage() {
this.$router.push({
path: '/user/privacy'
})
},
// 跳转到服务协议页面
jumpServicePage() {
this.$router.push({
path: '/user/service'
})
},
}
}
</script>
<style lang="less" scoped>
.setting_container {
background-color: #efefef;
height: 100vh;
}
.van-cell:not(:last-child)::after {
right: 16px;
}
.right_content {
display: flex;
justify-content: flex-end;
align-items: center;
}
.agreement_list {
margin-top: 10px;
}
.logout_btn {
margin-top: 200px;
width: 100%;
border: 0;
}
</style>
\ No newline at end of file \ No newline at end of file
<template>
<div>
<NafmHeader/>
</div>
</template>
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!