欢送关注我的公众号《人生代码》
组合式提供与注入
在之前的章节,咱们讲了选项式的 提供与注入,明天咱们持续讲组合式提供与注入。
咱们也能够在组合式 API 中应用 provide/inject。两者都只能在以后流动实例的 setup()
期间调用。
构想场景
假如咱们要重写以下代码,其中蕴含一个 TemplateM
组件,该组件应用组合式 API 为 MyMarker
组件提供用户的地位。
`<template>
<MyMarker />
</template>
<script>
import MyMarker from ‘../components/MyMarker’
export default {
components: {
MyMarker
},
provide: {
location: ‘North Pole’,
geolocation: {
longitude: 90,
latitude: 135
}
}
}
</script>
`
对于 MyMaker.vue 的代码如下:
`<template>
<div>
{{location}} – {{geolocation}}
</div>
</template>
<!– src/components/MyMarker.vue –>
<script>
export default {
inject: [‘location’, ‘geolocation’]
}
</script>
`
咱们能够看到成果如下:
下面咱们应用的选项式的提供与注入,接下来咱们就来应用组合式 API 来革新下面的代码。
组合式 provide
在 setup()
中应用 provide
时,咱们首先从 vue
显式导入 provide
办法。这使咱们可能调用 provide
时来定义每个 property。
provide
函数容许你通过两个参数定义 property:
- property 的 name (
<String>
类型) - property 的 value
应用 TemplateM
组件,咱们提供的值能够按如下形式重构:
`<template>
<MyMarker />
</template>
<script>
import MyMarker from ‘../components/MyMarker’
import {provide} from ‘vue’
export default {
components: {
MyMarker
},
setup() {
provide(‘location’, ‘North Pole’)
provide(‘geolocation’, {
longitude: 90,
latitude: 135
})
},
}
</script>
`
咱们发现就是将 provide
对象革新成 provide(key, value)
函数的模式。
组合式 inject
在 setup()
中应用 inject
时,还须要从 vue
显式导入它。一旦咱们这样做了,咱们就能够调用它来定义如何将它裸露给咱们的组件。
inject
函数有两个参数:
- 要注入的 property 的名称
- 一个默认的值 (可选)
应用 MyMarker
组件,能够应用以下代码对其进行重构:
`<template>
<div>{{location}} – {{geolocation}}</div>
</template>
<!– src/components/MyMarker.vue –>
<script>
import {inject} from ‘vue’
export default {
name: ‘MyMarker’,
setup() {
const location = inject(‘location’)
const geolocation = inject(‘geolocation’)
return {
location,
geolocation
}
}
}
</script>
`
咱们再次看看成果如下:
响应式
增加响应式
为了减少提供值和注入值之间的响应性,咱们能够在提供值时应用 ref 或 reactive。
应用 TemplateM
组件,咱们的代码能够更新如下:
`<template>
<MyMarker />
</template>
<script>
import MyMarker from ‘../components/MyMarker’
import {provide, ref, reactive} from ‘vue’
export default {
components: {
MyMarker
},
setup() {
const location = ref(‘North Pole’)
const geolocation = reactive({
longitude: 90,
latitude: 135
})
provide(‘location’, location)
provide(‘geolocation’, geolocation)
},
}
</script>
`
当初,如果这两个 property 中有任何更改,MyMarker
组件也将自动更新!
批改响应式 property
当应用响应式提供 / 注入值时,倡议尽可能,在 提供者 内放弃响应式 property 的任何更改。
例如,在须要更改用户地位的状况下,咱们最好在 TemplateM
组件中执行此操作。
`<template>
<MyMarker />
</template>
<script>
import MyMarker from ‘../components/MyMarker’
import {provide, ref, reactive} from ‘vue’
export default {
components: {
MyMarker
},
setup() {
const location = ref(‘North Pole’)
const geolocation = reactive({
longitude: 90,
latitude: 135
})
provide(‘location’, location)
provide(‘geolocation’, geolocation)
return {
location
}
},
methods: {
updateLocation() {
this.location = “hahaha”
}
}
}
</script>
`
然而,有时咱们须要在注入数据的组件外部更新注入的数据。在这种状况下,咱们倡议提供一个办法来负责扭转响应式 property。
`<template>
<MyMarker />
</template>
<script>
import MyMarker from ‘../components/MyMarker’
import {provide, ref, reactive} from ‘vue’
export default {
components: {
MyMarker
},
setup() {
const location = ref(‘North Pole’)
const geolocation = reactive({
longitude: 90,
latitude: 135
})
const updateLocation = () => {
location.value = “hahaha”
}
provide(‘location’, location)
provide(‘geolocation’, geolocation)
provide(‘updateLocation’, updateLocation)
},
}
</script>
`
`<template>
<div>{{location}} – {{geolocation}}</div>
</template>
<!– src/components/MyMarker.vue –>
<script>
import {inject} from ‘vue’
export default {
name: ‘MyMarker’,
setup() {
const location = inject(‘location’)
const geolocation = inject(‘geolocation’)
const updateLocation = inject(‘updateLocation’)
return {
location,
geolocation,
updateLocation
}
}
}
</script>
`
最初,如果要确保通过 provide
传递的数据不会被注入的组件更改,咱们倡议对提供者的 property 应用 readonly
。
`<template>
<MyMarker />
</template>
<script>
import MyMarker from ‘../components/MyMarker’
import {provide, ref, reactive, readonly} from ‘vue’
export default {
components: {
MyMarker
},
setup() {
const location = ref(‘North Pole’)
const geolocation = reactive({
longitude: 90,
latitude: 135
})
const updateLocation = () => {
location.value = “hahaha”
}
provide(‘location’, readonly(location))
provide(‘geolocation’, readonly(geolocation))
provide(‘updateLocation’, updateLocation)
},
}
</script>
`