愿舒适的晚风和星空 带走一切坏情绪。
<template>
<h1>{{ msg }}</h1>
<button @click="count++;num--">count is: {{ count }}{{num}}</button>
<p @click="addNum">Edit <code>components/HelloWorld.vue</code> to test hot module replacement.</p>
<p v-for="(item,index) in numCopy.stus" :key="index">{{item.key}}{{numCopy}}</p>
</template>
<script>
import { ref, reactive } from 'vue'
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
count: 0
}
},
// 组合api入口函数,是在beforecreate钩子之前完成的 无法使用 data和 methods
/**
*
*/
setup () {
//reactive ref 同理使用proxy
/**
function ref (obj) {
return reactive({ value: obj })
}
function reactive (obj) {
if (typeof obj === 'object') {
if (obj instanceof Array) {
//如果是数组,取出数组中的每一个元素
//判断其是否是一个对象,是否需要包装成proxy
obj.forEach((item, index) => {
if (typeof item === 'object') {
obj[index] = reactive(item)
}
})
} else {
//如果是对象,取出对象中的每一个value
//判断其是否是一个对象,是否需要包装成proxy
for (let key in obj) {
let item = obj[key];
if (typeof item === 'object') {
obj[key] = reactive(item)
}
}
}
}
}
*/
//手写一个shallowRef
/**
function shallowRef(obj){
return shallowReactive({value:obj});
}
function shallowReactive(obj){
return newProxy(obj,{
get(obj,key){
return obj[key]
},
set(obj,key,value){
obj[key=value];
console.log('页面更新')
return true;//这个必须
}
})
}
*/
//vue3.0响应式数据的本质
/**
proxy //=
set方法必须通过返回值告诉proxy此次操作是否成功
let obj={name:'ll',age:'18'}
let state=new proxy(obj,{
get(obj,key){ //监听外界有没有获取值
console.log(obj,key);
return obj[key]
},
set(obj,key,value){
console.log(obj,key,value)
obj[key]=value;
console.log('更新ui)
//需要添加
return true
}
})
console.log(state.name)
state.name="???"
*/
/**
readonly 可定义只读数据 递归只读 shallowReadonly 第一层只读,非递归只读 isReadonly判断是否只读?callback bool
与const 区别是 const为变量赋值保护,readonly属性赋值保护
*/
/**
组合api也可以加入生命周期
onMounted onCreated 。。。
onMounted(()=》{
。。。
})
*/
//ref函数和reactive函数都可监听所有数据类型(递归监听)
//默认情况下递归监听是好的,可以让数据变化是是被监听到,但是也带来了性能消耗问题;
// 内部函数为同步,不可异步
/**
* 2.非递归监听
shallowRef / shallowReactive
3.如何触发非递归监听属性更新界面?
- 如果是shallowRef类型数据, 可以通过triggerRef来触发
- 注意点: 如果是通过shallowRef创建数据, !!!
-- 那么Vue监听的是.value的变化, 并不是第一层的变化
4.应用场景
一般情况下我们使用 ref和reactive即可
只有在需要监听的数据量比较大的时候, 我们才使用shallowRef/shallowReactive
*/
//shallow类型的数据,只会监听最外层的数据的变化,才会引起视图层的变化
//对于 shallowRef 过的 ref 对象,我们还可以 triggerRef 去触发 ref 的变化监听来实现界面的改变
//----在 shallowReactive 中,并没有提供 trigger 方案来主动唤醒监测变化。
/**
* 本质上,shallowRef 是特殊的 shallowReactive,而 ref 是特殊的 reactive。
*/
let { num, addNum, numCopy } = numTagger();//提出
let state2 = reactive({//参数必须为对象
stu: [
{
id: '1',
name: 'aa',
age: '23'
},
{
id: '2',
name: 'bb',
age: '34'
},
{
id: '3',
name: 'cc',
age: '45'
},
]
})
/**
* 当我们修改了ref、reactive中的数据时,又不需要其更新视图,可以使用toRaw方法(追踪到原始数据 )
* let objCopy=toRaw(obj)
* 修改objCopy的值
*
*
* markRaw()永远不要追踪!之后追踪无效
*
*
* ref(obj。name)obj中的name变为响应式,修改name对之前的obj。name没有影响。
* toRef(obj,‘name’) 会影响到obj中的name,但是如果响应式是通过toRef创建的,修改不会触发ui更新
* ==》应用场景。。想让响应式数据和之前的数据关联起来,并且更新响应式数据后不想更新ui就使用toRef()
* ==》多重toRefs()obj对象中多个属性变化使用。
*
*
* customRef 自定义一个ref 适用于想把异步数据,假装成同步
function myRef(value){
return customRef((track,trigger)=>{
、、网络请求可以放到这里
return {
get(){
不能在这里发送网络请求:
渲染界面=》调用get=》发送网络请求=》保存数据=》更新页面=》调用get
track();//告诉Vue这个数据是需要追踪变化的
return value
},
set(newValue){
value = newValue;
trigger();//告诉ui数据发生了变化
}
}
})
}
*/
return { num, addNum, numCopy, state2 };//返回暴漏
}
}
function numTagger () {
let num = ref(0);//定义并未暴漏
let numCopy = reactive({
stus: [
{
key: 0
},
{
key: 1
},
{
key: 2
},
{
key: 3
}
]
})
function addNum () {//直接定义方法
console.log(num, numCopy)
}
return { num, addNum, numCopy }
}
</script>
复制代码
此时学习应不是太晚
看大佬视频学习Vue3.0 附一个链接 www.bilibili.com/video/BV14k…;自带倍速,句句重点,幽默诙谐。
over ?
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END