Vue2.X复盘

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

使用vue也一年多了,这是对之前的一次复盘,内容没有官方文档详细,对于vue大概也只是停留在使用的阶段,对于源码也没有过多的关注(这也是之后需要提升的),本文的内容可能存在很多的不足之处,希望大佬们可以帮忙指正,让我可以完善一下。真的是提笔容易下笔难,复盘感觉也没有那么清晰,但是也算是一次小总结吧

数据处理

推荐几个库
时间处理推荐Day.js
数据处理lodash

指令

vue中有哪几种指令?
v-html v-text v-if v-else v-else-if v-show v-for v-on v-bind v-model v-slot v-pre v-cloak v-once
复制代码
v-text 和 v-html

相同点两者都可以渲染数据,但是v-html可以解析标签

<span v-text="msg"></span>
<span v-html="htmlMsg"></span>
data(){return{
    msg:'我是一个span标签'
    htmlMsg:'<strong>我是一个span标签</strong>'
}}
复制代码
v-if和v-for不推荐在同一元素上连用

当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。

v-if vs v-show

v-show是通过css display去控制dom节点的显示或隐藏,v-if则是控制dom节点是否存在,频繁使用v-show,否则使用v-if

v-for与key

给dom节点增加唯一标识符,可以高效的更新虚拟dom

v-model

本质上是语法糖,会根据标签的不同生成不同的事件和属性

<input v-model="currentValue">等同于下面的
<input v-bind:value="currentValue" v-on:input="currentValue = $event.target.value">
复制代码
v-cloak

防止在页面加载时先出现变量名闪烁的情况

生命周期

概述
vue中有哪几个生命周期?
beforeCreate 实例初始化之后
created 完成了data数据的初始化
beforeMount 相关的render函数呗调用,当还未挂载html到页面上
mounted 挂载完成
beforeUpdate 数据更新前
updated 数据更新后
beforeDestroy 实例销毁前调用,重置操作,清除定时器和监听操作
destroyed 销毁后
复制代码
在组件外部监听内部的生命周期

之前我们想监听组件内部的生命周期,可能会选择在对应的生命钩子内emit,然后外部监听,其实我们可以通过hook事件直接监听到对应的生命周期

<base-button @hook:created="createBtn" label="主要按钮"></base-button>
复制代码
mounted和created谁更适合ajax请求

之前一直没在意过这个,直到有次看到关于这个的问题,建议放在mounted里使用,顿感是我一直放错了地方吗?
通过一些资料,感觉差异性不大,为了避免闪屏和一致性(ssr)放在created,需要操作dom放在mounted中。

created中操作dom

可以使用$nextTick,将回调延迟到下次DOM更新循环之后执行

this.$nextTick(()=>{...})
复制代码
nextTick

Promise.then、MutationObserver 和 setImmediate都不支持的情况下使用setTimeout,前两个是微任务后两个是宏任务,vue通过判断原生环境是否支持,并且不断降级最后使用setTimeout完成

样式绑定

对我们可以通过对象的形式以及数组的形式,通过条件来显示相应的样式

对象语法
<div class="base-button-container" :class="[{'disabled':disabled}]" :style="{'margin':margin}">
data(){return{
    margin:'15px',
    disabled:false
}}
数组语法
<div class="base-button-container" :class="[disabled]" :style="[baseStyle]">
data(){return{
    baseStyle:{
        color:'red'
    },
    disabled:'disabled'
}}
使用三目运算符,控制样式
<div class="base-button-container" :style="{'margin':isBorder?'0':'15px'}">
data(){return{
    isBorder:false
}}
复制代码

vue-router

beforeEach

处理身份验证(查看是否存在token)
根据用户的权限过滤路由表

来源于vue-element-admin
router.beforeEach(async(to, from, next) => {
  // start progress bar
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)

  // determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
    } else {
      // determine whether the user has obtained his permission roles through getInfo
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
        next()
      } else {
        try {
          // get user info
          // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
          const { roles } = await store.dispatch('user/getInfo')

          // generate accessible routes map based on roles
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)

          // dynamically add accessible routes
          router.addRoutes(accessRoutes)

          // hack method to ensure that addRoutes is complete
          // set the replace: true, so the navigation will not leave a history record
          next({ ...to, replace: true })
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/

    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

复制代码
hash和history模式的区别

最直观的区别就是hash模式下url中带了’#’,history模式下需要前端的URL和后端发起请求的URL一致,默认是hash模式

路由传值

场景:路由跳转显示商品详情

页面刷新时,数据不会丢失
$router.push({query:{}})
组件内部获取值
$route.query.X

使用$router.push({params:{}})刷新页面携带的数据会丢失
复制代码

vueX

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
使用场景:
多个视图依赖于同一状态。
来自不同视图的行为需要变更同一状态。

五个核心属性?
state、getters、mutations、actions、modules 。
复制代码

vuex在界面刷新的时候会初始化导致数据重置,这时候需要将数据存放在localStorage或者sessionStorage中

初始化的时候优先使用sessionStorage内的数据
const state = {
  state1: JSON.parse(sessionStorage.getItem('state1')) || null,
}
mutations中去更新sessionStorage内的数据
  SET_STATE1: (state, keyData) => {
    sessionStorage.setItem('state1', JSON.stringify(keyData))
    state.state1 = keyData
  },
复制代码
组件内使用
this.$store.state.xx
this.$store.getters.xx //类似于计算属性
复制代码
修改

显示的commit(提交)mutation或者dispatch action来修改state中的数据

this.$store.commit('SET_STATE1', keyData) //SET_STATE1为mutations定义的
this.$store.dispatch('SET_STATE1', null) //SET_STATE1为actions定义的
复制代码

axios

params传参

传递数组的时候,需要a=1&a=2&a=3

qs.stringify 将对象序列化成URL的形式
qs.stringify({ a: ['1', '2', '3'] }, { indices: false });
复制代码
封装
  return request({
    url: '',
    method: 'get',
    params
  })
  
  request.js
  创建一个axios请求,并且在request的时候添加token,reponse中处理请求返回的内容,下面内容来自于vue-element-admin用这个的话都是现成的
  const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})
复制代码

组件化

组件传值的几种方式?
父子间 props和emit 实例$parent,$children[节制地使用]
跨组件 Event Bus
vuex 状态管理实现通信
复制代码
attrs和listeners

在项目中,难免要去二次封装element组件,如果所有的属性都需要通过props传递给内部的element组件,会显得很繁杂,利用attrsattrs和listeners就可以跨层级的传递和监听了

    <div class="base-table-container">
        <el-table :data="list" v-on="$listeners" v-bind="$attrs" >
            <slot></slot>
        </el-table>
    </div>
复制代码

结语

还是再次推荐文档的阅读,对于理念上和一些细节的认知都会更加清晰,这次复盘写文章好像遗落了蛮多东西的,争取之后完善起来。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享