upset:
- upset()函数中返回出来的数据是会被浅解析的,原本我们直接定义的数据需要通过ref.value才能拿到ref中定义的数据,但是在upset中返会出来的直接使用定义的数据
- upset()中传入的数据都是响应式的,但是解构后会让数据失去响应式,推荐使用点的形式去拿到数据。如果想要解构数据,并且保持响应式,可以使用toref和torefs这两个方法
- 第一个参数是props,可以拿到子组件传递过来的props。第二个参数是setup上下文,上下文中暴露了其他一些会在setup中用到的值。
ref:
- 通过ref()方法可以创建一个任意类型的属性,并且通过ref方法创建的属性无论怎样使用(传入给函数,解构)都是响应式的
- ref在模板中的解包,通过ref创建的属性是一个顶层属性的时候,在模板结构中使用是不需要 .value的
- 通过const创建的顶层属性可以简单的理解成创建在栈中的简单数据类型,底层属性可以理解为引用类型的复杂数据类型的数据
- cosnt count = ref(1),count是一个ref响应式的值,当我们将给一个已有ref响应式值的常量state赋值一个ref响应式的值,那么新的值会将state中旧的值替换掉,state.count和count.value表示的不是一个ref响应式值
计算属性:
书写方式:const count = computed(()=>{return 返回通过计算得到的结果} )
- 计算属性中不可以操作DOM和进行异步请求,因为他是依赖一个值派生出新的值
- 计算属性通常是一个只读属性,不要去直接修改它
- 计算属性实在所依据的响应式依赖更新后,立即更新,而使用方法在依赖项更新时做出更新要想通过getter属性获取数据,再通过setter属性对数据做出更新,不如计算属性快,并且消耗更多的性能
-
<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>
通过getter和setter实现可写计算属性
类和样式的绑定:
- 和vue2中一样,可以在标签上绑定class属性,属性值是一个对象,对象的属性是要绑定的class类,属性值是boolean值,用来确定该class属性是否绑定
- class的属性值还可以是一个响应式对象,用来一次性绑定多个class类
-
const classObject = reactive({ active: true, 'text-danger': false }) <div :class="classObject"></div>
条件渲染 v-if v-eles 和列表渲染 v-for
1.v-if 和 v-eles可以在template编译模板上使用,为false时会将整个模板内的内容隐藏
2.v-show不支持在template上使用
3.v-if 和 v-for 在同一节点上时,v-if 的优先级更高,更先执行
4.v-for渲染的对象可以是一个数组,也可以是一个对象,在渲染对象的时候可以通过第一个参数value拿到对象中每一项的属性值,通过第二个参数key拿到属性名
Vue能够侦听到数组的变更方法
- 变更方法:push、pop、shift、unshift、splice、sort、resver
- 替换数组的方法:filter、slice、concat(创建一个新的数组,而不是修改之前的数组)
- 当我们需要使用替换数组的方法来实现时,比如使用filter方法来过滤数组数据,我们可以使用计算属性,返回一个新的数据,我们依据这个新的数据进行遍历展示
事件处理:通过 v-on/@ 绑定内联处理器和方法
- 内联处理器如:method()、count++
- 方法就是@click="方法名"
- 也就是说给方法传递参数了,他就是内联处理器而不是方法了
修饰符:vue3的修饰符相较vue2并没有做出什么变化,就不再赘述
v-model:表单输入绑定
生命周期:
- vue3中移除了beforeCreate和created这两个生命周期函数,而是使用setup
- vue3中的onBeforeMount=》vue2中的before Mount
- vue3中的onMounted=》vue2中的mounted
- vue3中的onBeforeUpdata=》vue2中的beforeUpdata
- vue3中的onUpdated=》vue2中的updataed
- vue3中的onBeforeMounted=》vue2中的beforeDescrity
- vue3中的onUnMounted=》vue2中的Descrited
- onErrorCapture用来捕获异常,这个钩子有个特性,如果在这个钩子组件的父组件或者继承链上同样有onErrorCapture钩子,那么它会像冒泡机制一样向上传递,可以在钩子的事件处理程序中return一个false来终止传递
- 以上钩子都不会在服务端渲染
- onRenderTracked 是一个调试钩子,在渲染过程中追踪到响应式依赖时调用,只在开发环境中可用,且在服务端渲染时是不可用的
- onRenderTriggerder 在响应式依赖的变更触发了了组件更新渲染时被调用,只在开发环境中可用,且在服务端渲染时是不可用的
- onActivated 当组件在keepalive缓存里时,当组件被插入到DOM中时被调用
- onDeActivated 组件是keepalive缓存里的一部分,但组件被移除dom树时被调用
- onServerPrefetch 注册一个异步函数 当组件在服务端被渲染之前调用。注意:1.这个钩子仅会在服务端执行,所以可以写一些特定在服务端的数据抓取过程;2.如果这个钩子最后返回了一个promise,那么服务端渲染会等在这个promise执行完再渲染这个组件
侦听器watch:
可以监听的数据类型有:响应式对象,一个ref(包括计算属性),一个getter函数,多个数据源组成的数组。
- watch(data,()=>{}),第一个参数是侦听的数据,第二个参数是侦听的数据发生变化时要执行的事件处理程序。
- 当侦听器watch监听的数据是一个响应式对象的属性值时,需要返回该属性的getter函数
- 如果侦听的对象是一个返回响应式对象的getter函数时,只有在返回不同对象的时候才会触发监听的事件处理程序。
- 深度监听:1.在监听的参数是一个响应式对象的时候,会隐式的开启深度监听。2.也可以在直接使用 {deep:true} 开启深度监听。深度监听的开启要慎重,因为深度监听对遍历监听对象中所有嵌套的属性。
- watchEffect 会立即执行一次回调函数,会自动的追踪到副作用的依赖,并且自动分析出响应源,也就是自己找依赖,并且监听依赖的变化,去执行事件处理程序。
- watch和watchEffect之间的区别,watch监听的是明确的数据源,不会去追踪事件处理程序中访问到的任何东西,所以可以更加精确的监控触发时机。而watchEffect会自动地追踪回调函数中所有能够访问的响应式依赖,代码简洁,但是依赖关系不明朗。
- watch和watchEffect中回调函数的执行时机是在vue组件被更新之前调用,也就是说我们在它们的回调函数中获取到是未被更新的dom,想要获取组件更新之后的dom,需要给watch和watchEffect设置一个新的参数{flush:‘post’}
watch(source, callback, { flush: 'post' }) watchEffect(callback, { flush: 'post' })
- 我们在setup上使用的侦听器是会被自动停止的,如果需要手动停止的话调用watch或watchEffect返回的函数
模板引用(ref、v-for、组件上的ref):
- ref,vue中ref是在标签上绑定,然后通过this.$refs来获取整个dom元素,但是在vue3中改变获取dom元素的方法,首先要再setup中定义 cosnt dom = ref(null),在标签上绑定ref='dom' ,再在onmounted函数中dom.value拿到dom,再进行dom操作
- 还可以动态给组件上的ref绑定一个函数,函数会接收这个dom作为参数引用。函数会在dom元素更新的时候调用,当dom元素被销毁的时候也会调用一次函数。:ref = "(el)=>{}"
- 组件上的ref的使用,在选项式API中,可以通过在组件上定义ref从而直接获得子组件上所有的方法和属性,但是在组合式API中,使用setup的组件是默认私有的,父组件想要使用子组件上的方法和属性可以通过defineExpose将子组件里面的方法和属性暴露出来。
组件注册:
- 全局注册:在main.js中引入createApp,再通过这个函数构建一个对象app,默认导入要注册的组件,通过app.component将它挂载到app上
-
import { createApp } from 'vue' const app = createApp({}) app.component( // 注册的名字 'MyComponent', // 组件的实现 { /* ... */ } )
- 全局注册的组件没有使用的话,在打包时无法自动移除,并且全局组件使项目中组件之间的依赖关系并不明确
- 局部注册组件只需要在使用该组件的地方导入,直接在template模板编译中使用就是了,如果script上没有开启setup,就需要通过components选项来声明。
- 在为组件起名时尽量使用驼峰命名法。
- 我们在重复使用一个组件时,发现一个组件的状态并不会收到另一个组件状态的影响,这是因为每个组件都在维护自己的状态,每次使用组件时,都会创建一个新的实例。
props:
- 在组合式api中,通过const props = defineProps()来接收父组件传递过来的数据
- 可以通过v-bind不绑定属性名,来一次性将父组件上的一个对象上的全部属性全部传递给子组件,这种方式子组件在拿数据的时候,props中默认的属性名是父组件上对象的属性名
- 注意组合式api中props的写法
事件监听
- 可以通过defineEmits来声明式触发事件
-
<script setup> const emit = defineEmits(['inFocus', 'submit']) function buttonClick() { emit('submit') } </script>
目前就写到这里吧,在上班没有大量空白的时间去学习,笔记日后会继续更新