乐趣区

关于javascript:Vue-3-组合式-provideinject

欢送关注我的公众号《人生代码》

组合式提供与注入

在之前的章节,咱们讲了选项式的 提供与注入,明天咱们持续讲组合式提供与注入。

咱们也能够在组合式 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:

  1. property 的 name (<String> 类型)
  2. 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 函数有两个参数:

  1. 要注入的 property 的名称
  2. 一个默认的值 (可选)

应用 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>
`

退出移动版