Subscribe on changes!

`default` for provide/inject either is no longer a function, or no longer automatically called

avatar
Sep 4th 2020

Version

3.0.0-rc.10

Reproduction link

workaround in v2: https://codesandbox.io/s/focused-villani-tpb93?file=/src/components/Consumer.js workaround in v3: https://codesandbox.io/s/modest-wozniak-bf9gb?file=/src/Consumer.js (sorry, I couldn't make an RC config on code sandbox)

Steps to reproduce

Run this:

import { h } from 'vue';

const Provider = {
  provide() {
    return {
      $_provided: () => 'provided data',
    };
  },
  render() {
    return h(
      'div',
      {},
      this.$slots.default()
    );
  },
};

const Consumer = {
  inject: {
    something: {
      from: '$_provided',
      default() {
        return () => 'default data';
      },
    },
  },
  render() {
    let data = this.something();
    return h('div', {}, data);
  },
};

render it like this:

<template>
  <div id="app">
    <Provider>
      <Consumer/>
    </Provider>
    <Consumer/>
  </div>
</template>

What is expected?

output would be:

provided data
default data

What is actually happening?

output is:

provided data

(since the default is a function)


I'm trying to make a library compatible with v2 & v3 at the same time, but did not see in the options (here: https://v3.vuejs.org/api/options-composition.html#provide-inject) or in the docs (here: https://v3.vuejs.org/guide/component-provide-inject.html#working-with-reactivity).

It even seems like the options is also using default() and not calling it, but just reading?

Workaround I found:

import { h } from "vue";

export default {
  inject: {
    something: {
      from: "$_provided",
      default() {
        return () => "default data";
      }
    }
  },
  render(localH) {
    let data = this.something();
    // in v3 `default` seems to not be a function?
    if (typeof data === "function") {
      data = data();
    }
    return (h || localH)("div", {}, data);
  }
};
avatar
Sep 4th 2020

thanks for fixing @yyx990803 :)