工作的记录点

176 阅读4分钟

路由守卫

场景

  • 通过在url通过路由访问形式跳过之前的页面验证,比如登录验证...

思路

可以使用组件内得路由守卫,使用beforeRouteEnter(to, from, next)
可以在create钩子函数中判断,但是此时页面已经创建了,所以会造成不必要的加载,而且如果设置重定向得话,页面会闪一下,视觉效果不好。
需要注意的两点是,

  • beforeRouteEnter拿不到this,所以需要用到vuex等需要重新引用
  • 必须调用next()

代码

import { httpGet, httpPost } from '../../../api/index'
export default {
  name: 'unsubscribeChoice',
  data() {
  //省略
  },
  beforeRouteEnter(to, from, next) {
    //为了拿到客户编码
    let customCode = ''
    httpGet('v2/user/accountSecurity').then(res => {
      customCode = res.userInfo.customCode
      console.log(customCode)
      //发起请求查看状态
      let params = {
        customerCode: customCode
      }
      httpPost(`v2/account/verification`, params)
        .then(res => {
          if (res.status !== 1) {
            // this.$router.push('userCenter')
            next({ path: 'userCenter' })
          } else {
            next()
          }
        })
        .catch(() => {
          next({ path: 'userCenter' })
        })
    })
  },
  mounted() {

  },
  methods: {
  }
}

父子组件之间得数据更新

不能直接用传过来的数值双向更新,必须是单向数据流,用计算属性传递数值
父级:

<popUpWindows :obj="obj" :visibles.sync="visibles"/>

子级:

  computed: {
    visible: {
      get: function() {
        return this.visibles
      },
      set: function(newValue) {
        this.$emit('update:visibles', newValue)
      }
    }
  },

实现表格多选框的逻辑

目的:

2799dab74c8e05071a6ebd968529616.png 根据接口数据渲染数据,然后可以进行编辑进行保存

   <a-table :columns="columns" :data-source="data">
                <span slot="customTitle">
                    <a-icon type="smile-o" /> 消息类型
                </span>
                <span slot="messageTitle">
                  <a-checkbox
                    @change="onCheckAllChange('message')"
                    :indeterminate="indeterminateObj.message"//2.控制联动样式两种状态
                    :checked="checkedAllObj.message">//2.控制选中或者不选,两种状态
                   </a-checkbox>站内信
                </span>
                <span slot="message" slot-scope="text, record, index">
                  <a-checkbox
                    @change="onChange(index, record, 'message')"
                    :checked="data[index].message"
                  >
                  </a-checkbox>
                </span>
                <span slot="emailTitle">
                  <a-checkbox
                    @change="onCheckAllChange('email')"
                    :indeterminate="indeterminateObj.email"
                    :checked="checkedAllObj.email"
                  >
                  </a-checkbox>
                  邮件
                </span>
                <span slot="email" slot-scope="text, record, index">
                  <a-checkbox
                    @change="onChange(index, record, 'email')"
                    :checked="data[index].email"
                  >
                  </a-checkbox>
                </span>
                <span slot="qqTitle">
                  <a-checkbox
                    @change="onCheckAllChange('qq')"
                    :indeterminate="indeterminateObj.qq"
                    :checked="checkedAllObj.qq"
                  >
                  </a-checkbox>
                  QQ
                </span>
                <span slot="qq" slot-scope="text, record, index">
                  <a-checkbox
                    @change="onChange(index, record, 'qq')"
                    :checked="data[index].qq"
                  >
                  </a-checkbox>
                </span>
                <span slot="wechatTitle">
                  <a-checkbox
                    @change="onCheckAllChange('wechat')"
                    :indeterminate="indeterminateObj.wechat"
                    :checked="checkedAllObj.wechat"
                  >
                  </a-checkbox>
                  微信
                </span>
                <span slot="wechat" slot-scope="text, record, index">
                  <a-checkbox
                    @change="onChange(index, record, 'wechat')"
                    :checked="data[index].wechat"
                  >
                  </a-checkbox>
                </span>
   </a-table>
 //js部分
 const data = [
  {
    key: '1',
    type: 'John Brown',
    message: true,
    email: true,
    qq: true,
    wechat: true
  }

  //data中的      
  checkedAllObj: {
        message: false,
        email: false,
        qq: false,
        wechat: false
      },
      indeterminateObj: {
        message: false,
        email: false,
        qq: false,
        wechat: false
      },
 methods:{
     onChange(index, record, key) {
      //   console.log(a)
      //   console.log(e.target.checked)
      // this.data.index.message=!this.data.index.message
      console.log(key)
      this.data[index][key] = !this.data[index][key]
      this.onCheckAllChange(key)
      console.log(record)
    },
    onCheckAllChange(key) {//2.key用来判断垂直列
      let arr = []
      for (let num of this.data) {
        arr.push(num[key])
      }
      if (arr.indexOf(true) === -1) {
        //一个true都没有
        console.log('1', arr)
        this.indeterminateObj[key] = false//2.根据两者状态判断对应状态
        this.checkedAllObj[key] = false
      } else if (arr.indexOf(false) === -1) {
        //全是true
        console.log('2', arr)
        this.indeterminateObj[key] = false
        this.checkedAllObj[key] = true
      } else {
        //存在true
        console.log('3', arr)
        this.indeterminateObj[key] = true
        this.checkedAllObj[key] = false
      }
 }

总结

1,第一点:双向数据绑定
2,垂直联动(框架里面没有)

关于computed和watch和 filters

计算属性

computed 支持缓存

get和set,如果对被监听的数据有赋值情况存在的话,那么就会执行set,但是结果还是会取get中的结果

侦听属性

watch 不支持缓存

应用:当需要在数据变化时执行异步或开销较大的操作时(可以限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态)

方法:

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

其实filtersvue3中已经删除,并且从功能上说可以用计算属性和方法来替代详细解释请点击这里

关于下拉框的样式处理:

目的:在下拉框前加一个固定的修饰词使其不存在于数据中:

image.png
代码:

  .choiceClassOne {
    display: inline-block;
    /deep/.ant-select-selection-selected-value::before {
      content: '类型:';
      display: inline-block;
      width: 10px;
      margin-right: 20px;
    }
  }

toFixed

首先什么是toFixed?
W3School,菜鸟:

image.png

例子:

let c=1.465
let d=1.455
let e=2.445
console.log(c.toFixed(2))//1.47
console.log(d.toFixed(2))//1.46
console.log(e.toFixed(2))//2.44

好家伙,如果是按照四舍五入的话,凭借我多年深厚的数学功底一点就能看出2.445的输出应该是2.45!!
其实去一些相对比较权威的网站上来说,对于toFixed的解释根本就没有提到四舍五入!
MDN中对toFixed的解释

toFixed()  方法使用定点表示法来格式化一个数值。
描述:一个数值的字符串表现形式,不使用指数记数法,而是在小数点后有 digits(注:digits具体值取决于传入参数)位数字。该数值在必要时进行四舍五入,另外在必要时会用 0 来填充小数部分,以便小数部分有指定的位数。 如果数值大于 1e+21,该方法会简单调用 Number.prototype.toString()并返回一个指数记数法格式的字符串。 原因: 其实在js中toFixed使用的是银行家舍入规则
银行家舍入:是一种四舍六入五取偶(又称四射六入五留双)法。

四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。

这句话是网上的解释但是其实从例子上看很明显不对。
我觉得应该是:
js四舍五入并没有采用标准的银行家算法,但是也是四舍六入,五后全部为0就情况不确定,不为0时所以只要四舍五入时加上一个足够小的数字(Number.EPSILON)就行了
关于Number.EPSILON
Number.EPSILON标识js能表示的最小数字 EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16,或者 2^-52。