组合式api入口-setup
简单说一下可以把vue3和vue2 理解成c++和c之间的关系
setup里面的方法必须return一下才能被template所使用
语法糖的意义:把复杂变简单,语法糖少了“结构体”和return但是可以达到相同的效果
语法糖eg:
<script setup>
const message ='this is me'
const logMessage =()=>{
console.log(message)
}
</script>
<template>
<div>
{{ message }}
<button @click="logMessage">log</button>
</div>
</template>
hhh忽略掉报红的部分这个应该是前面的错误,看蓝色部分哈。。
最佳实践
1.setup选项的执行时机?
- beforeCreate之前 自动执行
2.setup写代码的特点是什么?
- 内部可以写变量或者函数,但是必须return出去才可以,而且是以对象的方式return出去set
3.setup语法糖(<script setup>)解决了什么问题?
- 简化代码。经过语法糖的封装更简单的使用组合式API
4.setup中的this还指向组件实例吗?
- 不了,它指向undefined
组合式API-reactive和ref函数
reactive()作用:接受对象类型数据的参数传入并返回一个响应式对象
注意:他的参数必须是对象格式,他会得到一个响应式对象,响应式对象会引起视图的更新
在setup这个糖里面普通对象不会引起视图的更新的
别忘了核心步骤:1从vue中导如函数
2在<script setup>中执行reactive函数并传入类型为对象的初始值,并使用变量接收返回值
ref()作用:接受简单型或者对象类型的数据传入并返回一个响应式的对象
通过.value去拿这个相关的数据
最佳实践
1 reactive和ref函数的共同作用是什么?
- 用函数调用的方式生成响应式数据,类似vue2里面的date
2 reactive vs ref?
- reactive不能处理简单类型的数据
- ref参数类型支持更好但是必须通过.value访问修改
- .ref函数的内部实现依赖于reactive函数
3实际工作中推荐使用哪个?
- 推荐使用ref函数,更加灵活,例如我正在学习的小兔鲜项目主要用的是ref
API-computed
计算属性基本思想和vue2的完全一致,组合式API下的计算属性只是修改了写法
1.导入computed函数
2.执行函数 在回调参数中return基于响应式数据计算的值,用变量接收
演示一下用法
其实这里不太清楚filter的用法作用,让我往后看看,从demo中看到了他的用法。
一个计算属性的demo
最佳实践:
1.计算属性中不应该有“副作用”
- 比如除了计算以外还包含了一个异步请求,那这就是副作用,除了计算之外还修改了dom依然是副作用
2.避免直接修改计算属性的值
- 计算属性应该是只读的
watch函数
侦听一个
或多个数据的变化,数据变化时执行回调函数
俩个额外参数:1.immediate(立即执行) 2.deep(深度侦听)
调用watch侦听变化有两个参数(count,(newValue,oldValue))
第一个参数要要侦听谁就把响应式的数据放过来。第二个参数是一个回调函数,监听得count发生变化的时候他会不断地执行自动引入变化之前的老值和新值
demo侦听单个数据源:
在watch中用ref不需要加。value他会帮忙自动处理,弹幕有说如果是数组后者对象则需要.value
侦听多个数据
在watch中把要监听的数据写成数组格式,把想要侦听的放在一块
看逗号后面数组参数形式,前面数组是新值,后面数组是老值
<script setup>
//导入函数
import { ref } from 'vue';
const count =ref(0)
const changeCount=()=>{
count.value++
}
const name=ref('cp')
const changeName=()=>{
name.value='pc'
}
//watch侦听多个数据源
</script>
<template>
<div>
<button @click="changeCount">修改count--{{ count }}</button>
</div>
<div>
<button @click="changeName">修改name--{{name}}</button>
</div>
</template>
效果就是点击以后的效
<script setup>
//导入函数
import { ref, watch } from 'vue';
const count =ref(0)
const changeCount=()=>{
count.value++
}
const name=ref('cp')
const changeName=()=>{
name.value='pc'
}
//watch侦听多个数据源
watch(
[count,name],
(
[newCount,newName],
[oldCount,oldName]
) => {
console.log('count或者name变化了',
[newCount,newName],
[oldCount,oldName])
}
)
</script>
<template>
<div>
<button @click="changeCount">修改count--{{ count }}</button>
</div>
<div>
<button @click="changeName">修改name--{{name}}</button>
</div>
</template>
immediate在说明创建时立即触发回调,响应式数据变化之后继续执行回调
<script setup>
import { ref, watch } from 'vue'
const count =ref(0)
const setCount=()=>{
count.value++
}
//watch立即执行
watch(count,()=>{
console.log('count变化了')
},{
immediate:true
})
</script>
<template>
<div>
<button @click="setCount">+{{ count }}</button>
</div>
</template>
其实还是不太懂immidiate到底啥作用,得往后瞅瞅才行,第一次直接打印,第二次打印的是immidate的内容随着点击次数而变化,就是可以在watch第一次侦听的时候鲜执行一次,等到数据变化的时候会再次执行,这就是他的执行逻辑
deep侦听
默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套对象属性不会触发回调执行,需要开启deep
用例子体会一下
<script setup>
import { ref, watch } from 'vue';
const state =ref({count:0})
const changeStateByCount=()=>{
//直接修改count
state.value.count++
}
//watch深度侦听
watch(state,()=>{
console.log("count变化了")//只有这个的话是不会监听到对象里面的东西的
//因为默认的浅层直接修改是不会发生回调
})
</script>
<template>
<div>
{{ state.count }}
<button @click="changeStateByCount">通过count修改</button>
</div>
</template>
所以要用到deep选项,看下面这个代码
watch(state,()=>{
console.log("count变化了")
//只有这个的话是不会监听到对象里面的东西的
//因为默认的浅层直接修改是不会发生回调
},{
deep:true
})
如果是这样的const state =ref({count:0,age:20})。只想在age发生变化的时候对age进行回调,如果使用deep的话,count同样会被监听这就造成了资源的浪费
。在大多数情况下不要用deep。开启deep以后不管对象有多深都会帮我去做一个递归的处理,很浪费
所以有了:
精确侦听
在不开启deep的前提下,侦听
在第一个回调函数return出要侦听的数据,把要侦听的属性写出来
第二个数据变化的时候要执行的回调
最佳实践
1.作为watch函数的第一个参数,ref对象需要添加.value吗?
不需要watch会自动读取
2.watch只能侦听单个数据吗?
单个或多个
3.不开启deep,直接修改嵌套属性能触发回调吗?
不能,默认是浅层监听
4.不开启deep,想在某个层次比较深的属性变化时执行回调怎么做?
可以把第一个参数写成函数的写法,返回要监听具体属性