优势
传统的Vue写法是Options API,把data、methods、生命周期等等都分开,写个东西要上下滚动。
新的compostition API 可以把功能1相关的东西都写在一起
使用
1、直接使用
vue2.x中的xx.vue
<template>
<!--html -->
</template>
<script>
export default {
name:'test',
components:{}, // 组件
data(){ //数据
return{
o1Data:'功能1的数据',
o2Data:'功能2的数据'
}
},
methods:{ // 函数
o1function(){
//业务1的方法
},
o2function(){
//业务2的方法
},
},
mounted(){ // 生命周期
},
};
</script>
<style>
</style>
vue3.x中的xx.vue
<template>
<!--html -->
</template>
<script>
export default {
import { onMounted } from "vue";
name:'test',
components:{},// 组件
setup() { //组合api
// 功能1
let o1Data = '功能1的数据';
function o1function(){
//业务1的方法
};
// 功能2
let o2Data = '功能2的数据';
function o2function(){
//业务2的方法
};
onMounted(() => { // 生命周期,需要引入
})
return { o1Data, o1function, o2Data, o2function}; //template要用到的变量和函数,要return出去
},
};
</script>
<style>
</style>
也可以只保留数据和如何调用函数,把功能函数放到外面,甚至其他文件中
2、外部引入
也可以通过外部其他文件
查看 https://www.yuque.com/yejielin/mypn47/ff0z2s
语法糖(简写)
https://github.com/vuejs/rfcs/blob/script-setup-2/active-rfcs/0000-script-setup.md
注意
setup里面不能使用this,因为找不到实例,没有绑定对象(by 王红元)
=================
setup 的参数(props , ctx)
用不到的话可以不写参数
props
ctx
emit:见下 父子组件传递参数
attrs:查看 https://www.yuque.com/yejielin/mypn47/agwuud#XPXZF
父子组件传递参数
查看 https://www.yuque.com/yejielin/mypn47/wsa45l#9elM4
setup 的返回值 return
如果也有data属性,也有setup的返回值,里面有同名的变量,优先是用setup里的
setup 执行原理
https://www.yuque.com/yejielin/mypn47/cp5cvf
==================
响应式API
响应式原理
reactive 响应式对象(重要)
响应式数据对象,和ref类似,区别就是在setup里面不需要通过.value读取和使用值,直接引用。
他们都是递归监听,如果结构比较大,会影响性能
<template>
<div>{{a}}</div>
</template>
<script>
import { reactive } from "vue";
export default {
setup() {
let a = reactive({
a:0
});
a.a = 2;
return { a };
},
};
</script>
那么有没有办法让我们解构出来的属性是响应式的呢?见下toRef
ref 响应式变量(重要)
ref是reference的缩写
比较简单的变量,在setup里面使用时要通过 a.value 来获得和使用它表示的值。
<template>
<div>{{a}}</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
let a = ref(0); // 定义
a.value = 2;
return { a };
},
};
</script>
在template中使用时,正常来说也是要加.value才能获取这个引用的值 ,但是为了方便开发,template中做了一层解包,第一层的不用加.value,后续嵌套在其他对象中的要加
readonly 数据只读
无法修改,重新赋值也无效
原理是劫持了proxy的set方法,让他set不到其他任何值就可以了
用途
Reactive判断的API(少)
isProxy 判断是否代理
检查对象是否是由 reactive 或 readonly创建的 proxy,Vue3的响应式都是通过JS的Proxy代理功能实现的。
ref、reactive、readonly都是proxy,原生JS的new Proxy( ) 为false
isRef 判断是否ref
判断值是否是一个ref对象
isReactive 判断是否reactive
readonly 会返回false,但是readonly 包裹着reactive就是true
检查对象是否是由 reactive创建的响应式代理
如果该代理是 readonly 建的,但包裹了由 reactive 创建的另一个代理,它也会返回 true;
isReadonly 判断是否只读
检查对象是否是由 readonly 创建的只读代理。
shallowReactive 只监听第一层
创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (深层还是原生对象)。
let x = shallowReactive({
a:'a',
b:{
c:'c'
}
})
shallowReactive,非递归监听的情况下,只会响应式a和b,不会监听b.c
shallowReadonly 第一层只读
第一层只读,子层虽然可以变化,但是不会更新UI
其他API(少)
toRefs 和 toRef
相当于{ name : ref , age : ref }
参数要是reactive对象,才能用。
也可以用state.name,也是响应式的
通常用于解构reactive
unref 解除响应式
shallowRef 只监听第一层
<script>
import { shallowRef } from "vue";
export default {
setup(){
let state = shallowRef({})
//接下图,给state.value赋值
return { state }
}
}
</script>
非递归监听的情况下,只监听第一层a或gf,html模板里面的c、s、d、b、f不会发生变化,不会响应式更新UI。 把获取数据的方式,封装到一个自定义的Ref中 对双向绑定的属性进行debounce(防抖)的操作; 监听一个变量,属性变化时新的变量会跟着变化 查看 https://www.yuque.com/yejielin/mypn47/fvuxfy#eYk0z
给对象添加了一个v_skip的属性,后续这个对象不管怎么被别人包装,都不会被响应式化,包括对象里面的所有子属性、孙子属性等 查看 https://www.yuque.com/yejielin/mypn47/rpxbwu#wgLF3 查看 https://www.yuque.com/yejielin/mypn47/wsa45l#fFEBt
类似于用js返回html代码
triggerRef 手动触发响应式一次
customRef 追踪和响应
使用场景1
注意:获取数据的方法,不能写到get里面,会不断循环。
然后在setup方法里面调用Ref,这样setup这里就不用写一大坨代码,而是封装出去了,获取数据,然后响应式更新到ui使用场景2
双向绑定,一直输入就会立刻实时更新,一般使用没问题,但是如果输入框是动态发送请求获取下拉数据的,这样反复触发就会消耗网络性能
==================
computed 计算属性
查看 https://www.yuque.com/yejielin/mypn47/bilegi#HoGBG监听数据
—————————-
toRaw 获取源对象
true,还原原本对象的链接
markRaw 永远不追踪变化
比如我可以内部不响应式,外部响应式,实现性能优化
==================
选项
==================
生命周期
组件运行时
errorCaptured
onErrorCaptured
组件(包括子组件)出现错误时
renderTracked
onRenderTracked
组件的wach触发onTrack时
renderTriggered
onRenderTriggered
组件的wach触发onTrigger时
==================
获取元素
ref函数式
JSX