Skip to content
On this page

开发实用技巧

1、转boolean

WARNING

如果省略 value 参数,或者设置为 0、-0、null、""、false、undefined 或 NaN,则该对象设置为 false。否则设置为 true(即使 value 参数是字符串 "false")。

js
const toBoolean = (val) => {
  if (typeof val === 'string') {
    if (['true', 'false'].includes(val)) {
      return JSON.parse(val)
    }
    return false
  }
  return Boolean(val)
}

// toBoolean()
// false
// toBoolean('')
// false
// toBoolean('111')
// false
// toBoolean('true')
// true
// toBoolean('false')
// false
// toBoolean(true)
// true
// toBoolean(false)
// false

2、订阅发布

vue
<div ref="divRef" :style="{ width: '100px', height: '100px', background: 'red', marginBottom: '10px' }"></div>
<button :style="{ border: '1px solid #ccc', marginRight: '10px' }" @click="click1">订阅背景改变事件</button>
<button :style="{ border: '1px solid #ccc' }" @click="publish('bgChange')">发布背景改变事件</button>

<script setup>
  import { ref } from 'vue'
  const divRef = ref()
  // 订阅发布
  const depend = {};

  const subscribe = (key, fn) => {
    if (!fn) {
      return;
    }
    if (!depend[key]) {
      depend[key] = [];
    }
    depend[key].push(fn);
  }

  const publish = (key) => {
    const fns = depend[key] || [];
    for (const fn of fns) {
      fn();
    }
  }

  const click1 = () => {
    subscribe('bgChange', () => {
      divRef.value.style.background = 'blue';
    })
  }
</script>

示例:

3、Object.defineProperty(响应式数据)

vue
<div ref="divRef2" :style="{ width: '100px', height: '100px', background: 'red', marginBottom: '10px', color: 'white' }">{{ foo.__obj.name }}-{{ foo.__obj.age }}</div>
<button :style="{ border: '1px solid #ccc', marginRight: '10px' }" @click="click2">name改变事件</button>
<button :style="{ border: '1px solid #ccc' }" @click="click3">age改变事件</button>

<script setup>
  import { ref } from 'vue'

  const divRef = ref()
  const divRef2 = ref()

  const click1 = () => {
    subscribe('bgChange', () => {
      divRef.value.style.background = 'blue';
    })
  }

  // 订阅发布
  const depend = {};

  const subscribe = (key, fn) => {
    if (!depend[key]) {
      depend[key] = [];
    }
    depend[key].push(fn);
  }

  const publish = (key) => {
    const fns = depend[key] || [];
    for (const fn of fns) {
      fn();
    }
  }

  // 生成响应式数据
  const defineReactiveProperty = (obj, key='', value='', defineWatch = {}) => {
    Object.defineProperty(obj.__obj, key, {
      get() {
        // 收集依赖,订阅
        subscribe(key, defineWatch[key])
        return value
      },
      set(newValue) {
        value = newValue
        obj[key] = newValue
        // 消息发布
        publish(key)
      },
    })
  }

  let foo = {
    age: 18,
    name: 'bar',
    __obj: {},
  }

  const defineWatch = {
    name: () => {
      divRef2.value.style.background = 'blue'
      divRef2.value.innerHTML = foo.name
    },
    age: () => {
      divRef2.value.style.background = 'skyblue'
      divRef2.value.innerHTML = foo.age
    }
  }

  defineReactiveProperty(foo, 'name', 'bar', defineWatch)
  defineReactiveProperty(foo, 'age', 18, defineWatch)

  const click2 = () => {
    foo.__obj.name = 'mz'
  }
  const click3 = () => {
    foo.__obj.age = 20
  }
</script>

示例:

bar-18

4、Array.from创建数组

js
Array.from([1, 2, 3])

Array.from({ 0: 1, 1: 2, length: 4 })

Array.from({ length: 4 }, (_, i) => i + 1)

Array.from({ ...[1,2], length: 4 })

const arr = [1, 2, 3]
arr.length = 4
Array.from(arr).map((item, index) => {
  arr[index] = item + 1 // 修改原数组
})

Released under the MIT License.