Vue3 组合API
 一、组合式 API (Compositon API)
- 官网:https://v3.cn.vuejs.org/guide/composition-api-introduction.html 
- 官网:https://v3.cn.vuejs.org/guide/composition-api-setup.html 
- Vue3 新增的开发模式,把条条框框的js代码(data、methods、components、props),都放到一起 
- 使用传统的option配置方法写组件的时候问题,随着业务复杂度越来越高,代码量会不断的加大;由于相关业务的代码需要遵循option的配置写到特定的区域,导致后续维护非常的复杂,同时代码可复用性不高,而composition-api就是为了解决这个问题而生的。 
- Composition API字面意思是组合API,它是为了实现基于函数的逻辑复用机制而产生的。主要思想是,我们将它们定义为从新的 setup 函数返回的JavaScript变量,而不是将组件的功能(例如state、methods、computed等)定义为对象属性。 
 二、setup 方法
- setup()函数是vue3中专门新增的方法,可以理解为- Composition Api的入口
- Vue3.2版本新写法:除以下2种情况外,都应优先使用- script setup语法- 需要在非单文件组件中使用组合式 API时。
- 需要在基于选项式 API的组件中集成基于组合式API的代码时。
 
- 需要在非单文件组件中使用组合式 
 1、setup 使用
// 打开 src/Views/Home.vue
// 1、创建setup方法
// 1.1、创建一个常量
// 1.2、无须 return 返回
<template>
    <div>
        <div>{{ data }}</div>
    </div>
</template>
<script setup>
    const data = 10;
</script>
// 打开 src/Views/Home.vue
// 1、创建setup方法
// 1.1、创建一个常量
// 1.2、必须 return 返回,才能给模版使用
<template>
    <div>
        <div>{{ data }}</div>
    </div>
</template>
<script>
export default {
    name: "Home",
    setup() {
        const data = 10;
        return {
            data
        }
    }
};
</script>
 2、setup 使用 js 方法
// 打开 src/Views/Home.vue
// 1、点击方法,不能使用
<template>
    <div>
        <div>{{ data }}</div>
        <button @click="data++">加++</button>
    </div>
</template>
<script setup>
    const data = 10;
</script>
//  2、reactive 返回对象的响应式副本
//  所有的 api 都是方法、函数
<template>
    <div>
        <div>{{ data.number }}</div>
        //  2.2、使用 reactive 方法创建的数据,就能相应了
        <button @click="data.number++">加++</button>
        //  2.3、执行方法
        <button @click="jian()">减++</button>
    </div>
</template>
<script setup>
    // 2.1、引入 reactive 方法
    import {reactive} from 'vue';
    // 2.2、使用reactive方法,创建数据
    const data = reactive({
        number : 10
    })
    // 2.4、创建方法
    const jian = () => {
        data.number--;
    }
</script>
// 打开 src/Views/Home.vue
// 1、点击方法,不能使用
<template>
    <div>
        <div>{{ data }}</div>
        <button @click="data++">加++</button>
    </div>
</template>
<script>
export default {
    name: "Home",
    setup() {
        const data = 10;
        return {
            data
        }
    }
};
</script>
//  2、reactive 返回对象的响应式副本
//  所有的 api 都是方法、函数
<template>
    <div>
        <div>{{ data.number }}</div>
        //  2.2、使用 reactive 方法创建的数据,就能相应了
        <button @click="data.number++">加++</button>
        //  2.3、执行方法
        <button @click="jian()">减++</button>
    </div>
</template>
<script>
// 2.1、引入 reactive 方法
import {reactive} from 'vue';
export default {
    name: "Home",
    setup() {
        // 2.2、使用reactive方法,创建数据
        const data = reactive({
            number : 10
        })
        // 2.4、创建方法
        const jian = () => {
            data.number--;
        }
        // 2.5、方法也要return
        return {
            data,
            jian
        }
    }
};
</script>
 3、setup 计算属性
<template>
    <div>
        <div>{{ data.number }}</div>
        // 1.3、使用数据
        <div>{{ data.jisuan }}</div>
        <button @click="data.number++">加++</button>
        <button @click="jian()">减++</button>
    </div>
</template>
<script setup>
    // 1.1、引入 computed 方法
    import {reactive,computed} from 'vue';
    // 1.2、computed 计算属性
    const data = reactive({
        number : 10,
        jisuan : computed( ()=>data.number * data.number )
    })
    const jian = () => {
        data.number--;
    }
</script>
<template>
    <div>
        <div>{{ data.number }}</div>
        // 1.3、使用数据
        <div>{{ data.jisuan }}</div>
        <button @click="data.number++">加++</button>
        <button @click="jian()">减++</button>
    </div>
</template>
<script>
// 1.1、引入 computed 方法
import {reactive,computed} from 'vue';
export default {
    name: "Home",
    setup() {
        // 1.2、computed 计算属性
        const data = reactive({
            number : 10,
            jisuan : computed( ()=>data.count * data.count )
        })
        const jian = () => {
            data.number--;
        }
        return {
            data,
            jian
        }
    }
};
</script>
 4、setup 里面没有 this
// 1、setup 方法里没 this,因为它是最先运行的
<template>
    <div>
        <div>{{ name }}</div>
    </div>
</template>
<script>
export default {
    name: "Home",
    data() {
        return {
            name: "php中文网"
        }
    },
    // 1.1、打印结果是 setup 先运行
    beforeCreate() {
        console.log("beforeCreate");
        // 1.2、这个打印this.name,空值,但不报错,说明有this
        console.log(this.name);
    },
    created() {
        console.log("created");
        // 1.3、这个打印this.name,就有值,说明已经运行了data
        console.log(this.name);
    },
    beforeMount() {
        console.log("beforeMount");
    },
    setup() {
        console.log("setup");
        // 1.4、这个打印this.name,就会报错,说明没有this,就是这样设计的
        console.log(this.name);
    }
};
</script>
三、组件
1、组件传值
// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        # 1.1、使用one组件,传2个值,前2个值会被props接收,后2个值不会被props接收
        <one one="1111" two="2222" three="3333" four="4444"></one>
    </div>
</template>
<script setup>
import One from "../components/One.vue";
</script>
// 2、打开组件 src/components/One.vue
<template>
    <div>
        one = {{ one }} 
        two = {{ two }} 
    </div>
</template>
<script setup>
# 2.2、引入 useAttrs 方法
import { useAttrs } from 'vue'
const attrs = useAttrs()
# 2.3、没有被props接收的数据,未声明的数据。
console.log(attrs);
# 2.4、defineProps 接收传值
const props = defineProps(['one','two'])
# 2.5、defineProps 接收传值,并设置属性
const props = defineProps({
    one: {
        type: String
    },
    two : {
        type: String
    }
})
</script>
// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        # 1.1、使用one组件,传4个值,前2个值会被props接收,后2个值不会被props接收
        <one one="1111" two="2222" three="3333" four="4444"></one>
    </div>
</template>
<script>
import One from "../components/One.vue";
export default {
    components: {
        One
    }
};
</script>
# 2、打开组件 src/components/One.vue
<template>
    <div>
        one = {{ one }} 
        two = {{ two }} 
    </div>
</template>
<script>
    export default {
        name: "One",
        # 2.2、接收2个传值
        props: {
            one: {
                type: String,
            },
            two: {
                type: String,
            }
        },
        # 2.3、在setup里不能使用this,就无法使用props的数据
        # 2.4、setup方法,第一个参数:就是props里接收的数据,参数名可以更改
        # 2.5、第二个参数:没有被props接收的数据,未声明的数据。
        setup(props,context) { // setup(props,{attrs,slots}) 也可以解构赋值 展开
            console.log(props);
            console.log(context); // 里面有attrs参数,就是未接收的数据
            console.log(context.attrs); // Attribute (非响应式对象,等同于 $attrs)
        }
    };
</script>
2、插槽
// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        <one one="1111"></one>
        <one one="1111">
            # 1.1、插槽传值
            <div>这是插槽被替换了</div>
        </one>
    </div>
</template>
<script setup>
import One from "./components/One.vue";
</script>
// 2、打开组件 src/components/One.vue
<template>
    <div>
        one = {{ one }}
        # 2.2、插槽
        <slot>插槽</slot>
    </div>
</template>
<script setup>
# 2.3、引入插槽方法
import { useSlots } from 'vue'
const slots = useSlots()
# 2.4、插槽 (非响应式对象,等同于 $slots)
console.log(slots)
# 2.5、default() 获取外面传的子内容,必须父组件传了插槽,才有方法。
console.log(slots.default())
const props = defineProps(['one']);
</script>
// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        <one one="1111"></one>
        <one one="1111">
            # 1.1、插槽传值
            <div>这是插槽被替换了</div>
        </one>
    </div>
</template>
<script>
import One from "../components/One.vue";
export default {
    components: {
        One
    }
};
</script>
// 2、创建个组件 src/components/One.vue
<template>
    <div>
        one = {{ one }}
        # 2.1、插槽
        <slot>插槽</slot>
    </div>
</template>
<script>
    export default {
        props: {
            one: {
                type: String,
            }
        },
        setup(props,context) {
            // 2.2、插槽 (非响应式对象,等同于 $slots)
            console.log(context.slots);
            // 2.3、default() 获取外面传的子内容,必须父组件传了插槽,才有方法。
            console.log(context.slots.default());
        }
    };
</script>
3、调用父组件方法
// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        # 1.1、传方法给子组件
        <one one="1111" @on-confirm="onConfirm"></one>
    </div>
</template>
<script setup>
import One from "./components/One.vue";
// 1.2、父组件方法
const onConfirm = (e) => {
  console.log(e);
}
</script>
// 2、打开组件 src/components/One.vue
<template>
    <div>
        one = {{ one }} 
        <slot>插槽</slot>
        # 2.1、点击子组件事件
        <button @click="handleConfirm">按钮</button>
    </div>
</template>
<script setup>
const props = defineProps(['one','two'])
2.2、defineEmits 接收方法
const emit = defineEmits(['on-confirm'])
const handleConfirm = () => {
    emit('on-confirm','调用父组件方法并传值')
}
</script>
// 1、Home.vue 文件引入 One.vue组件
<template>
    <div>
        <one one="1111" @on-confirm="onConfirm"></one>
    </div>
</template>
<script>
import One from "./components/One.vue";
export default {
    components: {
        One
    },
    setup(){
        // 1.2、父组件方法
        const onConfirm = (e) => {
            console.log(e);
        }
        return {
          onConfirm
        }
    }
};
</script>
// 2、创建个组件 src/components/One.vue
<template>
    <div>
        one = {{ one }} 
        <slot>插槽</slot>
        <button @click="handleConfirm">按钮</button>
    </div>
</template>
<script>
export default {
        props: {
            one: {
                type: String,
            }
        },
        setup(props,context) {
            console.log(context.emit); // 触发事件 (方法,等同于 $emit)
            const handleConfirm = () => {
                context.emit('on-confirm','调用父组件方法并传值')
            }
            return {
                handleConfirm
            }
        }
    };
</script>
 四、常用 API
1、数据非响应式
# setup里不能使用this,数据也不能改变(非响应式)
<template>
    <div>
        <div>{{ num }}</div>
        <button @click="num++">加++</button>
    </div>
</template>
<script setup>
    let num = 10
</script>
# setup里不能使用this,数据也不能改变(非响应式)
<template>
    <div>
        <div>{{ num }}</div>
        <button @click="num++">加++</button>
    </div>
</template>
<script>
export default {
    setup() {
        let num = 10
        return {
            num
        }
    }
};
</script>
 2、ref方法
- ref方法接受一个内部值并返回一个响应式且可变的 ref 对象
<template>
    <div>
        <div>{{ num }}</div>
        <button @click="num++">加++</button>
        <button @click="add()">js加++</button>
    </div>
</template>
<script setup>
import {ref} from 'vue';
# 1.1、使用ref方法处理后,就变为响应式了
let num = ref(10)
# 1.2、用方法处理,没效果
const add = () => {
    num++
    # 1.3、打印后,发现里面有个value
    console.log(num)
    # 1.4、所以要使用 .value
    num.value++
}
</script>
<template>
    <div>
        <div>{{ num }}</div>
        <button @click="num++">加++</button>
        <button @click="add()">js加++</button>
    </div>
</template>
<script>
import {ref} from 'vue';
export default {
    setup() {
        # 1.1、使用ref方法处理后,就变为响应式了
        let num = ref(10)
        # 1.2、用方法处理,没效果
        const add = () => {
            num++
            # 1.3、打印后,发现里面有个value
            console.log(num)
            # 1.4、所以要使用 .value
            num.value++
        }
        return {
            num,
            add
        }
    }
};
</script>
3、reactive 方法
- reactive 函数接收一个普通对象,返回一个响应式的数据对象
<template>
    <div>
        <div>{{ data.num }}</div>
        <button @click="add()">加++</button>
    </div>
</template>
<script>
import { ref, reactive } from "vue";
# 1.1、reactive 创建数据
let data = reactive({
    num: 10
})
const add = () => {
    # 1.2、打印后,显示对象数据
    console.log(data)
    data.num++
}
# 1.3、返回值在模版中,会多一层 {{data.num}},之前是 {{num}}
</script>
<template>
    <div>
        <div>{{ data.num }}</div>
        <button @click="add()">加++</button>
    </div>
</template>
<script>
import { ref, reactive } from "vue";
export default {
    setup() {
        # 1.1、reactive 创建数据
        let data = reactive({
            num: 10
        })
        const add = () => {
            # 1.2、打印后,显示对象数据
            console.log(data)
            data.num++
        }
        # 1.3、返回值在模版中,会多一层 {{data.num}},之前是 {{num}}
        return {
            data,
            add
        }
    }
};
</script>
 4、toRefs方法
- toRefs方法接收一个对象作为参数,它会遍历对象身上的所有属性,然后挨个调用toRef执行
# 1、使用解构赋值,就可以减少一层,但是会导致 数据不能相应
<template>
    <div>
        <div>{{ data.num }}</div>
        <div>{{ num }}</div>
        # 1.1、点击后,{{num}}不变,不是响应式的了
        <button @click="add()">加++</button>
    </div>
</template>
<script setup>
# 1.2、引入 toRefs 方法:返回时转换为ref,在不丢失响应性的情况下对返回的对象进行解构/展开
import { reactive,toRefs } from "vue";
let data = reactive({
    num: 10,
    name : "欧阳克"
})
const add = () => {
    data.num++
}
const { name,name } = data
// toRefs 返回时转换为ref
const { name,name } = toRefs(data)
</script>
# 1、使用解构赋值,就可以减少一层,但是会导致 数据不能相应
<template>
    <div>
        <div>{{ data.num }}</div>
        <div>{{ num }}</div>
        # 1.1、点击后,{{num}}不变,不是响应式的了
        <button @click="add()">加++</button>
    </div>
</template>
<script>
# 1.2、引入 toRefs 方法:返回时转换为ref,在不丢失响应性的情况下对返回的对象进行解构/展开
import { reactive,toRefs } from "vue";
export default {
    setup() {
        let data = reactive({
            num: 10,
            name : "欧阳克"
        })
        const add = () => {
            data.num++
        }
        return {
            data,
            add,
            ...data,
            ...toRefs(data) // toRefs 返回时转换为ref
        }
    }
};
</script>
 5、readonly方法
- readonly方法接受一个对象 (响应式或纯对象) 或 ref 并返回原始对象的只读代理
<template>
    <div>
        <div>{{ read.num }}</div>
        <button @click="add()">加++</button>
    </div>
</template>
<script>
import { reactive, ref, readonly } from "vue";
let data = reactive({
    num: 10,
    name: "欧阳克",
});
# 1、readonly 方法把data数据,设置为只读
const read = readonly(data);
read.num++; // 会报错
const add = () => {
    read.num++; // 会报错
};
</script>
<template>
    <div>
        <div>{{ read.num }}</div>
        <button @click="add()">加++</button>
    </div>
</template>
<script>
import { reactive, ref, readonly } from "vue";
export default {
    setup() {
        let data = reactive({
            num: 10,
            name: "欧阳克",
        });
        # 1、readonly 方法把data数据,设置为只读
        const read = readonly(data);
        read.num++; // 会报错
        const add = () => {
            read.num++; // 会报错
        };
        return {
            read,
            add,
        };
    }
};
</script>
 6、isRef方法
- isRef方法检查值是否为一个 ref 对象
<template>
    <div>{{data}}</div>
</template>
<script setup>
import { ref, isRef } from "vue";
# 1、如果是ref创建的数据,isRef就会返回true
let data = ref(10);
console.log(isRef(data));
</script>
<template>
    <div>{{data}}</div>
</template>
<script>
import { ref, isRef } from "vue";
export default {
    setup() {
        # 1、如果是ref创建的数据,isRef就会返回true
        let data = ref(10);
        console.log(isRef(data));
        return {
            data
        };
    }
};
</script>
 五、侦听 API
 1、watch方法侦听数据的改变
<template>
    <div>
        <div>a = {{ a }} b = {{ b }}</div>
        <button @click="a++">a++</button>
        <button @click="b++">b++</button>
    </div>
</template>
<script setup>
import { reactive, ref, watch } from "vue";
let a = ref(0)
let b = ref(0)
# 1.1、默认情况下,它有惰性的,只有当被侦听的源发生变化时才执行回调
watch(() => {
    console.log(a)
    console.log(a.value)
    console.log(b.value)
})
# 1.2、侦听单个数据源
watch(a, () => {
    console.log(a);
    console.log(a.value);
});
# 1.3、新老值
watch(a, (new_a, old_a) => {
    console.log("新:" + new_a);
    console.log("老:" + old_a);
});
# 1.4、侦听多个数据源
watch([a,b], () => {
    console.log(a.value);
    console.log(b.value);
});
# 1.5、新老值
watch([a,b], ([new_a,new_b],[old_a,old_b]) => {
    console.log('a新值:'+new_a+',a老值:'+old_a);
    console.log('b新值:'+new_b+',b老值:'+old_b);
});
</script>
<template>
    <div>
        <div>a = {{ a }} b = {{ b }}</div>
        <button @click="a++">a++</button>
        <button @click="b++">b++</button>
    </div>
</template>
<script>
import { reactive, ref, watch } from "vue";
export default {
    setup() {
        let a = ref(0)
        let b = ref(0)
        # 1.1、默认情况下,它有惰性的,只有当被侦听的源发生变化时才执行回调
        watch(() => {
            console.log(a)
            console.log(a.value)
            console.log(b.value)
        })
        # 1.2、侦听单个数据源
        watch(a, () => {
            console.log(a);
            console.log(a.value);
        });
        # 1.3、新老值
        watch(a, (new_a, old_a) => {
            console.log("新:" + new_a);
            console.log("老:" + old_a);
        });
        # 1.4、侦听多个数据源
        watch([a,b], () => {
            console.log(a.value);
            console.log(b.value);
        });
        # 1.5、新老值
        watch([a,b], ([new_a,new_b],[old_a,old_b]) => {
            console.log('a新值:'+new_a+',a老值:'+old_a);
            console.log('b新值:'+new_b+',b老值:'+old_b);
        });
        return {
            a,
            b
        }
    }
};
</script>
 2、watch方法侦听对象
<template>
    <div>
        <input type="text" v-model="name"/><br>
        <input type="text" v-model="age"/><br>
    </div>
</template>
<script>
import { reactive, ref, watch, toRefs } from "vue";
const obj = reactive({
    name : "欧阳克",
    age : 38
})
# 1.1、对象数据改变,会被侦听。侦听对象里的全部数据
watch(obj, () => {
    console.log(obj.name);
    console.log(obj.age);
})
    
# 1.2、侦听对象里的单个数据
# 1.2.1、之间写对象里的数据,会报错
watch(obj.age, () => {
    console.log(obj.age);
})
# 1.2.2、参数写成方法
watch(()=>obj.age, () => {
    console.log(obj.age);
})
# 1.2.3、多个参数
watch([()=>obj.age,()=>obj.name], () => {
    console.log(obj.age);
    console.log(obj.name);
})
</script>
<template>
    <div>
        <input type="text" v-model="name"/><br>
        <input type="text" v-model="age"/><br>
    </div>
</template>
<script>
import { reactive, ref, watch, toRefs } from "vue";
export default {
    setup() {
        const obj = reactive({
            name : "欧阳克",
            age : 38
        })
        # 1.1、对象数据改变,会被侦听。侦听对象里的全部数据
        watch(obj, () => {
            console.log(obj.name);
            console.log(obj.age);
        })
            
        # 1.2、侦听对象里的单个数据
        # 1.2.1、之间写对象里的数据,会报错
        watch(obj.age, () => {
            console.log(obj.age);
        })
        # 1.2.2、参数写成方法
        watch(()=>obj.age, () => {
            console.log(obj.age);
        })
        # 1.2.3、多个参数
        watch([()=>obj.age,()=>obj.name], () => {
            console.log(obj.age);
            console.log(obj.name);
        })
        return {
            ...toRefs(obj)
        }
    }
};
</script>
 3、watchEffect方法
- watchEffect方法侦听数据的改变,默认会执行一次
<template>
    <div>
        <div>a = {{ a }} b = {{ b }}</div>
        <button @click="a++">a++</button>
        <button @click="b++">b++</button>
    </div>
</template>
<script>
import { reactive, ref, watch, watchEffect } from "vue";
let a = ref(1)
let b = ref(2)
watchEffect(() => {
    console.log(a)
    console.log(a.value)
    console.log(b.value)
})
</script>
<template>
    <div>
        <div>a = {{ a }} b = {{ b }}</div>
        <button @click="a++">a++</button>
        <button @click="b++">b++</button>
    </div>
</template>
<script>
import { reactive, ref, watch, watchEffect } from "vue";
export default {
    setup() {
        let a = ref(1)
        let b = ref(2)
        watchEffect(() => {
            console.log(a)
            console.log(a.value)
            console.log(b.value)
        })
        return {
            a,
            b
        }
    }
};
</script>
六、生命周期
| 生命周期 | 作用 | Setup生命周期 | 
|---|---|---|
| beforeCreate | 在创建组件之前调用 | use setup | 
| created | 组件创建完成调用 | use setup | 
| beforeMount | 模版挂载之前调用 | onBeforeMount | 
| mounted | 模版挂载完成调用 | onMounted | 
| beforeUpdate | 改变内容之前调用 | onBeforeUpdate | 
| update | 改变内容之后调用 | onUpdate | 
| beforeUnmount | 组件销毁之前调用 | onBeforeUnmount | 
| unmounted | 组件销毁之后调用 | onUnmounted | 
<template>
    <div>欧阳克</div>
</template>
<script>
import { onBeforeMount, onMounted } from "vue";
onBeforeMount( ()=>{
    console.log('onBeforeMount 模版挂载之前调用');
} )
onMounted( ()=>{
    console.log('onMounted 模版挂载完成调用');
} )
</script>
<template>
    <div>欧阳克</div>
</template>
<script>
import { onBeforeMount, onMounted } from "vue";
export default {
    setup() {
        onBeforeMount( ()=>{
            console.log('onBeforeMount 模版挂载之前调用');
        } )
        onMounted( ()=>{
            console.log('onMounted 模版挂载完成调用');
        } )
    }
};
</script>
七、在组合API中provide和inject使用
# 1、src/Views/Home.vue 文件
<template>
    <div>
        <div>{{ name }}</div>
        <one></one>
    </div>
</template>
<script>
import { ref } from "vue";
import One from "../components/One";
export default {
    components: {
        One
    },
    data() {
        return {
            name: ref("欧阳克")
        }
    },
    provide() {
        return {
            name: "欧阳克",
            name: this.name // 还可以用data里的变量
        }
    }
};
</script>
# 1.1、创建儿子文件:src/components/One.vue文件
<template>
    <div>
        <div>这是one</div>
        <two></two>
    </div>
</template>
<script>
import Two from "../components/Two";
export default {
    name: "One",
    components: {
        Two
    }
};
</script>
  
# 1.2、创建孙子文件:src/components/Two.vue文件
# 1.2.1、使用 inject 参数,获取它爷爷的数据
<template>
    <div>
        <div>这是two {{ name }}</div>
    </div>
</template>
<script>
export default {
    name: "Two",
    inject: ["name"]
};
</script>
----------------------------------------
# 2、在组合API中provide和inject使用
# 2.1、src/Views/Home.vue 文件
<template>
    <div>
        <div>{{ name }}</div>
        <one></one>
    </div>
</template>
<script>
import { ref, provide } from "vue";
import One from "../components/One";
export default {
    components: {
        One
    },
    setup() {
        let name = ref("欧阳克");
        provide("name", name)
    }
};
</script>
# 2.2、src/components/Two.vue文件
<template>
  <div>
    <div>这是two {{ name }}</div>
  </div>
</template>
<script>
import { inject } from "vue";
export default {
    name: "Two",
    setup() {
        let name = inject("name");
        return {
            name
        }
    },
};
</script>
八、路由
1、获取路由
- useRoute方法获取路由信息
- useRouter方法跳转新页面,并携带参数
<template>
    <div>
        <div>欧阳克</div>
    </div>
</template>
<script>
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
console.log(route);
console.log(route.fullPath);
console.log(route.query);
console.log(route.params);
console.log(router);
router.push({
    path : "/new",
    query: { id:10 }
});
</script>
<template>
    <div>
        <div>欧阳克</div>
    </div>
</template>
<script>
import { useRoute, useRouter } from "vue-router";
export default {
    setup() {
        const route = useRoute();
        const router = useRouter();
        console.log(route);
        console.log(route.fullPath);
        console.log(route.query);
        console.log(route.params);
        console.log(router);
        
        router.push({
            path : "/new",
            query: { id:10 }
        });
    }
};
</script>
2、vuex状态管理器
- useStore方法获取状态管理器
<template>
    <div>
        <div>欧阳克</div>
    </div>
</template>
<script>
import { useStore } from "vuex";
const store = useStore();
console.log(store);
console.log(store.state.num);
</script>
# 1、打开 /src/store/index.js 文件
import { createStore } from "vuex";
const state = {
    num: 10,
};
export default createStore({
    state
});
<template>
    <div>
        <div>欧阳克</div>
    </div>
</template>
<script>
import { useStore } from "vuex";
export default {
    setup() {
        const store = useStore();
        console.log(store);
        console.log(store.state.num);
    }
};
</script>
# 1、打开 /src/store/index.js 文件
import { createStore } from "vuex";
const state = {
    num: 10,
};
export default createStore({
    state
});

