演示地址:ECNU-2022Spring-DatabaseTermProject第四组_哔哩哔哩_bilibili

关于登录信息、权限显示

这里利用sessionStorage将用户的信息跟权限(理论上应该一起作为user信息返回的,这里分开存储。后续页面左侧Aside的访问也可以根据存储的sessionStorage解决。

*sessionStorage 属性允许你访问一个 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。**在新标签或窗口打开一个页面时会在顶级浏览上下文中初始化一个新的会话,*这点和 session cookies 的运行方式不同。

request.post("/api/login", this.form).then(res => {
console.log(res)
  if (res.code === 0) {
console.log(3333)
    this.$message({
      type: "success",
      message: "登录成功"
    })
sessionStorage.setItem("user",JSON.stringify(res.data))  // 缓存用户信息
request.post("/api/permission?user_id=" + res.data.user_id).then(res1 => {
console.log(res1)
console.log("permission Get")
sessionStorage.setItem("userPermission",JSON.stringify(res1))  // 缓存用户信息
      let userStrr =sessionStorage.getItem("userPermission") || "{}"
      this.permissionList =JSON.parse(userStrr)
      activeRouter()
      this.$router.push("/")  //登录成功之后进行页面的跳转,跳转到主页
    })

    // 登录成功的时候更新当前路由
    //activeRouter()

  } else  {
    this.$message({
      type: "error",
      message: res.msg
    })
  }
})

关于路由配置

需要避免任何用户都能通过改url的方式访问对应页面,因此考虑如果此用户没有访问该页面的权限,便不进行路由加载。采取循环的方式进行路由注册。(addRoute)

同时采用foreach的方式进行权限控制。

非常简洁的写法

function activeRouter() {
    const userStr =sessionStorage.getItem("userPermission")
    if (userStr) {
        const userPermission =JSON.parse(userStr)
        let root = {
            path: '/',
            name: 'Layout',
						component:Layout,
            redirect: "/home",
            children: []
        }
        userPermission.forEach(p => {
            let obj = {
                path: p.path,
                name: p.name,
                component: () => import("@/views/" + p.name)
            };
            root.children.push(obj)
        })
        if (router) {
					router.addRoute(root)
        }
    }
}

router.beforeEach((to, from, next) => {
    if (to.path === '/login' || to.path === '/register') {
        next()
        return
    }
    let userPermission = sessionStorage.getItem("userPermission") ? JSON.parse(sessionStorage.getItem("userPermission")) : {}
    if (!userPermission || !userPermission.length) {
        next('/login')
    } else if (!userPermission.find(p => p.path === to.path)) {
        next('/login')
    } else {
        next()
    }
})

关于前端分页

这里利用了elementUi,因此分页操作非常简洁,只需要修改:data取值,利用js的slice函数。(之前傻乎乎写了一堆..)。

(不建议前端分页。没有意义。)

<el-table
    v-loading="loading"
    :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)"
    border
    stripe
    style="width: 100%">
  <el-table-column
      prop="user_id"
      label="ID"
      sortable
  >

关于清空表单

简便写法,清空this.form

this.form={brand_right:0}

关于评论加载

在评论后按发表回复时需要页面实时刷新,但是又不能采用直接刷新整个页面的方式,找到了这样一种很巧妙的写法

首先在app.vue里注册reload方法

<template>
  <div id="app" class = "body"></div>
  <el-config-provider :locale="locale">
    <router-view v-if="isRouterAlive"></router-view>
  </el-config-provider>
</template>

export default {
  name: "App",
  provide(){
    return {
      reload: this.reload
    }
  },
  components: {
    [ElConfigProvider.name]:ElConfigProvider,
  },
  data() {
    return {
      isRouterAlive:true,
locale:zhCn,
    }
  },
  methods:{
    reload(){
      this.isRouterAlive = false
      this.$nextTick(function (){
        this.isRouterAlive = true
      })
    }
  }
}

在需要用到的地方引入inject:

export default {
  name:'Comment',
  props:{
    paperid: Number
  },
  inject:['reload']
}

关于Vuex:

什么时候用vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

说白了就是管理组件间通信,可以把信息全局存储,不用在两个组件间传来传去。

用登录,记录用户相关信息做演示(其实这个场景并不适用,因为vuex是响应式的,刷新一下就没了。尝试的时候没太意识到)

export default createStore({
  state: {
    user: {}
  },
  mutations: {
    SET_USER(state, user) {
      state.user = user
			console.log("set_user in mutation:")
			console.log(user)
    }
  },
  actions: {
    SET_USER(context,user) {
			console.log("set_user in actions:")
      context.commit('SET_USER',user)
    }
  },
  getters: {
    getUser(state){
      return state.user
    },
    printUsername(state){
			console.log("print through getters")
			console.log(state.user.username)
    },
  }
})

用state存储状态

登录时触发:

this.$store.state.user = res
this.$store.commit('SET_USER',res.data)
this.$store.dispatch('SET_USER',res.data)

第一行直接赋值,第二行采用函数调用mutation方法。第三行调用getters方法(mutation的异步)

对比本地存储和会话存储:

1.区别:vuex存储在内存,localstorage(本地存储)则以文件的方式存储在本地,永久保存(不主动删除,则一直存在);sessionstorage( 会话存储 ) ,临时保存。localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理

2.应用场景:vuex(响应式的)用于组件之间的传值,localstorage,sessionstorage则主要用于不同页面之间的传值。(非响应式的,页面刷新才会更新)

3.永久性:当刷新页面(这里的刷新页面指的是 –> F5刷新,属于清除内存了)时vuex存储的值会丢失。localstorage、sessionstorage,不受页面刷新影响而存储数据的俩种方式。sessionstorage页面关闭后就清除掉了,localstorage不会。

JSON与字符串的相关处理:

JSON 是序列化的对象或数组,它是 JS 对象的字符串表示方法,也就是说,JSON本质上是一个字符串。JSON以键值对 (key, value) 的形式存在,其中:

JSON的 key 必须用 "" (双引号)包起来 JSON的 value 不可以为 function/undifined/NaN 数据结尾不允许出现无意义的 , JS 对象

对比而言,JS对象没有以上三条,也是与 JSON 最大的不同。

JSON 与 JS 对象的转换

从 JSON 转为 JS 对象:使用 JSON.parse() 方法 从 JS 对象转为 JSON:使用 JSON.stringify() 方法 应用场景

JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,传递这串字符串比传递一大组数据轻松得多,在需要的时候再将它还原为支持的数据格式。

写在最后:

是之前数据库大作业的项目。这门课是我认为华师大大二下唯一有用的一门课。主要负责了前端部分。当时是22年六月做完的,现在基本上很多都忘光了…最近想找实习所以干脆拿出之前随便整理的一些内容放上来好了。整个过程比较满意的地方是对项目需求进行了比较完备的分析和实现。花时间比较多的地方在于多级评论加删除的部分,那部分实现的比较满意(虽然现在基本上全忘了…)剩下一半时间都在调试接口+debug。 演示地址: