解决 Vue DevTools 中的 Open in Editor 错误唤起 Notepad 的问题

其实从 切换主力编辑器到 Cursor 开始,我的 Vue DevTools 插件中的 Open in Editor 功能一直都有问题。当时始想着都切换到 Cursor 了,再用 VS Code 来打开组件就不太合适了。所以就按照推荐的使用 Shell Commands 命令执行 Install 'code' command 直接把 Cursor 注册进去,以为就搞定了就没有再去验证。
实际上并没有注册成功(也不知道是不是因为我的受控账户所以没办法直接操作环境变量)。直到后面某一天调试的时候,突然发现并没有和预期的一样使用 Cursor 打开,而是直接通过 Notepad 记事本打开了对应的 .vue 文件!
重新执行 Shell Command: Install 'code' command 也没有效果。那我想着注册不行的话,我先恢复成 VS Code 打开拖动到 Cursor 里面先用着等有时间了再解决。结果执行完 uninstall 之后使用 Open in Editor 功能还是使用的 Notepad 打开的组件文件,我就裂开了 🤯。

但是当时开发任务又紧张,可以看到我有很长一段时间都没有更新博客也能发现。但是最近有时间了,就可以着手解决这个问题。

阅读全文

Vue3 中创建 useHooks 遇到的一个 TS 泛型和 Reactive 响应式类型冲突的问题

TIP
不推荐使用 reactive() 的泛型参数,因为处理了深层次 ref 解包的返回值与泛型参数的类型不同。

这段时间总算是得空可以把早些时候快速开发时期挖的坑填一下了,所以准备着手改造一下前人遗留下来的 useTable 这个组合式函数。
期望可以在使用 useTable 的时候可以正确推导出来 tableDataqueryParams 对应的数据类型。

一开始的改造非常顺利,使用泛型可以正确的推导出来我需求的属性类型,直到我遇到了下面这两个TS告警:

Cannot assign type 'T[]' to type 'UnwrapRefSimple<T>[]'. ts(2322) 
不能将类型“T[]”分配给类型“UnwrapRefSimple<T>[]”。ts(2322)
Argument of type 'T' is not assignable to parameter of type 'UnwrapRefSimple<T>'.ts(2345)
类型“T”的参数不能赋给类型“UnwrapRefSimple<T>”的参数。ts(2345)

当然可以选择简单暴力的使用 as 来解决这个问题,但是我总觉得是不是有一些其他更好的方式来解决。

阅读全文

Vue3 中关于 defineProps 的一些 “糖”

const { foo, bar } = defineProps(['foo', 'bar'])

在思否刷到一个问题 🔗 Vue3: 响应式 props 解构得到的变量将不是响应式?也不会更新? 按照问题中引用的文档描述来说确实是不能够解构返回值的。但是问题主提供的两个例子又说明了实际情况下,defineProps() 的返回值是能够被解构的。

VueJS 的 <script setup> 文档 中关于 defineProps() 的部分也没有针对其返回值是否能够解构做出说明。
我在Vue3项目的开发过程中并没有考虑到过这个问题,一直都是通过 props.xx 的形式来使用的。一下子就命中了我的知识盲区,还是 Vue3 写的少了啊。

不过在问题主引用的文档开头有一个响应性语法糖被 移除 的提示,所以去看了一下提示中链接的 废弃原因

阅读全文

绑定的 value 值和元素的 value 值

今天在刷思否的时候遇到这样的一个问题:

<template>
  <input type="text" :value="inputValue" @input="handleInput" />
</template>

<script setup>
import { ref } from 'vue'
const inputValue = ref('')
const handleInput = (e) => {
  const val = e.target.value
  const reg = /^\d*$/
  if (reg.test(val)) {
    inputValue.value = val
  } else {
    inputValue.value = ''
  }
}
</script>

题主希望通过正则校验去限制输入框只能输入数字类型的值,但是只有在先输入数字再输入非数字的情况下才会被正确置空。如果一开始就是输入非数字的内容,后续即使继续输入非数字内容,输入框中的内容并不会清空。

我们可以在 Vue SFC Playground 中体验这个现象。

阅读全文

为什么v-model绑定的对象属性不是总是响应式?

v-model 仅仅只是 v-bind:value="value"@input="value = $event.target.value" 的语法糖吗?

一直以来我都喜欢在Vue中声明对象变量的时候给变量赋值一个空对象,而不是把所有的属性值一起声明好。
比如说:

// vue2.x form demo
export default {
  data() {
    return {
      // 我喜欢这样声明
      formData: {},
      // 而不是这样在声明时把所有的属性一起书写好 
      formData: {
        username: '',
        password: ''
      }
    }
  }
}

也可以从我之前关于 props 属性的笔记中察觉到 👉 Vue中接收没有声明的Prop属性[null/undefined]的接收问题

因为我在写业务的时候如果 props 的属性值不存在,传入的会是一个 undefined 而不是 null 或者 '' 这样的预设。因为我期望使用组件 props 中声明的默认值,而不是在外部预设的空值
所以一直以来我都在和小伙伴交流的时候也是推荐直接给变量一个空对象即可,除了一些数组属性需要单独声明。

但前段时间一位小伙伴向我提问:他在组件生命周期函数中给表单属性赋值了一个预设值,后续再使用 v-model 对表单属性修改时发现丢失了响应……

阅读全文

聊一个VueJS的DOM模板解析注意事项

今天在社区答题的时候,遇到一个题目 《CDN引入的 Vue3 和Element Plus 表格异常,怎么解决呢?》。在去复现的时候和提问者犯了一样的错误。没有显式地写出关闭标签,想当然的直接复制了官方的代码示例就粘贴上去运行了。

问题图片预览

然后还以为是 CDN 上最新版本的包有问题,从 2.2.32 一路试到了 2.0.0 都还是一样情况,然后很果断地得出了一个结论:官方的演示 Demo 也有问题 😂。

其实问题就是在 没有显式地写出关闭标签……

阅读全文

Set & Map 数据结构是无法被 Vue 监听的

这次在写业务的时候因为是无限层级的递归表单,用了 provide/inject 来暴露注册以便收集数据。所以就想要用 Map 数据结构来处理数据的收集等等功能。直接使用 记录ID 作为键名就可以了,这样也可以直接去重。但是写完了业务代码之后发现我把后代的表单注册进来并没有触发响应,导致数据回填失败。

所以想着是不是 Vue 2x 无法监听 Map 或者 Set 的数据变更的。就去检索了一下相关的信息,发现 Vue 2x 真的无法监听 Map 以及 Set 俩兄弟。只能够通过修改其他变量来曲线救国。

Vue 3x 通过 Proxy 来代理就没有了这个问题。

阅读全文

Vue 中的样式穿透 v-deep、/deep/ 和 >>>

Vue 项目的开发中,很多人都因为想要限制 CSS 样式的作用范围(避免样式污染的问题)去使用 scope 属性。

但是很多的情况下都会去修改分装好的子组件以及UI库中的组件样式,所以经常会用到 样式穿透 这个东西,因为我以前是使用的 Stylus 作为样式预处理器的,所以并没有感觉到什么困惑的地方,但是有很多同学是使用的 Scss 以及 Less 的,对于他们来说什么时候使用 /deep/ 什么时候使用 ::v-deep 是很困扰的。特别是对于一些刚刚进入前端圈的小伙伴们。

正好最近在思否也遇到了很多人来问这样的问题,就像一次性都把相关的疑问都回答了。

阅读全文

Vue中接收没有声明的Prop属性[null/undefined]的接收问题

最近在写基础组件,同事一直反馈说组件总是提示警告:

[Vue warn]: Invalid prop: type check failed for prop "value". Expected String, Array, got Null

一开始以为是接收的问题,把定义的props加上了工厂函数后没有报异常就没再管了。
今天再去看的时候发现还是有报错,检查了一下组件代码没发现问题,在查看业务代码的时候发现同事喜欢给声明的变量默认赋值为 null。而不是声明正确的基础类型。所以我就想应该如何把这个问题彻底解决掉。

🔔 其实这个提示为了提醒可能你绑定的变量并不一定存在。

阅读全文

聊一个复用组件中使用debounce时遇到的问题

今天我中遇到了一个这样的场景,发现触发复用的自定义组件中添加了防抖的函数,发现只执行了一次,并没有如预期的那样每个组件内的函数都执行一次。

一开始以为是没有同步赋值,检查了一下没问题,才把关注点转移到 debounce 上面。移除防抖之后果然解决问题了,但防抖又不能去去掉。

所以查了一下相关的问题,发现是因为多个组件实例是共享同一个预置防抖的函数,并不是相互独立的。

阅读全文