vue3 之 问题总结(一)
Vue3 官网:https://cn.vuejs.org/guide/introduction.html
一、为什么要使用ref?
使用ref来创建响应式数据,当你在模板中使用了一个 ref,然后改变了这个 ref 的值时,Vue 会自动检测到这个变化,并且相应地更新 DOM。在标准的 JavaScript 中,检测普通变量的访问或修改是行不通的。然而,我们可以通过 getter 和 setter 方法来拦截对象属性的 get 和 set 操作。该 .value
属性给予了 Vue 一个机会来检测 ref 何时被访问或修改。
【那这儿就要提到其原理】
Vue3是通过Object.define.proxy 对对象进行代理,从而实现数据劫持。使用Proxy 的好处是它可以完美的监听到任何方式的数据改变,唯一的缺点是兼容性的问题,因为 Proxy 是 ES6 的语法
Vue3.0 摒弃了 Object.defineProperty,改成了 Proxy 。
首先说一下 Object.defineProperty 的缺点:
① Object.defineProperty 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实施响应。 this.$set()解决
② Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue2.X 里,是通过递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象才是更好的选择。
③ proxy:可以代理整个对象,并返回一个新对象,而Object.defineProperty代理的是对象中的单个属性
二、自动引入ref、reactive等等
可以使用 unplugin-auto-import 插件
1 | npm i unplugin-auto- import -D |
vite中使用 ,于vite.config.js中配置
1 2 3 4 5 6 7 8 9 10 11 12 | import vue from '@vitejs/plugin-vue' ; // 引入插件 import AutoImport from 'unplugin-auto-import/vite' ; export default defineConfig({ plugins: [ vue(), AutoImport({ imports:[ 'vue' , 'vue-router' ] }) ] }); |
三、reactive()
的局限性
① 有限的值类型:只能用于对象类型(对象、数组这样的集合类型)
② 不能替换整个对象:如果“替换”,那么可能导致数据失去响应式
③ 对解构操作不友好:会导致数据失去响应式
四、reactive、ref 与 shallowRef的区别
① ref:可以定义基本类型和赋值类型
② reactive只能定义复杂类型,定义基本类型会有警告,而且数据不具备响应式
③ shallowRef的性能高于ref,复杂类型的完整赋值,shallowRef只需要解包一次,ref需要解包两次
④ ref定义的变量获取时需要.value,reactive可以直接获取
五、如何修改计算属性呢
计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性,你可以通过同时提供 getter 和 setter 来创建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <script setup> import { ref, computed } from 'vue' const firstName = ref( 'John' ) const lastName = ref( 'Doe' ) const fullName = computed({ // getter get() { return firstName.value + ' ' + lastName.value }, // setter set(newValue) { // 注意:我们这里使用的是解构赋值语法 [firstName.value, lastName.value] = newValue.split( ' ' ) } }) </script> |
六、聊聊v-if、v-for、v-show吧
最主要是来说说 v-if与v-for v-if与v-show
① v-if 与 v-for
1) vue2 v-for 优先级高于 v-if ; vue3 v-if 优先级高于 v-for
2) 两者不推荐同时使用
② v-if 与 v-show
1) v-if 是控制标签/元素的销毁和重建
2) v-show 是相当于display属性值来隐藏和显示
七、简单聊聊vue3的组件通信吧
1)父传子
通过在子组件上定义自定义属性进行传递,在子组件中使用defineProps进行接收(不携带默认值),如果需要携带默认值则使用withDefaults(defineProps(),{默认值})进行接收
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <Child :msg= "msg" num= "152" @zxc= "zxc" ></Child> // 父传子 type Props = { num: number, msg: string, str: string } // 不带默认值的写法 // let props = defineProps<Props>() // 携带默认值 let props = withDefaults(defineProps<Props>(), { str: '默认值' }) |
2)子传父
子组件自定义事件进行触发,通过defineEmits来触发事件,父组件通过自定义事件接收
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <button @click= "devFather" >子传父</button> // 子传父 let childMsg = ref<string>( '子组件的数据' ) type Emit = { (event: 'zaq' ): void (event: 'zxc' , childMsg: string): void } let $emit = defineEmits<Emit>() let devFather = () => { // 子传父,不携带参数 // $emit('zaq') // 携带参数 $emit( 'zxc' , childMsg.value) } |
注:该文档为个人理解所写,有误可建议修改
本文作者:persistIn
本文链接:https://www.cnblogs.com/persistIn/p/17975241
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步