在vue2我写过一篇关于provide,inject的文章,但是的确在项目中用的很少,所以写的很简单,但是这个传值方法还是有我们需要注意的地方
在vue2中其实通过provide和inject来进行传值的话,这些传的值是不具备响应式的,意思在祖组件中传一个值到孙组件中,这个值在孙组件中进行更改在祖组件中是感应不到的,但是这也是vue官网故意设计成这样的,不然在多人开发的项目上这个数据就很难维护了。
在vue2中要达到响应式 我们可以用计算属性
app.component('todo-list', {
// ...
provide() {
return {
todoLength: Vue.computed(() => this.todos.length)
}
}
})
app.component('todo-list-statistics', {
inject: ['todoLength'],
created() {
console.log(`Injected property: ${this.todoLength.value}`) // > Injected property: 5
}
})
这是官网vue2写法
<!-- src/components/MyMap.vue -->
<template>
<MyMarker />
</template>
<script>
import MyMarker from './MyMarker.vue'
export default {
components: {
MyMarker
},
provide: {
location: 'North Pole',
geolocation: {
longitude: 90,
latitude: 135
}
}
}
</script>
<!-- src/components/MyMarker.vue -->
<script>
export default {
inject: ['location', 'geolocation']
}
</script>
vue3写法
<!-- src/components/MyMap.vue -->
<template>
<MyMarker />
</template>
<script>
import { provide } from 'vue'
import MyMarker from './MyMarker.vue
export default {
components: {
MyMarker
},
setup() {
provide('location', 'North Pole')
provide('geolocation', {
longitude: 90,
latitude: 135
})
}
}
</script>
<!-- src/components/MyMarker.vue -->
<script>
import { inject } from 'vue'
export default {
setup() {
const userLocation = inject('location', 'The Universe')
const userGeolocation = inject('geolocation')
return {
userLocation,
userGeolocation
}
}
}
</script>
响应式
在vue3中我们使用依赖注入的话,当我们对ref或者reactive数据进行传值它是具有响应式的因为内部是proxy。
<!-- src/components/MyMap.vue -->
<template>
<MyMarker />
</template>
<script>
import { provide, reactive, ref } from 'vue'
import MyMarker from './MyMarker.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>
此时传递的数据就有了响应式了,但是即便有了响应式,但是vue官方还是不建议在引用数据的地方进行修改数据,这样会难以维护。
具体官网写的很详细,比如传只读数据防止被修改等。
官网地址