zoukankan      html  css  js  c++  java
  • vue3

    • Provide 和 Inject
      • 可以传递响应对象,可以传递方法
      • 如果要确保通过 provide 传递的数据不会被 inject 的组件更改,我们建议对提供者的 property 使用 readonly
    <script>
    import { provide,inject } from 'vue'
    
    export default {
      setup() {
        const location = ref('North Pole')
        const updateLocation = () => {
          location.value = 'South Pole'
        }
        provide('location', readonly(location))
        provide('geolocation', {
          longitude: 90,
          latitude: 135
        })
        provide('updateLocation', updateLocation)
      }
    }
    </script>
    // 
    export default {
      setup() {
        const userLocation = inject('location', 'The Universe')
        const userGeolocation = inject('geolocation')
    
        return {
          userLocation,
          userGeolocation
        }
      }
    }
    

    原文地址 v3.cn.vuejs.org

    我们也可以在组合式 API 中使用 provide/inject。两者都只能在当前活动实例的 setup() 期间调用。

    # 设想场景

    假设我们要重写以下代码,其中包含一个 MyMap 组件,该组件使用组合式 API 为 MyMarker 组件提供用户的位置。

    <template>
      <MyMarker />
    </template>
    
    <script>
    import MyMarker from './MyMarker.vue'
    
    export default {
      components: {
        MyMarker
      },
      provide: {
        location: 'North Pole',
        geolocation: {
          longitude: 90,
          latitude: 135
        }
      }
    }
    </script>
    
    <script>
    export default {
      inject: ['location', 'geolocation']
    }
    </script>
    

    # 使用 Provide

    调用 provide 时来定义每个 property。

    provide 函数允许你通过两个参数定义 property:

    1. property 的 name (<String> 类型)
    2. property 的 value

    使用 MyMap 组件,我们 provide 的值可以按如下方式重构:

    <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>
    

    # 使用 inject

    我们就可以调用它来定义如何将它暴露给我们的组件。

    inject 函数有两个参数:

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

    使用 MyMarker 组件,可以使用以下代码对其进行重构:

    <script>
    import { inject } from 'vue'
    
    export default {
      setup() {
        const userLocation = inject('location', 'The Universe')
        const userGeolocation = inject('geolocation')
    
        return {
          userLocation,
          userGeolocation
        }
      }
    }
    </script>
    

    # 响应性

    # 添加响应性

    为了增加 provide 值和 inject 值之间的响应性,我们可以在 provide 值时使用 refreactive

    <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>
    

    # 修改响应式 property

    当使用响应式 provide / inject 值时,建议尽可能,在_提供者_内保持响应式 property 的任何更改

    例如,在需要更改用户位置的情况下,我们最好在 MyMap 组件中执行此操作。

    <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)
    
        return {
          location
        }
      },
      methods: {
        updateLocation() {
          this.location = 'South Pole'
        }
      }
    }
    </script>
    

    然而,有时我们需要在注入数据的组件内部更新 inject 的数据。在这种情况下,我们建议 provide 一个方法来负责改变响应式 property。

    <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
        })
    
        const updateLocation = () => {
          location.value = 'South Pole'
        }
    
        provide('location', location)
        provide('geolocation', geolocation)
        provide('updateLocation', updateLocation)
      }
    }
    </script>
    
    <script>
    import { inject } from 'vue'
    
    export default {
      setup() {
        const userLocation = inject('location', 'The Universe')
        const userGeolocation = inject('geolocation')
        const updateUserLocation = inject('updateLocation')
    
        return {
          userLocation,
          userGeolocation,
          updateUserLocation
        }
      }
    }
    </script>
    

    最后,如果要确保通过 provide 传递的数据不会被 inject 的组件更改,我们建议对提供者的 property 使用 readonly

    <template>
      <MyMarker />
    </template>
    
    <script>
    import { provide, reactive, readonly, 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
        })
    
        const updateLocation = () => {
          location.value = 'South Pole'
        }
    
        provide('location', readonly(location))
        provide('geolocation', readonly(geolocation))
        provide('updateLocation', updateLocation)
      }
    }
    </script>
    
  • 相关阅读:
    apache安装遇到的问题
    babel+gulp实时转码ES6
    highcharts点击切换,不能自适应宽度
    多行文本溢出
    文件上传
    iscroll最后一个列表项无法显示出来
    curry化函数
    zepto中animate方法的使用注意
    js去除中间空格
    JS实现计算任意一个数的各个位数的和
  • 原文地址:https://www.cnblogs.com/qq3279338858/p/14504365.html
Copyright © 2011-2022 走看看