vue
相关
vue2.x的响应式
-
实现原理
。对象类型:通过Object.defineProperty()
对属性的读取 修改进行拦截(数据劫持)。
。数组类型:通过重写更新数组的一些列方法来实现拦截,(对数组的变更方法进行了包裹)。
Object.defineProperty(data, 'name', {
get(){
return person.name
},
set(value){
console.log('有人修改了name属性,被我发现了,我要去更新name属性了')
person.name = value
}
})
- 存在问题 。新增属性 删除属性,界面不会更新 。直接通过下标修改数组,界面不会自动更新
vue3.x的响应式
。通过Proxy (代理): 拦截对象中任意属性的变化,包括:属性值的读写 属性的添加 属性的删除等
。通过Reflect(反射):对被代理对象的属性进行操作
MDN文档中描述的Proxy与Reflect:
。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy
。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
const p = new Proxy(person, {
//拦截读取属性
get(target, prop){
return Reflect.get(target, prop)
},
//拦截修改属性或添加属性
set(target, prop, value){
return Reflect.set(target, prop, value)
},
//拦截删除属性
deleteproprty(target, prop) {
return Reflect.deleteproprty(target, prop)
}
})
p.name = 'hi'
vue...中数组方法链式简写
//原本的
const countryModelList = this.$lodash.cloneDeep(res.records)
const keys = countryModelList.map(model => {
return model.modelId
})
this.filterForm.values = this.modelList
.filter(item => {
return keys.includes(item.id)
})
.map(f => {
return f.key
})
//简写后
const countryModelList = this.$lodash.cloneDeep(res.records)
const keys = countryModelList.map(model => model.modelId)
this.filterForm.values = this.modelList.filter(item => keys.includes(item.id)).map(f => f.key)
vue中...运算扩展符使用
//原本的
const { brandCode, period, deptCode } = this.bandObj
const params = { brandCode, period: this.$utils.formatDate(new Date(period), 'yyyyMM'), deptCode }
console.log(params) //{brandCode: "Infinix", period: "202108", deptCode: "Infinix BU"}
//改版后
const { period } = this.bandObj
const params = { ...this.bandObj, period: this.$utils.formatDate(new Date(period), 'yyyyMM') }
console.log(params) //{brandCode: "Infinix", deptCode: "Infinix BU", period: "202108"}
vue中...对象解构多层结构
//number one
const user = {
id:1,
name:'xiaoming',
age: 20,
sex: '女',
edcation:{
degree:'Master'
}
}
const { edcation:{ degree } } = user
console.log(degree) // prints: Master
//number two 1.取别名 2.设置默认值
const user = {
id:1,
name:'maiming',
age: 20,
sex: '女',
// hobby: 'Swimming',
education:{
degree:'Master',
user: {
userId: 2,
userName:'maiming-1',
}
}
}
const { sex: gender, hobby = 'running', education:{ user: {userId: id, userName} } } = user
console.log(gender,hobby, id, userName) // 女 running 2 maiming-1
javascript
实用技巧
提前退出和提前返回
/*
1.需求
如果没有动物 抛出异常
打印出动物名称
打印出动物类型
打印出动物性别
*/
function printAnimalDetails(){
var result = null
if(animal){
if(animal.type){
if(animal.name){
if(animal.positioning){
result = `${animal.name} is a ${animal.positioning} ${animal.type}`
}else{
result = 'no animal positioning'
}
}else{
result = 'no animal name'
}
}else{
result = 'no animal type'
}
}else{
result = 'no animal'
}
return result
}
建议写法
const printAnimalDetails = ({ type, name, gender } = {}) =>{
if(!type) return 'no animal type'
if(!name) return 'no animal name'
if(!gender) return 'no animal gender'
return `${name}is a ${gender}的${type}`
}
let getResult = printAnimalDetails({type:'狗子', name:'佩奇', gender:'雌性'})
console.log('@@@@@@@@', getResult)
对象字面量
//需求:基于颜色打印水果
//1. switch...case
function printFruits(color){
switch (color) {
case 'red':
return ['apple']
break;
case 'yellow':
return ['banana']
break;
default:
return []
break;
}
}
let res = printFruits('red')
console.log(res)
//2.对象字面量 0-建议
const fruitsColor = {
red: ['apple'],
yellow : ['banana']
}
function printFruits2(obj, color){
return obj[color] || []
}
console.log(printFruits2(fruitsColor, 'yellow'))
console.log(printFruits2(fruitsColor, null))
//3.map 1-建议
const fruitsColorMap = new Map().set('red',['apple']).set('yellow', ['banana'])
function printFruits3(obj, color){
return obj.get(color) || []
}
console.log(printFruits3(fruitsColorMap, 'red'))
console.log(printFruits3(fruitsColorMap, null))
some-every运用场景
//需求:检查所有颜色是否都是red
const fruits = [
{name: 'apple', color: 'red'},
{name: 'banana', color: 'yellow'},
{name: 'orange', color: 'yellow'},
{name: 'pitaya', color: 'red'}
]
//every
const isAllRed = (fruits) => {
return fruits.every(f => f.color === 'red')
}
console.log('@@@@@@@@', isAllRed(fruits))
//需求:检查是否有一个颜色是red
//some
const hasOneRed = (fruits) => {
return fruits.some(f => f.color === 'red')
}
console.log('@@@@@@@@', hasOneRed(fruits))
find和filter
const fruits = ['apple', 'banana', 'orange', 'peach', 'plum']
//1.对满足的length 只会返回第一个元素
//2.对不满足的返回undefined
let getResult = fruits.find((item, index, data) => {
// console.log('@@@@@@@',item, index, data )
return item.length === 5
})
console.log('@@@@@@--find', typeof getResult, getResult)
//1.对满足的length 返回满足条件的数组
//2.对不满足的返回[]
let getResult2 = fruits.filter((item, index, data) => {
// console.log('@@@@@@@',item, index, data )
return item.length === 5
})
console.log('@@@@@@--filter', getResult2)
(filter) 需求:数组去掉空
const arr = ['', 'arr', ' ', 0, {name:'tom'}, [1,2,3], '', null, undefined, '']
let getResult3 = arr.filter((item,index) => {
return item || typeof item === 'number' || item === null || item === undefined
})
console.log('@@@@@@--filter--arr', getResult3) // ["arr", " ", 0, {…}, Array(3), null, undefined]
日期计算
*需求:当月24号之前 月份为当月,月份24号之后 提报为下一个月。例子(2021-8-23 即为提报日期 2021-8 2021-12-26 即为提报日期 2022-01)
getDate() {
const NOW = new Date() //当前时间
const DAY = Number(NOW.getDate()) // 当天
const setMonth = Number(NOW.getMonth()) + 1 // 代表当月
const nextMonth = setMonth + 1 // 代表下一个月
const getYear = NOW.getFullYear() // 当年
const MONTH = DAY < 24 ? setMonth : nextMonth < 13 ? nextMonth : nextMonth - 12 < 10 ? '0' + (nextMonth - 12) : nextMonth - 12
const YRAR = DAY < 24 ? getYear : nextMonth < 13 ? getYear : getYear + 1
return YRAR + '-' + MONTH
},
async await
// 抽离成公共方法用来处理async
const awaitWrap = (promise) => { return promise.then(data => [null, data]).catch(err => [err, null]) }
// 请求
const [err, res] = await awaitWrap(areaAddAPI(params))
//try...catch...包裹
try {
const {data} = await areaAddAPI(params)
console.log(data)
}catch(err){
console.log(err)
}