• 【Vue3】响应性数据_2



    【Vue3】响应性数据_1



    readonly & shallowReadonly

    • 格式:readonly(响应性数据)
    • readonly 修饰的数据,不可被修改
    <template>
        <p>obj.name: {{ obj.name }}p>
        <button @click="obj.name += '!'">修改 obj.namebutton>
        <hr />
        <p>reObj.name: {{ reObj.name }}p>
        
        <button @click="reObj.name += '!'">修改 reObj.namebutton>
    template>
    
    <script>
    import { reactive, readonly } from "vue";
    export default {
        name: "App",
        setup() {
            let obj = reactive({ name: "superman" });
            let reObj = readonly(obj);
            return { obj, reObj };
        },
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    shallowReadonly

    • 格式:shallowReadonly(响应性数据)
    • shallowReadonly 修饰的数据,浅层数据不可被修改,但深层数据可以被修改
    <template>
        
        <p>obj.name: {{ obj.name }}p>
        <button @click="obj.name += '!'">修改 obj.namebutton>
        <p>reObj.name: {{ reObj.name }}p>
        
        <button @click="reObj.name += '!'">修改 reObj.namebutton>
        <hr />
        
        <p>obj.girlfriend.name: {{ obj.girlfriend.name }}p>
        <button @click="obj.girlfriend.name += '!'">
            修改 obj.girlfriend.name
        button>
        <p>reObj.girlfriend.name: {{ reObj.girlfriend.name }}p>
        
        <button @click="reObj.girlfriend.name += '!'">
            修改 reObj.girlfriend.name
        button>
    template>
    
    <script>
    import { reactive, shallowReadonly } from "@vue/reactivity";
    export default {
        name: "App",
        setup() {
            let obj = reactive({
                name: "superman",
                girlfriend: { name: "superwoman" },
            });
            let reObj = shallowReadonly(obj);
            return { obj, reObj };
        },
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    toRaw & markRaw

    • reactive 修饰的响应式数据变为普通数据:toRaw(响应式数据)
    • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,都不会引起页面更新
    <template>
        <p>obj.name: {{ obj.name }}p>
        <button @click="obj.name += '!'">修改 obj.namebutton>
        <hr />
        <p>raObj.name: {{ raObj.name }}p>
        <button @click="raObj.name += '!'">修改 raObj.namebutton>
    template>
    
    <script>
    import { reactive, toRaw } from "@vue/reactivity";
    export default {
        name: "App",
        setup() {
            let obj = reactive({ name: "superman" });
            let raObj = toRaw(obj);
            return { obj, raObj };
        },
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以发现,toRaw 修饰的数据,会变为普通数据,修改普通数据,页面不会重新渲染
    但是数据是已经被改变了的,页面如果重新渲染的话,还是会显示最新数据

    markRaw

    • 用于标记一个对象数据,使其永远不能成为一个响应式数据
    <template>
        <p>obj: {{ obj }}p>
        <p>
            第一步: 选择接收数据
            <button @click="changeObj">changeObjbutton> |
            <button @click="maChangeObj">maChangeObjbutton>
        p>
        <p>
            第二步: 选择改变的数据
            <button @click="changeName">changeNamebutton> |
            <button @click="changeGirl">changeGirlbutton>
        p>
    template>
    
    <script>
    import { markRaw, reactive } from "vue";
    export default {
        name: "App",
        setup() {
            // 定义响应式数据
            let obj = reactive({ name: "superman" });
    
            // 假设通过 Ajax 接收一个对象数据
            function changeObj() {
                let girl = { name: "superwoman" };
                obj.girlfriend = girl;
            }
    
            // 假设通过 Ajax 接收一个对象数据,并用 markRaw 修饰
            function maChangeObj() {
                let girl = markRaw({ name: "superwoman" });
                obj.girlfriend = girl;
            }
    
            // 改变接收的数据
            function changeGirl() { obj.girlfriend.name += "!" }
    
            // 改变原数据
            function changeName() { obj.name += "!" }
    
            return {
                obj,
                changeObj,
                changeGirl,
                maChangeObj,
                changeName,
            };
        },
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    可以发现,正常接收的对象数据,是可以被修改并渲染到页面上的;
    但是,用 markRaw 修饰的对象数据,数据会被修改,但不会被渲染到页面上(当然,页面重新渲染时,还是会显示最新数据)

    provide & inject

    • provide 用于传递数据给后代组件:provide("XXX", 数据值)
    • inject 用于接收祖先组件传递的数据:inject("XXX")
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    此时,不论在哪个组件修改数据,数据都会被修改成功,并渲染到页面上

    • 如果想后代组件无法修改并渲染数据,可以使用 toRaw 修饰数据:

      此时,后代组件无法修改并渲染接收的数据,但是数据是已经被修改了的,页面重新渲染的话,还是会显示最新数据

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 如果不允许修改数据,可以使用 readonly 修饰数据:

      此时,只有父级组件可以修改数据,后代组件不能修改接收的数据

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    判断响应式数据

    1. isRef - 检查一个值是否由 ref 修饰
    2. isReactive - 检查一个对象是否由 reactive 修饰
    3. isReadonly - 检查一个对象是否由 readonly 修饰
    4. isProxy - 检查一个对象是否由 reactive / readonly 修饰
    <script>
    import { isProxy, isReactive, isReadonly, isRef, reactive, readonly, ref } from 'vue';
    export default {
        name: "App",
        setup() {
            let person = reactive({ name: "superman" });
            let num = ref(0);
            let readonly_num = readonly(num);
    
            console.log(isReactive(person)); // true
            console.log(isRef(num)); // true
            console.log(isReadonly(readonly_num)); // true
            console.log(isProxy(readonly_num)); // true
        },
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    排序算法:插入排序
    前端工程化
    【集成学习】对已训练好的模型进行投票
    C++正则表达式
    QMainWindow
    CUDA中Occupancy相关知识
    深入剖析多重背包问题(下篇)
    软体机器人接触压力分析
    真正“搞”懂HTTPS协议15之安全的定义
    shell选择结构(if)
  • 原文地址:https://blog.csdn.net/Superman_H/article/details/126276553