一、依赖注入
依赖注入就是祖先组件向后代组件传递数据,使用provide()和inject()函数来实现
这两个函数只能在setup()函数中使用
在祖先组件中使用provide()函数向下传递数据
在后代组件中使用inject()函数获取上层传递传递过来的数据
//父组件<template> <div class="hello"> <h1>父组件</h1> <son></son> <button @click="colorRef='red'">红</button> <button @click="colorRef='yellow'">黄</button> <button @click="colorRef='blue'">蓝</button> </div></template><script> import { provide,ref} from 'vue' import son from './son.vue' export default { setup(){ // 向后代传数据 不会响应式更新 provide('color','yellow'); // 传递响应式的数据 let colorRef = ref('red') provide('colorRef',colorRef); return{ colorRef } }, components: { son } }</script>//子组件<template> <div class="son"> <h1>子组件</h1> <grandson></grandson> </div></template><script> import grandson from './grandson.vue' export default { setup(){ }, components: { grandson } }</script>//孙子组件<template> <div class="grandson"> <h1 :style="{color:color}">孙组件1</h1> <h1 :style="{color:colorRef}">孙组件1</h1> </div></template><script> import { inject} from 'vue' export default { setup(){ const color = inject('color'); const colorRef = inject('colorRef'); return { color, colorRef } } }</script>
二、模板Refs
通过ref()函数还可以引用页面上的元素或组件
步骤:
1、在setup()中创建一个ref()对象并返回
2、在页面上为元素添加ref属性,并设置属性值与创建的ref对象的名称相同
3、当前页面渲染完成后(onMounted),可以通过该ref对象获取到页面中对应的dom元素
//refs.vue<template> <div> <h1 ref="hRef">这是一段文字,需要获取</h1> <hr> <compRefs ref="comRef" :onChanges="onChanges"></compRefs> </div></template><script> import {ref,onMounted} from 'vue' import compRefs from './compRef.vue' export default { setup(){ // 创建一个值为null的ref对象并返回 const hRef = ref(null); // 获取组件 const comRef = ref(null); // 在页面渲染完成后 onMounted(()=>{ console.log(hRef.value) //DOM对象 console.log(comRef.value) //DOM对象 hRef.value.style.color = 'red' comRef.value.onChange(); //父组件调用子组件方法 }) let onChanges = ()=>{ hRef.value.innerHTML = ' hello' } return{ hRef, comRef, onChanges } }, components:{ compRefs } }</script>//compRefs.vue<template> <div> <p>{{msg}}</p> <button @click="childMethod">点击</button> </div></template><script> import {ref,onMounted} from 'vue' export default { props:{ onChanges: Function }, setup(props){ const msg = ref('welcome'); let onChange = ()=>{ msg.value += ' hello' } let childMethod = ()=>{ console.log(props) props.onChanges(); //子组件调用父组件方法 } onMounted(()=>{ }) return{ msg, onChange, childMethod } } }</script>
三、响应式系统工具集
1、isRef
检查一个值是否为一个 ref 对象。
import{ref,reactive,isRef} from 'vue'export default { setup(){ let num = ref(5); let single = 5; let obj = reactive({ age:5 }) let numFlag = isRef(num); //true let singleFlag = isRef(single); //false let objFlag = isRef(obj); //false return{ numFlag, singleFlag, objFlag } },}
2、isReactive
检查一个对象是否是由 reactive 创建的响应式代理。
import{ref,reactive,isReactive} from 'vue'export default { setup(){ let num = ref(5); let single = {num:5}; let obj = reactive({ age:5 }) let numFlag = isReactive(num); //false let singleFlag = isReactive(single); //false let objFlag = isReactive(obj); //true return{ numFlag, singleFlag, objFlag } },}
3、isReadonly
检查一个对象是否是由 readonly 创建的只读代理。
import {ref,reactive,isReadonly,readonly} from 'vue'export default { setup(){ let num = ref(5); let single = readonly({ name:'tom' }); let obj = reactive({ age:5 }) let numFlag = isReadonly(num); //false let singleFlag = isReadonly(single); //true let objFlag = isReadonly(obj); //false return{ numFlag, singleFlag, objFlag } },}
4、isProxy
检查一个对象是否是由 reactive 还是 readonly 方法创建的代理。
import {ref,reactive,isProxy,readonly} from'vue'export default { setup(){ let num = ref(5); let single = readonly({ name:'tom' }); let obj = reactive({ age:5 }) let numFlag = isProxy(num); //false let singleFlag = isProxy(single); //true let objFlag = isProxy(obj); //true return{ numFlag, singleFlag, objFlag } },}
5、unref
如果参数是一个 ref 则返回它的 value,否则返回参数本身。它是 val = isRef(val) ? val.value : val 的语法糖。注意:unref都是小写的
import {ref,reactive,unref,readonly} from 'vue'export default { setup(){ let num = ref(5); let single = readonly({ name:'tom' }); let obj = reactive({ age:5 }) let numFlag = unref(num); //5 let singleFlag = unref(single); //{name:'tom'} let objFlag = unref(obj); //{age:5} return{ numFlag, singleFlag, objFlag } },}
6、toRef
用来为一个 reactive 对象的属性创建一个 ref。这个 ref 可以被传递并且能够保持响应性,可以被传递。
<template> <div> <p>obj:{{obj.num}}</p> <p>objFlag:{{objFlag}}</p> <button @click="onChange">修改num</button> </div></template><script> import {reactive,toRef} from 'vue' export default { setup(){ let obj = reactive({ age:5, num:1 }) //只能是reactive对象中的一个属性 let objFlag = toRef(obj,'num'); const onChange = ()=>{ objFlag.value = 10; console.log(obj.num) //10 console.log(objFlag.value) //10 } return{ objFlag, obj, onChange } }, }</script>
7、toRefs
用来将reactive对象转换为一个普通对象,但该普通对象的每个 属性都是一个 ref ,并且这个ref具有响应式,可以被传递。
<template> <div> <p>obj:{{obj.name}}</p> <p>obj:{{obj.num}}</p> <p>objFlag:{{objFlag}}</p> <button @click="onChange">修改num</button> </div></template><script> import {reactive,toRefs} from 'vue' export default { setup(){ let obj = reactive({ name:'tom', num:1 }) let objFlag = toRefs(obj); const onChange = ()=>{ objFlag.name.value = 'Json'; objFlag.num.value = 10; console.log(obj.num) //10 console.log(obj.name) //Json } return{ objFlag, obj, onChange } }, }</script>
欢迎关注公众号(web学习吧),一起学习进步: