vue#provide TypeScript Examples

The following examples show how to use vue#provide. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RequestConfig.tsx    From vue-request with MIT License 6 votes vote down vote up
RequestConfig = defineComponent({
  name: 'RequestConfig',
  props: {
    config: {
      type: Object as PropType<GlobalOptions>,
      required: true,
    },
  },
  setup(props, { slots }) {
    const { config } = props;

    provide(GLOBAL_OPTIONS_PROVIDE_KEY, config);

    return () => slots.default?.();
  },
})
Example #2
Source File: useParent.ts    From elenext with MIT License 6 votes vote down vote up
useChildren = <T extends Record<string, unknown>>(key: InjectionKey<ParentProvide<T>>, data: T) => {
  const children: ComponentInternalInstance[] = reactive([])
  provide(key, {
    ...data,
    children,
    insert: (child: ComponentInternalInstance) => {
      children.push(child)
    },
    remove: (child: ComponentInternalInstance) => {
      const index = children.indexOf(child)
      children.splice(index, 1)
    }
  })
}
Example #3
Source File: config.ts    From elenext with MIT License 6 votes vote down vote up
EConfigProvider = defineComponent({
  name: '',
  props: { theme: vptypes.object() },
  setup(props, { slots }) {
    const config = reactive({
      theme: props.theme,
    })
    provide(EConfigProvider_IJK, config)
    return slots.defalut?.()
  },
})
Example #4
Source File: useTree.ts    From vue3-treeview with MIT License 6 votes vote down vote up
export default function useTree(props: any, emit: (event: string, ...args: any[]) => void): {} {
    const element = ref<HTMLElement>(null);

    const id = createState(props);

    const state = states.get(id);

    provide("emitter", emit);

    provide("state", state);

    const style = computed(() => {
        return {
            "display": "flex",
            "align-items": "center"
        };
    });

    onUnmounted(() => {
        states.delete(id);
    })

    return {
        element,
        style
    };
}
Example #5
Source File: lib.ts    From hexon with GNU General Public License v3.0 6 votes vote down vote up
export function createDialogPlugin(): Dialog {
  const dialogs = ref<IDialog[]>([])
  function create(option: IDialogOption) {
    const item = new DialogItem(option, dialogs)
    dialogs.value.push(item)
  }
  return {
    dialogs,
    create,
    install(app: App) {
      const dialog = this
      app.provide(key, dialog)
    },
  }
}
Example #6
Source File: provider.ts    From fect with MIT License 5 votes vote down vote up
createProvider = <
  // eslint-disable-next-line
  T extends ComponentPublicInstance = ComponentPublicInstance<{}, any>,
  ProvideValue = never
>(
  key: InjectionKey<ProvideValue>
) => {
  const publicChildren: T[] = reactive([])
  const internalChildren: ComponentInternalInstance[] = reactive([])
  const parent = getCurrentInstance()!
  const provider = (value?: ProvideValue) => {
    const link = (child: ComponentInternalInstance) => {
      if (child.proxy) {
        internalChildren.push(child)
        publicChildren.push(child.proxy as T)
        sortChildren(parent, publicChildren, internalChildren)
      }
    }

    const unlink = (child: ComponentInternalInstance) => {
      const idx = internalChildren.indexOf(child)
      publicChildren.splice(idx, 1)
      internalChildren.splice(idx, 1)
    }
    provide(
      key,
      Object.assign(
        {
          link,
          unlink,
          children: publicChildren,
          internalChildren
        },
        value
      )
    )
  }
  return {
    children: publicChildren,
    provider
  }
}
Example #7
Source File: wc.test.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
test('basic', async () => {
  const i18n = createI18n<false>({
    legacy: false,
    locale: 'en',
    messages: {
      en: {
        hello: 'hello web components!'
      },
      ja: {
        hello: 'こんにちは Web コンポーネント!'
      }
    }
  })

  const Provider = defineCustomElement({
    setup() {
      provide(I18nInjectionKey, i18n)
      return () => h('my-consumer')
    }
  })
  customElements.define('my-provider', Provider)
  const Consumer = defineCustomElement({
    setup() {
      const { t } = useI18n()
      return () => h('div', t('hello'))
    }
  })
  customElements.define('my-consumer', Consumer)

  container.innerHTML = `<my-provider></my-provider>`
  await nextTick()
  const provider = container.childNodes[0] as VueElement
  const consumer = provider.shadowRoot!.childNodes[0] as VueElement
  expect(consumer.shadowRoot!.innerHTML).toBe(
    `<div>hello web components!</div>`
  )

  i18n.global.locale.value = 'ja'
  await nextTick()
  expect(consumer.shadowRoot!.innerHTML).toBe(
    `<div>こんにちは Web コンポーネント!</div>`
  )
})
Example #8
Source File: wc.test.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
test('custom blocks', async () => {
  const i18n = createI18n<false>({
    legacy: false,
    locale: 'en',
    messages: {
      en: {
        hello: 'hello web components!'
      },
      ja: {
        hello: 'こんにちは Web コンポーネント!'
      }
    }
  })

  const Provider = defineCustomElement({
    setup() {
      provide(I18nInjectionKey, i18n)
      return () => h('my-child-block')
    }
  })
  customElements.define('my-provider-block', Provider)
  const Child = defineCustomElement({
    setup() {
      const instance = getCurrentInstance()
      if (instance == null) {
        throw new Error()
      }
      const options = instance.type as ComponentOptions
      options.__i18n = [
        {
          locale: 'en',
          resource: { foo: 'foo!' }
        },
        {
          locale: 'ja',
          resource: { foo: 'ふー!' }
        }
      ]
      const { t } = useI18n({
        inheritLocale: true,
        useScope: 'local'
      })
      return () => h('div', t('foo'))
    }
  })
  customElements.define('my-child-block', Child)

  container.innerHTML = `<my-provider-block></my-provider-block>`
  await nextTick()
  const provider = container.childNodes[0] as VueElement
  const child = provider.shadowRoot!.childNodes[0] as VueElement
  expect(child.shadowRoot!.innerHTML).toBe(`<div>foo!</div>`)

  i18n.global.locale.value = 'ja'
  await nextTick()
  expect(child.shadowRoot!.innerHTML).toBe(`<div>ふー!</div>`)
})
Example #9
Source File: index.ts    From jz-gantt with MIT License 5 votes vote down vote up
initStore = () => {
  const GtData = reactive(new GanttData()) as GanttData;
  provide(Variables.provider.gtData, GtData);

  const GtParam = reactive(new ParamData()) as ParamData;
  provide(Variables.provider.gtParam, GtParam);

  const rootEmit = ref();
  provide(Variables.provider.gtRootEmit, rootEmit);

  const rootRef = ref<HTMLDivElement>();
  provide(Variables.provider.gtRootRef, rootRef);

  const ganttRef = ref<HTMLDivElement>();
  provide(Variables.provider.gtGanttRef, ganttRef);

  const tableRef = ref<HTMLDivElement>();
  provide(Variables.provider.gtTableRef, tableRef);

  const isShowMask = ref(false);
  provide(Variables.provider.gtIsShowMask, isShowMask);

  const showDateList = reactive<Date[]>([]);
  provide(Variables.provider.gtShowDateList, showDateList);

  const successBarList: Row[] = reactive([]);
  provide(Variables.provider.gtSuccessBarList, successBarList);

  const initGanttWidth = ref(0);
  provide(Variables.provider.gtInitGanttWidth, initGanttWidth);

  // 设置移动线
  const columnSliderLineVisible = ref(false);
  provide(
    Variables.provider.gtColumnSliderLineVisible,
    columnSliderLineVisible
  );
  const columnSliderLineLeft = ref(0);
  provide(Variables.provider.gtColumnSliderLineLeft, columnSliderLineLeft);
  const columnDefaultLeft = ref(-1);
  provide(Variables.provider.gtColumnDefaultLeft, columnDefaultLeft);

  const timeout = 500; // 提示条消失时间
  provide(Variables.provider.gtSuccessBarTimeout, timeout);

  // toast
  const isShowToast = ref(false);
  provide(Variables.provider.gtIsShowToast, isShowToast);
  const toastMessage = ref('');
  provide(Variables.provider.gtToastMessage, toastMessage);
  const toastQueue: any[] = [];
  provide(Variables.provider.gtToastQueue, toastQueue);

  // wheel
  const scrollTop = ref(0);
  provide(Variables.provider.gtScrollTop, scrollTop);
  const rootHeight = ref(0);
  provide(Variables.provider.gtRootHeight, rootHeight);
  const scrollBarHeight = ref(Variables.size.defaultScrollBarHeight);
  provide(Variables.provider.gtScrollBarHeight, scrollBarHeight);

  const stopClickEvent = ref(false);
  provide(Variables.provider.gtStopClickEvent, stopClickEvent);
}
Example #10
Source File: setting.ts    From novel-downloader with GNU Affero General Public License v3.0 4 votes vote down vote up
vm = createApp({
  name: "nd-setting",
  components: { "filter-tab": FilterTab, "log-ui": LogUI, "test-ui": TestUI },
  setup() {
    interface Setting {
      enableDebug?: boolean;
      enableTestPage?: boolean;
      chooseSaveOption?: string;
      filterSetting?: filterSettingGlobal;
      currentTab: string;
    }

    const setting = reactive({} as Setting);
    let settingBackup = {};

    interface SaveOption {
      key: string;
      value: string;
      options: globalSaveOptions;
    }

    const saveOptions: SaveOption[] = [
      { key: "null", value: "不使用自定义保存参数", options: {} },
      {
        key: "chapter_name",
        value: "将章节名称格式修改为 第xx章 xxxx",
        options: {
          getchapterName: (chapter) => {
            if (chapter.chapterName) {
              return `第${chapter.chapterNumber.toString()}${
                chapter.chapterName
              }`;
            } else {
              return `第${chapter.chapterNumber.toString()}章`;
            }
          },
        },
      },
      {
        key: "txt_space",
        value: "txt文档每个自然段前加两个空格",
        options: {
          genChapterText: (chapterName, contentText) => {
            contentText = contentText
              .split("\n")
              .map((line) => {
                if (line.trim() === "") {
                  return line;
                } else {
                  return line.replace(/^/, "    ");
                }
              })
              .join("\n");
            return `## ${chapterName}\n\n${contentText}\n\n`;
          },
        },
      },
      {
        key: "reverse_chapters",
        value: "保存章节时倒序排列",
        options: {
          chapterSort: (a, b) => {
            if (a.chapterNumber > b.chapterNumber) {
              return -1;
            }
            if (a.chapterNumber === b.chapterNumber) {
              return 0;
            }
            if (a.chapterNumber < b.chapterNumber) {
              return 1;
            }
            return 0;
          },
        },
      },
    ];
    setting.enableDebug = enableDebug.value;
    setting.chooseSaveOption = "null";
    setting.enableTestPage = false;
    setting.currentTab = "tab-1";
    const curSaveOption = () => {
      const _s = saveOptions.find((s) => s.key === setting.chooseSaveOption);
      if (_s) {
        return _s.options;
      } else {
        return saveOptions[0].options;
      }
    };
    const saveFilter = (filterSetting: filterSettingGlobal) => {
      setting.filterSetting = deepcopy(filterSetting);
    };
    const getFilterSetting = () => {
      if (setting.filterSetting) {
        return setting.filterSetting;
      } else {
        return;
      }
    };
    provide("getFilterSetting", getFilterSetting);

    const setConfig = (config: Setting) => {
      setEnableDebug();
      setCustomSaveOption();
      setCustomFilter();

      function setEnableDebug() {
        if (typeof config.enableDebug === "boolean") {
          config.enableDebug ? log.setLevel("trace") : log.setLevel("info");
          enableDebug.value = config.enableDebug;
          if (config.enableDebug) {
            debug();
          }
          log.info(`[Init]enableDebug: ${enableDebug.value}`);
        }
      }

      function setCustomSaveOption() {
        (unsafeWindow as UnsafeWindow).saveOptions = curSaveOption();
      }

      function setCustomFilter() {
        if (config.filterSetting) {
          if (config.filterSetting.filterType === "null") {
            (unsafeWindow as UnsafeWindow).chapterFilter = undefined;
          } else {
            const filterFunction = getFilterFunction(
              config.filterSetting.arg,
              config.filterSetting.functionBody
            );
            if (filterFunction) {
              (unsafeWindow as UnsafeWindow).chapterFilter = (
                chapter: Chapter
              ) => {
                if (chapter.status === Status.aborted) {
                  return false;
                }
                return filterFunction(chapter);
              };
            }
          }
        }
      }
    };

    const openStatus = ref("false");
    const openSetting = () => {
      settingBackup = deepcopy(setting) as Setting;
      openStatus.value = "true";
    };
    const closeSetting = (keep: PointerEvent | boolean) => {
      if (keep === true) {
        settingBackup = deepcopy(setting);
      } else {
        Object.assign(setting, settingBackup);
      }
      openStatus.value = "false";
    };
    const closeAndSaveSetting = async () => {
      closeSetting(true);
      await sleep(30);
      setConfig(deepcopy(setting));
      log.info("[Init]自定义设置:" + JSON.stringify(setting));
    };

    return {
      openStatus,
      openSetting,
      closeSetting,
      closeAndSaveSetting,
      saveFilter,
      setting,
      saveOptions,
    };
  },
  template: settingHtml,
}).mount(el)
Example #11
Source File: useInput.ts    From formkit with MIT License 4 votes vote down vote up
/**
 * A composable for creating a new FormKit node.
 * @param type - The type of node (input, group, list)
 * @param attrs - The FormKit "props" — which is really the attrs list.
 * @returns
 * @public
 */
export function useInput(
  props: FormKitComponentProps,
  context: SetupContext<any>,
  options: FormKitOptions = {}
): FormKitNode {
  /**
   * The configuration options, these are provided by either the plugin or by
   * explicit props.
   */
  const config = Object.assign({}, inject(optionsSymbol) || {}, options)

  /**
   * The current instance.
   */
  const instance = getCurrentInstance()

  /**
   * Extracts the listeners.
   */
  const listeners = onlyListeners(instance?.vnode.props)

  /**
   * Determines if the prop is v-modeled.
   */
  const isVModeled = props.modelValue !== undefined

  /**
   * Determines if the object being passed as a v-model is reactive.
   */
  // const isReactiveVModel = isVModeled && isReactive(props.modelValue)

  /**
   * Define the initial component
   */
  const value: any =
    props.modelValue !== undefined
      ? props.modelValue
      : cloneAny(context.attrs.value)

  /**
   * Creates the node's initial props from the context, props, and definition
   * @returns
   */
  function createInitialProps(): Record<string, any> {
    const initialProps: Record<string, any> = {
      ...nodeProps(props),
      ...listeners,
    }
    const attrs = except(nodeProps(context.attrs), pseudoProps)
    initialProps.attrs = attrs
    const propValues = only(nodeProps(context.attrs), pseudoProps)
    for (const propName in propValues) {
      initialProps[camel(propName)] = propValues[propName]
    }
    const classesProps = { props: {} }
    classesToNodeProps(classesProps as FormKitNode, props)
    Object.assign(initialProps, classesProps.props)
    if (typeof initialProps.type !== 'string') {
      initialProps.definition = initialProps.type
      delete initialProps.type
    }
    return initialProps
  }

  /**
   * Create the FormKitNode.
   */
  const initialProps = createInitialProps()

  /**
   * The parent node.
   */
  const parent = initialProps.ignore
    ? null
    : props.parent || inject(parentSymbol, null)

  const node = createNode(
    extend(
      config || {},
      {
        name: props.name || undefined,
        value,
        parent,
        plugins: (config.plugins || []).concat(props.plugins),
        config: props.config,
        props: initialProps,
        index: props.index,
      },
      false,
      true
    ) as Partial<FormKitOptions>
  ) as FormKitNode

  /**
   * If no definition has been assigned at this point — we're out!
   */
  if (!node.props.definition) error(600, node)

  /**
   * All props that are bound "late" (after node creation) — are added to a set
   * which is used to watch the context.attrs object.
   */
  const lateBoundProps = ref<Set<string | RegExp>>(
    new Set(node.props.definition.props || [])
  )

  /**
   * Any additional props added at a "later" time should also be part of the
   * late bound props.
   */
  node.on('added-props', ({ payload: lateProps }) => {
    if (Array.isArray(lateProps))
      lateProps.forEach((newProp) => lateBoundProps.value.add(newProp))
  })

  /**
   * These prop names must be assigned.
   */
  const pseudoPropNames = computed(() =>
    pseudoProps.concat([...lateBoundProps.value]).reduce((names, prop) => {
      if (typeof prop === 'string') {
        names.push(camel(prop))
        names.push(kebab(prop))
      } else {
        names.push(prop)
      }
      return names
    }, [] as Array<string | RegExp>)
  )

  /* Splits Classes object into discrete props for each key */
  watchEffect(() => classesToNodeProps(node, props))

  /**
   * The props object already has properties even if they start as "undefined"
   * so we can loop over them and individual watchEffect to prevent responding
   * inappropriately.
   */
  const passThrough = nodeProps(props)
  for (const prop in passThrough) {
    watch(
      () => props[prop as keyof FormKitComponentProps],
      () => {
        if (props[prop as keyof FormKitComponentProps] !== undefined) {
          node.props[prop] = props[prop as keyof FormKitComponentProps]
        }
      }
    )
  }

  /**
   * Watch "pseudoProp" attributes explicitly.
   */
  const attributeWatchers = new Set<WatchStopHandle>()
  const possibleProps = nodeProps(context.attrs)
  watchEffect(() => {
    watchAttributes(only(possibleProps, pseudoPropNames.value))
  })

  /**
   * Defines attributes that should be used as props.
   * @param attrProps - Attributes that should be used as props instead
   */
  function watchAttributes(attrProps: Record<string, any>) {
    attributeWatchers.forEach((stop) => {
      stop()
      attributeWatchers.delete(stop)
    })
    for (const prop in attrProps) {
      const camelName = camel(prop)
      attributeWatchers.add(
        watch(
          () => context.attrs[prop],
          () => {
            node.props[camelName] = context.attrs[prop]
          }
        )
      )
    }
  }

  /**
   * Watch and dynamically set attribute values, those values that are not
   * props and are not pseudoProps
   */
  watchEffect(() => {
    const attrs = except(nodeProps(context.attrs), pseudoPropNames.value)
    node.props.attrs = Object.assign({}, node.props.attrs || {}, attrs)
  })

  /**
   * Add any/all "prop" errors to the store.
   */
  watchEffect(() => {
    const messages = props.errors.map((error) =>
      createMessage({
        key: slugify(error),
        type: 'error',
        value: error,
        meta: { source: 'prop' },
      })
    )
    node.store.apply(
      messages,
      (message) => message.type === 'error' && message.meta.source === 'prop'
    )
  })

  /**
   * Add input errors.
   */
  if (node.type !== 'input') {
    const sourceKey = `${node.name}-prop`
    watchEffect(() => {
      const keys = Object.keys(props.inputErrors)
      const messages = keys.reduce((messages, key) => {
        let value = props.inputErrors[key]
        if (typeof value === 'string') value = [value]
        if (Array.isArray(value)) {
          messages[key] = value.map((error) =>
            createMessage({
              key: error,
              type: 'error',
              value: error,
              meta: { source: sourceKey },
            })
          )
        }
        return messages
      }, {} as Record<string, FormKitMessage[]>)
      node.store.apply(
        messages,
        (message) =>
          message.type === 'error' && message.meta.source === sourceKey
      )
    })
  }

  /**
   * Watch the config prop for any changes.
   */
  watchEffect(() => Object.assign(node.config, props.config))

  /**
   * Produce another parent object.
   */
  if (node.type !== 'input') {
    provide(parentSymbol, node)
  }

  let inputTimeout: number | undefined

  // eslint-disable-next-line @typescript-eslint/ban-types
  const mutex = new WeakSet<object>()

  /**
   * Explicitly watch the input value, and emit changes (lazy)
   */
  node.on('modelUpdated', () => {
    // Emit the values after commit
    context.emit('inputRaw', node.context?.value, node)
    clearTimeout(inputTimeout)
    inputTimeout = setTimeout(
      context.emit,
      20,
      'input',
      node.context?.value,
      node
    ) as unknown as number

    if (isVModeled && node.context) {
      const newValue = useRaw(node.context.value)
      if (isObject(newValue) && useRaw(props.modelValue) !== newValue) {
        // If this is an object that has been mutated inside FormKit core then
        // we know when it is emitted it will "return" in the watchVerbose so
        // we pro-actively add it to the mutex.
        mutex.add(newValue)
      }
      context.emit('update:modelValue', newValue)
    }
  })

  /**
   * Enabled support for v-model, using this for groups/lists is not recommended
   */
  if (isVModeled) {
    watchVerbose(toRef(props, 'modelValue'), (path, value): void | boolean => {
      const rawValue = useRaw(value)
      if (isObject(rawValue) && mutex.has(rawValue)) {
        return mutex.delete(rawValue)
      }
      if (!path.length) node.input(value, false)
      else node.at(path)?.input(value, false)
    })
  }

  /**
   * When this input shuts down, we need to "delete" the node too.
   */
  onUnmounted(() => node.destroy())

  return node
}