1.什么是setup()
setup()函数是在组件使用组合式API的入口。
- 可以在选项式API(data、watch…)的组件中使用组合式API,也可以单独使 用组合式API。
- 通过return一个对象,暴露模版需要使用的响应式 属性、计算数据性、方法 等…
- 在setup()方法中是不能获取this实例的,那也就意味着,setup中不能够访问 选项式API暴露的属性,但是选项式API中可以访问setup中的暴露的属性。
<script>
import {ref }from "vue";
export default {
//选项式api
data(){
return {count:1};
},
//组合式api
setup(){
let count1 =ref(0);
return {count1 };
},
};
</script>
2.在setup()中使用所有选项式API的选项
(1) 响应式数据
- 在setup()函数中创建响应式数据需要使用ref或者reactive方法
import {reactive,ref }from "vue";
通过 ref 创建任意数据类型的响应式数据:
- ref创建的响应式数据是一个包裹value属性的对象,所以在setup函数使 用需要:变量.value。
- ref创建的响应式数据暴露到模板中时,不需要通过value属性获取。
通过reactive创建对象类型的响应式数据:
let info =reactive(f username:“张三”})
注意:
- reactive只能创建对象类型数据(对象、数组、map…)
- reactive创建的响应式对象不能经历“被替换”(将响应式对象的属 性赋值或解构至本地变量时,或是将该属性传入一个函数时)
let info =reactive({username:“张三”});
let change =()=>{
//info ={}; //info被替换成空,响应式特性丢失
info.username =""; //未经历替换,响应式继续存在。
};
(2) props
setup()函数接收一个参数,即为props!,但是这里需要通过传统方式先接收props,然后可以传递给setup函数
import {ref }from "vue";
export default {
props:"count",
setup(props){
const count1 =ref(props.count);
const add =()=>{
count1.value++;
};
return {count1,add };
},
};
(3)setup()第二个参数:setup上下文对象(阉割版的vue实例)
- setup()函数接收第二个参数context,setup的上下文对象。他包含:attrs, emit,slots, expose四大属性。attrs相当于之前的this.$ attrs, emit相当于之前的 this.$ emit。
- 在setup中有context第二个参数,主要是setup中没有this实例,所以需要使用上下文对象完成某些需求。如果值是在模版中需要使用attrs或者emit,使用方式不变,还是$emit()。
(4)computed()
通过computed()方法可以制定计算属性
import {ref,computed }from "vue"; export default setup()K let count =ref(0);
let change =()=>{
count.value++;
};
let even =computed(()=>count.value*2);
(5)关于监听:watch()、watchEffect()
- watchEffect()自动监听所有属性。
- watchEffect()方法自动监听所有属性,只要有属性发生改变,就会触发 watchEffect();
注意:必须要在watchEffect当中使用到具体变化的属性,否则watchEffect不执行。 - watchEffect()
- 默认执行一次。
- 监听所有属性改变,但是必须要在watchEffect当中使用到当前具体 ,才能触发watchEffect。
- 只能得到改变之后的最新值
import {ref,computed,watchEffect }from "vue";
export default {
setup(props,context){
let count =ref(0);
let count1 =ref(10);
console.log(context);
watchEffect(()=>{
console.log(count.value);
console.log(count1.value);
});
}
}
watch监听属性:
- 语法:watch(ref值|回调函数,( newValue,oldValue )=>{})
- 普通ref值:监听ref值不需要count.value,直接监听ref值count。
import {ref,computed,watchEffect,watch }from "vue";
export default {
setup(){
let count =ref(0);
watch(count,(n,o)=>{
console.log(n,o);
});
}
}
- 对象ref值:
监听整个对象的变化:(如果监听整个对象的变化,他的新值和旧值一样,因为对象类型数据是通过指针存储的。) - watch()
- 第一次不执行。
- 指定要监听的属性。
- 可以得到属性的新值和旧值
(6)路由对象和路由信息的处理
- 因为setup()方法中不能使用this,所以需要使用其他方式处理路由对象和路由信息:
useRoute和useRouter方法必须在setup函数中执行,不能再他的嵌套函数中执行! - 路由信息
1. 设定路由规则中允许使用props传递参数
{
path:"/about/:id/:name",
name:"about",
props:true,
component:()=>import("../views/AboutView.vue"),
},
props:["id","name"],
setup(props){ }
- 使用useRoute方法创建路由信息对象。
import {useRouter }from "vue-router";
const router =useRouter();
console.log(router);
- 使用getCurrentInstance()方法创建当前组件的实例对象(相当于以前的this),然 后就可以像使用this一样,去使用getCurrentInstance()的返回值。\
import {getCurrentInstance }from "vue";
//只在开发环境有效,生产环境失效
let {ctx }=getCurrentInstance();
//在开发环境和生产环境都有效(推荐)
let {proxy }=getCurrentInstance();
(7)生命周期
- setup()方法本身就相当于之前声明周期中的created之前生命周期的总和,也就是说setup替代了created和beforeCreated。
其他常用的生命周期函数:
onMounted()、onUpdated()、onUnmounted()
3. setup语法糖写法
(1)响应式数据
语法糖模式下不需要写暴露语法,默认暴露。
<script setup>
//1.在当前模式下,不需要在写暴露语法,因为语法糖模式默认暴露
//2.响应式数据和方法
import{ref}from "vue";
let count =ref(O);
let add =()=>{
count.value++;
};
</script>
(2)使用子组件
在语法糖模式下,组件导入后不需要注册可以直接使用
(3)props和emits
可以通过defineProps() 和 defineEmits()方法使用props和emit。
//defineProps
let props=defineProps({
mas:String
})
- defineProps返回的是一个包裹着props属性的对象
//defineEmits
let emits=defineEmits(['change'])
- defineEmits返回的是一个事件触发器(相当于$emit),可以使用他的返回值触 发他接收到的自定义事件
@click="emits('change')"
(4)useAttrs()
使用useAttrs()方法可以在setup中获取未接收的attrs属性。
import {useAttrs }from "vue";
const attrs =useAttrs();
console.log(attrs);