• 用户的注册和微信授权
    • 1. 让微信用户打开首页后,直接跳转到后台服务器
    • 1.5 与后台的对接
    • 查看效果
    • 总结

    用户的注册和微信授权

    为了追求快速上线,项目组决定,去掉传统项目中的“用户注册”, “用户登录”, 直接使用微信的账户来核对。

    1. 用户的微信浏览器带着当前微信用户的open_id,跳转到“后台服务器”。
    2. “后台服务器” 给“微信服务器” 发送请求。 获得当前微信用户的信息
    3. “后台服务器” 为该用户生成一个用户文件
    4. “后台服务器” 告知“H5端” 已经成功注册该用户。
    5. “H5端” 为该用户展示对应的页面。

    如下图所示:

    用户注册过程

    可以看出, 主要代码都是在 服务器端。

    1. 让微信用户打开首页后,直接跳转到后台服务器

    1.1 修改对应的路由文件(src/router/index.js):

    1. Vue.use(Router)
    2. export default new Router({
    3. routes: [
    4. {
    5. path: '/wait_to_shouquan',
    6. name: 'wait_to_shouquan',
    7. component: require('../views/wait_to_shouquan.vue')
    8. },
    9. ]
    10. })

    1.2 增加对应的vue(src/views/wait_to_shouquan.vue) :

    1. <template>
    2. <div style="padding: 50px;">
    3. <h3>正在跳转到授权界面...</h3>
    4. </div>
    5. </template>
    6. <script>
    7. export default {
    8. created () {
    9. window.location.href = this.$store.state.web_share + "/auth/wechat"
    10. },
    11. components: {
    12. }
    13. }
    14. </script>

    可以看到, 上面的代码中, 使用到了 Vuex 来保存系统变量(后台服务器的地址) .

    1.3 增加核心模板文件(src/main.vue) :

    1. <template>
    2. <div id="app">
    3. <router-view></router-view>
    4. </div>
    5. </template>
    6. <script>
    7. import store from './vuex/store'
    8. import { SET_BASEINFO, GET_BASEINFO } from './vuex/mutation_types'
    9. export default {
    10. store,
    11. name: 'app',
    12. data () {
    13. return {
    14. user_info: {
    15. open_id: this.$route.query.open_id
    16. }
    17. }
    18. },
    19. mounted () {
    20. // TODO 开发环境下使用, 生产环境下注释掉
    21. // store.dispatch(SET_BASEINFO, {open_id: 'opFELv6YkJkMaH-xFkokTWCs5AlQ'})
    22. if (this.user_info.open_id) {
    23. store.dispatch(SET_BASEINFO, this.user_info)
    24. } else {
    25. store.dispatch(SET_BASEINFO)
    26. if (store.state.userInfo.open_id === undefined) {
    27. console.info('用户id和open_id不存在, 跳转到授权等待页面')
    28. this.$router.push({name: 'wait_to_shouquan'})
    29. } else {
    30. console.info('已经有了BASEINFO')
    31. }
    32. }
    33. },
    34. watch: {
    35. '$route' (val) {
    36. }
    37. },
    38. methods: {
    39. },
    40. components:{
    41. }
    42. }
    43. </script>
    44. <!-- 下方的 CSS 略过 -->

    可以看到, 上面代码的 mounted() 方法中, 会对 当前用户的open_id 进行判断. 如果存在,调到首页。 如果不存在,表示该用户是新用户。 需要跳转到授权等待页面。对应的代码如下所示:

    1. if (this.user_info.open_id) {
    2. store.dispatch(SET_BASEINFO, this.user_info)
    3. } else {
    4. store.dispatch(SET_BASEINFO)
    5. if (store.state.userInfo.open_id === undefined) {
    6. console.info('用户id和open_id不存在, 跳转到授权等待页面')
    7. this.$router.push({name: 'wait_to_shouquan'})
    8. } else {
    9. console.info('已经有了BASEINFO')
    10. }
    11. }

    1.4 增加对应的Vuex代码

    目前来看, Vuex需要保存2个信息:

    • 用户的open id
    • 远程服务器的地址,端口等常量.

    1.4.1 增加 src/vuex/store.js . 这个是最最核心的文件。 完整如下所示:

    1. import Vue from 'vue'
    2. import Vuex from 'vuex'
    3. import userInfo from './modules/user_info'
    4. import tabbar from './modules/tabbar'
    5. import toast from './modules/toast'
    6. import countdown from './modules/countdown'
    7. import products from './modules/products'
    8. import shopping_car from './modules/shopping_car'
    9. import * as actions from './actions'
    10. import * as getters from './getters'
    11. Vue.use(Vuex)
    12. Vue.config.debug = true
    13. const debug = process.env.NODE_ENV !== 'production'
    14. export default new Vuex.Store({
    15. state: {
    16. web_share: 'http://shopweb.siwei.me',
    17. h5_share: 'http://shoph5.siwei.me/?#'
    18. },
    19. actions,
    20. getters,
    21. modules: {
    22. products,
    23. shopping_car,
    24. userInfo,
    25. tabbar,
    26. toast,
    27. countdown
    28. },
    29. strict: debug,
    30. middlewares: debug ? [] : []
    31. })

    上面的代码中, 部分代码是在后面会陆续用到的。 我们不用过多考虑。 只需要关注下面几行:

    1. export default new Vuex.Store({
    2. // 这里定义了若干系统常量
    3. state: {
    4. web_share: 'http://shopweb.siwei.me',
    5. h5_share: 'http://shoph5.siwei.me/?#'
    6. },
    7. modules: {
    8. // 这里定义了 当前用户的各种信息, 我们把它封装成为一个js对象
    9. userInfo,
    10. },
    11. })

    1.4.2 增加vuex/modules/user_info.js 这个文件:

    1. import {
    2. SET_BASEINFO,
    3. CLEAR_BASEINFO,
    4. GET_BASEINFO,
    5. COMMEN_ROLE,
    6. GET_BGCOLOR,
    7. GET_FONTCOLOR,
    8. GET_BORDERCOLOR,
    9. GET_ACTIVECOLOR,
    10. EXCHANGE_ROLE
    11. } from '../mutation_types'
    12. const state = {
    13. id: undefined, //用户id
    14. open_id: undefined, // 用户open_id
    15. role: undefined
    16. }
    17. const mutations = {
    18. //设置用户个人信息
    19. [SET_BASEINFO] (state, data) {
    20. try {
    21. state.id = data.id
    22. state.open_id = data.open_id
    23. state.role = data.role
    24. } catch (err) {
    25. console.log(err)
    26. }
    27. },
    28. //注销用户操作
    29. [CLEAR_BASEINFO] (state) {
    30. console.info('清理缓存')
    31. window.localStorage.clear()
    32. },
    33. }
    34. const getters = {
    35. [GET_BASEINFO]: state => {
    36. console.info('进入到了getter中了')
    37. let localStorage = window.localStorage
    38. let user_info
    39. if (localStorage.getItem('SLLG_BASEINFO')) {
    40. console.info('有数据')
    41. user_info = JSON.parse(localStorage.getItem('SLLG_BASEINFO'))
    42. } else {
    43. console.info('没有数据')
    44. }
    45. return user_info
    46. },
    47. [COMMEN_ROLE]: state => {
    48. if (state.role === 'yonghu') {
    49. return true
    50. } else {
    51. return false
    52. }
    53. },
    54. }
    55. const actions = {
    56. [SET_BASEINFO] ({ commit, state }, data) {
    57. //保存信息
    58. if (data !== undefined) {
    59. let localStorage = window.localStorage
    60. localStorage.setItem('BASEINFO', JSON.stringify(data))
    61. commit(SET_BASEINFO, data)
    62. } else {
    63. if (localStorage.getItem('BASEINFO')) {
    64. data = JSON.parse(localStorage.getItem('BASEINFO'))
    65. commit(SET_BASEINFO, data)
    66. } else {
    67. }
    68. }
    69. }
    70. }
    71. export default {
    72. state,
    73. mutations,
    74. actions,
    75. getters
    76. }

    该文件定义了用户的信息的各种属性。

    1.4.3 增加 src/vuex/mutation_types.js

    1. export const SET_BASEINFO = 'SET_BASEINFO'
    2. export const GET_BASEINFO = 'GET_BASEINFO'

    上面内容定义了该对象的两个操作。

    1.4.4 增加 src/vuex/modules/actions.js

    1. import * as types from './mutation_types'

    可以看到上面的内容对于 mutation_types 进行了引用。

    1.4.5 增加 src/vuex/modules/getters.js

    1. // 先放成空内容好了

    这个文件先这样存在,目前阶段不需要有任何内容。

    1.5 与后台的对接

    后台的同学, 为我们提供了一个链接入口:

    http://shopweb.siwei.me/auth/wechat

    我们让H5页面直接跳转过去就可以。 这里不需要加任何参数, 直接由后端的同学搞定接下来的事情。

    查看效果

    在微信开发者工具中,打开我们的H5 页面, 就会看到页面会自动跳转.

    观察仔细的同学可以看到有两次跳转:

    第一次跳转到 http://shopweb.siwei.me/auth/wechat第二次跳转到 https://open.weixin.qq.com/connect/oauth2/authorize…

    如下图所示:

    微信授权页面

    点击“确认登录”按钮,进行授权后,就会进入到H5的首页

    总结

    本节中,为了做一件事: 让用户跳转到微信授权,并注册, 我们做了如下的程序层面的内容:

    • 使用Vuex 记录系统常量(远程服务器的地址)
    • 使用Vuex 记录用户的信息(新增了一个对象:user_info)
    • 使用了一个独立的页面(等待微信授权页面)
    • 每次打开首页之前,都要判断该用户是否登录。
    • (后台任务) 让该用户在微信端授权, 并且在本地生成一个新的用户, 然后把相关数据返回给前端

    Vuex 是Vuejs 最复杂最不好理解的地方。 同学们不要怕。 之所以这么麻烦, 可以认为是javascript的语言特性决定的。 就好像java, C语言中大量用到的设计模式, 在现代编程语言(Ruby , Python, Perl)中就用不到, 可以有更加简单的办法, 例如Mixin)

    另外,本节对于后端的同学是个挑战, 不但要在微信端做修改,还需要对微信返回的数据结构很熟悉。 由于本书内容所限,不再赘述。