vue#DefineComponent TypeScript Examples

The following examples show how to use vue#DefineComponent. 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: utils.ts    From vue-hooks-form with MIT License 7 votes vote down vote up
renderHook = <Result>(
  callback: () => Result | void = () => { },
): RenderHookResult<Result> => {
  let result
  const Container = defineComponent({
    setup() {
      result = callback()
      return result
    },
    render() {
      return null
    },
  })
  mount(Container)

  return {
    result,
  }
}
Example #2
Source File: diretive.test.ts    From vue-i18n-next with MIT License 6 votes vote down vote up
test('using in template', async () => {
  const i18n = createI18n({
    locale: 'en',
    messages: {
      en: {
        hello: 'hello!'
      }
    }
  })

  const App = defineComponent({
    template: `<p v-t="'hello'"></p>`
  })
  const wrapper = await mount(App, i18n)

  expect(wrapper.html()).toEqual('<p>hello!</p>')
})
Example #3
Source File: vue-template.tsx    From vue3-datagrid with MIT License 6 votes vote down vote up
vueTemplateConstructor =
    (vueConstructor: DefineComponent, e: HTMLElement|null, p: Record<string, any>) => {
        if (!e) {
            return null;
        }
        let el: VueElement|undefined;
        if (e?.childNodes.length) {
            el = e.childNodes[0] as VueElement;
        }
        
        if (!el) {
            // create dom element wrapper for vue instance
            el = document.createElement('span');
            e.appendChild(el);
        }
        // check, probably vue instance already inited
        let vueInstance = el._vnode;
        // if exists, return
        if (vueInstance) {
            // if vue inited just update it's properties
            for (const k in p) {
                vueInstance.component.props[k] = p[k];
            }
        } else {
            const vNode = createVNode(vueConstructor, p);
            render(vNode, el);
        }
        return vueInstance;
    }
Example #4
Source File: index.ts    From vue-components-lib-seed with MIT License 6 votes vote down vote up
createDemoModule = (
  name: string,
  demos: component[],
  comps?: component[]
) =>
  defineComponent({
    name: `${name}-demo`,
    setup() {
      return {
        demos,
      }
    },
  })
Example #5
Source File: Mesh.ts    From trois with MIT License 6 votes vote down vote up
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function meshComponent<P extends Readonly<ComponentPropsOptions>>(
  name: string,
  props: P,
  createGeometry: {(c: any): BufferGeometry}
) {
  return defineComponent({
    name,
    extends: Mesh,
    props,
    created() {
      this.createGeometry()
      this.addGeometryWatchers(props)
    },
    methods: {
      createGeometry() {
        this.geometry = createGeometry(this)
      },
    },
  })
}
Example #6
Source File: invokeHook.ts    From vhook with MIT License 6 votes vote down vote up
export function invokeHook (setup: () => any, template = defaultTemplate) {
  document.body.innerHTML = `
    <div id="app"></div>
  `
  const App = defineComponent({
    template,
    setup
  })
  // @ts-ignore
  return shallowMount(App, {
    attachTo: document.getElementById('app')
  })
}
Example #7
Source File: diretive.test.ts    From vue-i18n-next with MIT License 6 votes vote down vote up
test('legacy mode', async () => {
  const i18n = createI18n({
    legacy: true,
    locale: 'en',
    messages: {
      en: {
        hello: 'hello!'
      }
    }
  })

  const App = defineComponent({
    setup() {
      // <p v-t="'hello'"></p>
      const t = resolveDirective('t')
      return () => {
        return withDirectives(h('p'), [[t!, 'hello']])
      }
    }
  })
  const wrapper = await mount(App, i18n)

  expect(wrapper.html()).toEqual('<p>hello!</p>')
})
Example #8
Source File: app.ts    From vite-plugin-ssr with MIT License 6 votes vote down vote up
function createApp(pageContext: PageContext) {
  const { Page, pageProps } = pageContext
  const PageWithLayout = defineComponent({
    render() {
      return h(
        PageShell,
        {},
        {
          default() {
            return h(Page, pageProps || {})
          },
        },
      )
    },
  })

  const app = createSSRApp(PageWithLayout)

  // Make `pageContext` available from any Vue component
  setPageContext(app, pageContext)

  return app
}
Example #9
Source File: index.ts    From elenext with MIT License 6 votes vote down vote up
createSvgIcon = (compName: string, className: string, svgSource: string) => {
  const Icon = defineComponent({
    name: compName,
    props: { spin: Boolean },
    setup(props, { attrs }) {
      injectCss(injectCssId, iconStyles, true)

      return () =>
        createVNode('i', {
          ...attrs,
          class: {
            'el-icon': true,
            [`el-icon-${className}`]: true,
            'el-icon-spin': props.spin
          },
          innerHTML: svgSource
        })
    }
  })

  Icon.install = (app: App): void => {
    app.component(compName, Icon)
  }
  return Icon
}
Example #10
Source File: components.ts    From vite-ssr with MIT License 6 votes vote down vote up
ClientOnly = defineComponent({
  name: 'ClientOnly',
  setup(_, { slots }) {
    const show = ref(false)
    onMounted(() => {
      show.value = true
    })

    return () => (show.value && slots.default ? slots.default() : null)
  },
})
Example #11
Source File: snapshot.test.tsx    From vue-request with MIT License 6 votes vote down vote up
describe('RequestConfig', () => {
  const Child = defineComponent({
    setup() {
      return () => <button>button</button>;
    },
  });
  it('RequestConfig default slots should work ', () => {
    const wrapperA = mount(
      defineComponent({
        setup() {
          return () => (
            <RequestConfig config={{ loadingDelay: 0 }}>
              this is a text
            </RequestConfig>
          );
        },
      }),
    );
    expect(wrapperA.html()).toMatchSnapshot();
    wrapperA.unmount();

    const wrapperB = mount(
      defineComponent({
        setup() {
          return () => (
            <RequestConfig config={{ loadingDelay: 0 }}>
              this is a text
              <Child />
            </RequestConfig>
          );
        },
      }),
    );
    expect(wrapperB.html()).toMatchSnapshot();
  });
});
Example #12
Source File: use-is-mounted.spec.ts    From vooks with MIT License 6 votes vote down vote up
describe('# useIsMounted', () => {
  it('works', (done) => {
    const wrapper = mount(defineComponent({
      setup () {
        const isMounted = useIsMounted()
        expect(isMounted.value).toEqual(false)
        return {
          isMounted
        }
      },
      beforeMount () {
        expect(this.isMounted).toEqual(false)
      },
      mounted () {
        nextTick(() => {
          expect(this.isMounted).toEqual(true)
          wrapper.unmount()
          done()
        })
      }
    }))
  })
})
Example #13
Source File: hexo-init-fail-modal.ts    From hexon with GNU General Public License v3.0 6 votes vote down vote up
export default function showHexoInitFailModal(text: string) {
  modal.create(
    defineComponent({
      name: "HErrorInfo",
      components: {
        HHexoInitFailModal,
        HBaseModal,
      },
      props: {
        close: Function,
      },
      render() {
        return h(
          HBaseModal,
          {
            onOnClose: this.close,
          },
          () => h(HHexoInitFailModal, { text })
        )
      },
    })
  )
}
Example #14
Source File: DatetimeFormat.test.ts    From vue-i18n-next with MIT License 6 votes vote down vote up
test('basic usage', async () => {
  const i18n = createI18n({
    locale: 'en-US',
    datetimeFormats
  })

  const App = defineComponent({
    template: `
<i18n-d tag="p" :value="new Date()"></i18n-d>
<i18n-d tag="p" :value="new Date()" format="long"></i18n-d>
<i18n-d
  tag="p"
  :value="new Date()"
  format="long"
  locale="ja-JP-u-ca-japanese"
></i18n-d>
`
  })
  const wrapper = await mount(App, i18n)

  expect(wrapper.html()).toMatch(
    /([1-9]|1[0-2])\/([1-9]|[12]\d|3[01])\/([12]\d{3})/
  )
  expect(wrapper.html()).toMatch(
    /(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/([12]\d{3}), (0[0-9]|1[0-2]):([0-5][0-9]):([0-5][0-9]) (AM|PM)/
  )
  expect(wrapper.html()).toMatch(
    /令和([1-9]|1[0-2])年([1-9]|1[0-2])月([1-9]|[1-3][0-9])日(月|火|水|木|金|土|日)曜日 (午前|午後)([0-9]|1[0-2]):([0-5][0-9]):([0-5][0-9]) (協定世界時|グリニッジ標準時)/
  )
})
Example #15
Source File: use-memo.spec.ts    From vooks with MIT License 5 votes vote down vote up
describe('# useMemo', () => {
  it('only trigger render once', async () => {
    const mock = jest.fn()
    const depRef = ref(0)
    const wrapper = mount(defineComponent({
      setup () {
        return {
          memoValue: useMemo(() => {
            return depRef.value < 2 ? '<2' : '>=2'
          })
        }
      },
      renderTriggered: mock,
      render () {
        return this.memoValue
      }
    }))
    depRef.value = 1
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(0)
    depRef.value = 2
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(1)
    depRef.value = 3
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(1)
    wrapper.unmount()
  })
  it('work with computed writable options', async () => {
    const mock = jest.fn()
    const depRef = ref(0)
    const wrapper = mount(defineComponent({
      setup () {
        const memoValueRef = useMemo({
          get: () => {
            return depRef.value < 2 ? '<2' : '>=2'
          },
          set: (v: '<2' | '>=2') => {
            if (v === '<2') depRef.value = 0
            else depRef.value = 4
          }
        })
        return {
          memoValue: memoValueRef,
          setMemoValue: (value: '<2' | '>=2') => {
            memoValueRef.value = value
          }
        }
      },
      renderTriggered: mock,
      render () {
        return this.memoValue
      }
    }))
    depRef.value = 1
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(0)
    depRef.value = 2
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(1)
    depRef.value = 3
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(1)
    ;(wrapper.instance as any).setMemoValue('<2')
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(2)
    ;(wrapper.instance as any).setMemoValue('<2')
    await nextTick()
    expect(mock).toHaveBeenCalledTimes(2)
    wrapper.unmount()
  })
})
Example #16
Source File: app.ts    From vite-plugin-ssr with MIT License 5 votes vote down vote up
function createApp(pageContext: PageContext) {
  const { Page } = pageContext

  let rootComponent: Component
  const PageWithWrapper = defineComponent({
    data: () => ({
      Page: markRaw(Page),
      pageProps: markRaw(pageContext.pageProps || {}),
    }),
    created() {
      rootComponent = this
    },
    render() {
      return h(
        PageShell,
        {},
        {
          default: () => {
            return h(this.Page, this.pageProps)
          },
        },
      )
    },
  })

  const app = createSSRApp(PageWithWrapper)

  // We use `app.changePage()` to do Client Routing, see `_default.page.client.js`
  objectAssign(app, {
    changePage: (pageContext: PageContext) => {
      Object.assign(pageContextReactive, pageContext)
      rootComponent.Page = markRaw(pageContext.Page)
      rootComponent.pageProps = markRaw(pageContext.pageProps || {})
    },
  })

  // When doing Client Routing, we mutate pageContext (see usage of `app.changePage()` in `_default.page.client.js`).
  // We therefore use a reactive pageContext.
  const pageContextReactive = reactive(pageContext)

  // Make `pageContext` accessible from any Vue component
  setPageContext(app, pageContextReactive)

  return app
}
Example #17
Source File: on-font-ready.spec.ts    From vooks with MIT License 5 votes vote down vote up
describe('# onFontsReady', () => {
  let fonts: any
  beforeEach(() => {
    fonts = (document as any).fonts
    ;(document as any).fonts = {
      ready: undefined
    }
  })
  afterEach(() => {
    (document as any).fonts = fonts
  })
  it('should do nothing when documnt does not support fonts.ready', (done) => {
    const fn = jest.fn()
    const wrapper = mount(defineComponent({
      setup () {
        onFontsReady(fn)
      }
    }))
    setTimeout(() => {
      expect(fn).not.toHaveBeenCalled()
      wrapper.unmount()
      done()
    }, 0)
  })
  it('should be called when documnt supports fonts.ready', (done) => {
    const fn = jest.fn()
    ;(document as any).fonts = {
      ready: new Promise((resolve) => {
        setTimeout(resolve, 500)
      })
    }
    init()

    console.log('document.fonts', document.fonts)
    const wrapper = mount(
      defineComponent({
        setup () {
          onFontsReady(fn)
        }
      })
    )
    setTimeout(() => {
      expect(fn).toHaveBeenCalled()
      wrapper.unmount()
      done()
    }, 1000)
  })
  it('should not be called when comoponent is unmounted', () => {
    const fn = jest.fn()
    let res: any
    ;(document as any).fonts = {
      ready: new Promise(resolve => { res = resolve })
    }
    const wrapper = mount(defineComponent({
      setup () {
        onFontsReady(fn)
      }
    }))
    wrapper.unmount()
    res()
    setTimeout(() => {
      expect(fn).not.toHaveBeenCalled()
    }, 0)
  })
})
Example #18
Source File: masonry-wall.spec.ts    From vue-masonry-wall with MIT License 5 votes vote down vote up
TestComponent = defineComponent({
  template: '<masonry-wall :items="[1, 2, 3]" />',
})
Example #19
Source File: vue-editor-adapter.tsx    From vue3-datagrid with MIT License 5 votes vote down vote up
constructor(
        private VueEditorConstructor: DefineComponent,
        public column: RevoGrid.ColumnDataSchemaModel,
        private save: Function,
        private close: Function
    ) {}
Example #20
Source File: component.ts    From vue3-gettext with MIT License 5 votes vote down vote up
Component = defineComponent({
  // eslint-disable-next-line vue/multi-word-component-names, vue/component-definition-name-casing
  name: "translate",
  props: {
    tag: {
      type: String,
      default: "span",
    },
    // Always use v-bind for dynamically binding the `translateN` prop to data on the parent,
    // i.e.: `:translate-n`.
    translateN: {
      type: Number,
      default: null,
    },
    translatePlural: {
      type: String,
      default: null,
    },
    translateContext: {
      type: String,
      default: null,
    },
    translateParams: {
      type: Object,
      default: null,
    },
    translateComment: {
      type: String,
      default: null,
    },
  },

  setup(props, context) {
    const isPlural = props.translateN !== undefined && props.translatePlural !== undefined;
    if (!isPlural && (props.translateN || props.translatePlural)) {
      throw new Error(
        `\`translate-n\` and \`translate-plural\` attributes must be used together: ${
          context.slots.default?.()[0]?.children
        }.`,
      );
    }

    const root = ref<HTMLElement>();

    const plugin = useGettext();
    const msgid = ref<string | null>(null);

    onMounted(() => {
      if (!msgid.value && root.value) {
        msgid.value = root.value.innerHTML.trim();
      }
    });

    const translation = computed(() => {
      const translatedMsg = translate(plugin).getTranslation(
        msgid.value!,
        props.translateN,
        props.translateContext,
        isPlural ? props.translatePlural : null,
        plugin.current,
      );

      return interpolate(plugin)(translatedMsg, props.translateParams, undefined, getCurrentInstance()?.parent);
    });

    // The text must be wraped inside a root HTML element, so we use a <span> by default.
    return () => {
      if (!msgid.value) {
        return h(props.tag, { ref: root }, context.slots.default ? context.slots.default() : "");
      }
      return h(props.tag, { ref: root, innerHTML: translation.value });
    };
  },
})
Example #21
Source File: utils.ts    From vue3-datagrid with MIT License 5 votes vote down vote up
defineContainer = <Props>(name: string, [...componentProps]: string[] = [], componentOptions: ComponentOptions = {}) => {
  const { modelProp, modelUpdateEvent } = componentOptions;

  /**
  * Create a Vue component wrapper around a Web Component.
  * Note: The `props` here are not all properties on a component.
  * They refer to whatever properties are set on an instance of a component.
  */
  const Container = defineComponent<Props & InputProps>((props, { attrs, slots, emit }) => {
    let modelPropValue = (props as any)[modelProp];
    const containerRef = ref<HTMLElement>();
    const classes = new Set(getComponentClasses(attrs.class));
    const onVnodeBeforeMount = (vnode: VNode) => {
      // Add a listener to tell Vue to update the v-model
      if (vnode.el) {
        vnode.el.addEventListener(modelUpdateEvent.toLowerCase(), (e: Event) => {
          modelPropValue = (e?.target as any)[modelProp];
          emit(UPDATE_VALUE_EVENT, modelPropValue);

          /**
           * We need to emit the change event here
           * rather than on the web component to ensure
           * that any v-model bindings have been updated.
           * Otherwise, the developer will listen on the
           * native web component, but the v-model will
           * not have been updated yet.
           */
          emit(modelUpdateEvent, e);
          e.stopImmediatePropagation();
        });
      }
    };

    const currentInstance = getCurrentInstance();
    const hasRouter = currentInstance?.appContext?.provides[NAV_MANAGER];
    const navManager: NavManager | undefined = hasRouter ? inject(NAV_MANAGER) : undefined;
    const handleRouterLink = (ev: Event) => {
      const { routerLink } = props as any;
      if (!routerLink) return;

      const routerProps = Object.keys(props).filter(p => p.startsWith(ROUTER_PROP_REFIX));

      if (navManager !== undefined) {
        let navigationPayload: any = { event: ev };
        routerProps.forEach(prop => {
          navigationPayload[prop] = (props as any)[prop];
        });
        navManager.navigate(navigationPayload);
      } else {
        console.warn('Tried to navigate, but no router was found. Make sure you have mounted Vue Router.');
      }
    }

    return () => {
      getComponentClasses(attrs.class).forEach(value => {
        classes.add(value);
      });

      const oldClick = (props as any).onClick;
      const handleClick = (ev: Event) => {
        if (oldClick !== undefined) {
          oldClick(ev);
        }
        if (!ev.defaultPrevented) {
          handleRouterLink(ev);
        }
      }

      let propsToAdd = {
        ref: containerRef,
        class: getElementClasses(containerRef, classes),
        onClick: handleClick,
        onVnodeBeforeMount: (modelUpdateEvent) ? onVnodeBeforeMount : undefined
      };

      for (const [prop, value] of Object.entries(props)) {
        if (value !== EMPTY_SENTINEL) {
          propsToAdd[prop] = value;
        }
      }

      if (modelProp) {
        propsToAdd = {
          ...propsToAdd,
          [modelProp]: props.modelValue !== EMPTY_SENTINEL ? props.modelValue : modelPropValue
        }
      }

      return h(name, propsToAdd, slots.default && slots.default());
    }
  });

  Container.displayName = name;
  componentProps.push(ROUTER_LINK_VALUE);
  if (modelProp) {
    componentProps.push(MODEL_VALUE);
    Container.emits = [UPDATE_VALUE_EVENT, modelUpdateEvent];
  }

  Container.props = {};
  for (const componentProp of componentProps) {
	Container.props[componentProp] = { default: EMPTY_SENTINEL };
  }

  return Container;
}
Example #22
Source File: use-keyboard.spec.ts    From vooks with MIT License 5 votes vote down vote up
describe('# useKeyboard', () => {
  it('works with keyup & keydown', () => {
    const KeyDownArrowUp = jest.fn()
    const KeyUpArrowDown = jest.fn()
    const wrapper = mount(defineComponent({
      setup () {
        useKeyboard({
          keydown: {
            ArrowUp: KeyDownArrowUp
          },
          keyup: {
            ArrowDown: KeyUpArrowDown
          }
        })
      }
    }))
    expect(KeyDownArrowUp).toHaveBeenCalledTimes(0)
    document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true }))
    expect(KeyDownArrowUp).toHaveBeenCalledTimes(1)
    document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true }))
    expect(KeyDownArrowUp).toHaveBeenCalledTimes(2)
    document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
    expect(KeyDownArrowUp).toHaveBeenCalledTimes(2)
    expect(KeyUpArrowDown).toHaveBeenCalledTimes(0)
    document.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown', bubbles: true }))
    expect(KeyUpArrowDown).toHaveBeenCalledTimes(1)
    document.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown', bubbles: true }))
    expect(KeyUpArrowDown).toHaveBeenCalledTimes(2)
    document.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowUp', bubbles: true }))
    expect(KeyUpArrowDown).toHaveBeenCalledTimes(2)
    wrapper.unmount()
    document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true }))
    document.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown', bubbles: true }))
    expect(KeyDownArrowUp).toHaveBeenCalledTimes(2)
    expect(KeyUpArrowDown).toHaveBeenCalledTimes(2)
  })
  it('works with pressed key', () => {
    const wrapper = mount(defineComponent({
      setup () {
        return {
          state: useKeyboard()
        }
      }
    }))
    expect((wrapper.instance as any).state.tab).toEqual(false)
    document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Tab', bubbles: true }))
    expect((wrapper.instance as any).state.tab).toEqual(true)
    document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Tab', bubbles: true }))
    expect((wrapper.instance as any).state.tab).toEqual(false)
  })
})
Example #23
Source File: Geometry.ts    From trois with MIT License 5 votes vote down vote up
Geometry = defineComponent({
  emits: ['created'],
  props: {
    rotateX: Number,
    rotateY: Number,
    rotateZ: Number,
    attributes: { type: Array as PropType<Array<GeometryAttributeInterface>>, default: () => ([]) },
  },
  // inject for sub components
  inject: {
    mesh: MeshInjectionKey as symbol,
  },
  setup(): GeometrySetupInterface {
    return {}
  },
  created() {
    if (!this.mesh) {
      console.error('Missing parent Mesh')
      return
    }

    this.createGeometry()
    this.rotateGeometry()
    if (this.geometry) this.mesh.setGeometry(this.geometry)

    Object.keys(this.$props).forEach(prop => {
      // @ts-ignore
      watch(() => this[prop], this.refreshGeometry)
    })
  },
  unmounted() {
    this.geometry?.dispose()
  },
  methods: {
    createGeometry() {
      const bufferAttributes: Record<string, unknown> = {}
      const geometry = new BufferGeometry()
      this.attributes.forEach(attribute => {
        if (attribute.name && attribute.itemSize && attribute.array) {
          const bufferAttribute = bufferAttributes[attribute.name] = new BufferAttribute(attribute.array, attribute.itemSize, attribute.normalized)
          geometry.setAttribute(attribute.name, bufferAttribute)
        }
      })
      geometry.computeBoundingBox()
      geometry.userData.component = this
      this.geometry = geometry
      this.$emit('created', geometry)
    },
    rotateGeometry() {
      if (!this.geometry) return
      if (this.rotateX) this.geometry.rotateX(this.rotateX)
      if (this.rotateY) this.geometry.rotateY(this.rotateY)
      if (this.rotateZ) this.geometry.rotateZ(this.rotateZ)
    },
    refreshGeometry() {
      const oldGeo = this.geometry
      this.createGeometry()
      this.rotateGeometry()
      if (this.geometry && this.mesh) this.mesh.setGeometry(this.geometry)
      oldGeo?.dispose()
    },
  },
  render() { return [] },
})
Example #24
Source File: use-click-position.spec.ts    From vooks with MIT License 5 votes vote down vote up
describe('# useClickPosition', () => {
  it('is null when not clicked', () => {
    const wrapper = mount(defineComponent({
      setup () {
        return {
          position: useClickPosition()
        }
      },
      mounted () {
        expect(this.position).toEqual(null)
      }
    }))
    wrapper.unmount()
  })
  it('works', () => {
    const comp = defineComponent({
      setup () {
        return {
          position: useClickPosition()
        }
      },
      mounted () {
        document.dispatchEvent(new MouseEvent('click', {
          clientX: 100,
          clientY: 100,
          bubbles: true
        }))
        expect(this.position).toEqual({
          x: 100,
          y: 100
        })
      }
    })
    // use two wrappers to cover all lines
    const wrapper1 = mount(comp)
    const wrapper2 = mount(comp)
    wrapper1.unmount()
    wrapper2.unmount()
  })
})
Example #25
Source File: Material.ts    From trois with MIT License 5 votes vote down vote up
BaseMaterial = defineComponent({
  emits: ['created'],
  props: {
    color: { type: String, default: '#ffffff' },
    props: { type: Object as PropType<MaterialPropsInterface>, default: () => ({}) },
  },
  inject: {
    mesh: MeshInjectionKey as symbol,
  },
  setup(): MaterialSetupInterface {
    return {}
  },
  provide() {
    return {
      [MaterialInjectionKey as symbol]: this,
    }
  },
  created() {
    if (!this.mesh) {
      console.error('Missing parent Mesh')
      return
    }

    if (this.createMaterial) {
      const material = this.material = this.createMaterial()
      // @ts-ignore
      watch(() => this.color, (value) => { material.color.set(value) })
      bindObjectProp(this, 'props', material, false, this.setProp)
      this.$emit('created', material)
      this.mesh.setMaterial(material)
    }
  },
  unmounted() {
    this.material?.dispose()
  },
  methods: {
    getMaterialParams() {
      return { ...propsValues(this.$props, ['props']), ...this.props }
    },
    setProp(material: any, key: string, value: any, needsUpdate = false) {
      const dstVal = material[key]
      if (dstVal instanceof Color) dstVal.set(value)
      else material[key] = value
      material.needsUpdate = needsUpdate
    },
    setTexture(texture: Texture | null, key = 'map') {
      this.setProp(this.material, key, texture, true)
    },
  },
  render() {
    return this.$slots.default ? this.$slots.default() : []
  },
  __hmrId: 'Material',
})
Example #26
Source File: use-clicked.spec.ts    From vooks with MIT License 5 votes vote down vote up
describe('# useClicked', () => {
  it('works', (done) => {
    const wrapper = mount(defineComponent({
      setup () {
        return {
          clicked: useClicked(100)
        }
      },
      mounted () {
        document.dispatchEvent(new MouseEvent('click', {
          bubbles: true
        }))
        expect(this.clicked).toEqual(true)
      }
    }))
    setTimeout(() => {
      expect((wrapper.instance as any).clicked).toEqual(false)
      wrapper.unmount()
      done()
    }, 200)
  })
  it('works on multiple instances', (done) => {
    const comp = defineComponent({
      setup () {
        return {
          clicked: useClicked(100)
        }
      },
      mounted () {
        document.dispatchEvent(new MouseEvent('click', {
          bubbles: true
        }))
        expect(this.clicked).toEqual(true)
      }
    })
    const wrapper = mount(comp)
    const wrapper2 = mount(comp)
    setTimeout(() => {
      expect((wrapper.instance as any).clicked).toEqual(false)
      expect((wrapper2.instance as any).clicked).toEqual(false)
      wrapper.unmount()
      document.dispatchEvent(new MouseEvent('click'))
      expect((wrapper2.instance as any).clicked).toEqual(true)
      setTimeout(() => {
        expect((wrapper2.instance as any).clicked).toEqual(false)
        wrapper2.unmount()
        done()
      }, 200)
    }, 200)
  })
})
Example #27
Source File: Mesh.ts    From trois with MIT License 5 votes vote down vote up
Mesh = defineComponent({
  name: 'Mesh',
  extends: Object3D,
  props: {
    castShadow: Boolean,
    receiveShadow: Boolean,
  },
  setup(): MeshSetupInterface {
    return {}
  },
  provide() {
    return {
      [MeshInjectionKey as symbol]: this,
    }
  },
  mounted() {
    // TODO : proper ?
    if (!this.mesh && !this.loading) this.initMesh()
  },
  methods: {
    initMesh() {
      const mesh = new TMesh(this.geometry, this.material)

      bindProp(this, 'castShadow', mesh)
      bindProp(this, 'receiveShadow', mesh)

      this.mesh = mesh
      this.initObject3D(mesh)
    },
    createGeometry() {},
    addGeometryWatchers(props: Readonly<ComponentPropsOptions>) {
      Object.keys(props).forEach(prop => {
        // @ts-ignore
        watch(() => this[prop], () => {
          this.refreshGeometry()
        })
      })
    },
    setGeometry(geometry: BufferGeometry) {
      this.geometry = geometry
      if (this.mesh) this.mesh.geometry = geometry
    },
    setMaterial(material: Material) {
      this.material = material
      if (this.mesh) this.mesh.material = material
    },
    refreshGeometry() {
      const oldGeo = this.geometry
      this.createGeometry()
      if (this.mesh && this.geometry) this.mesh.geometry = this.geometry
      oldGeo?.dispose()
    },
  },
  unmounted() {
    // for predefined mesh (geometry/material are not unmounted)
    if (this.geometry) this.geometry.dispose()
    if (this.material) this.material.dispose()
  },
  __hmrId: 'Mesh',
})
Example #28
Source File: RouteLayoutSource.ts    From convue with MIT License 5 votes vote down vote up
export function createRouterLayout(
  resolve: (layoutName: string) => Promise<Component | { default: Component }>,
) {
  return defineComponent({
    name: 'RouterLayout',

    async beforeRouteEnter(to, _from, next) {
      const name = to.meta.layout || 'default'
      const layoutComp = name
        ? ((await resolve(name)) as any).default
        : undefined

      next((vm: any) => {
        vm.layoutName = name
        if (name && layoutComp)
          vm.layouts[name] = layoutComp
      })
    },

    async beforeRouteUpdate(to, _from, next) {
      try {
        const name = to.meta.layout || 'default'
        if (name && !this.layouts[name])
          this.layouts[name] = ((await resolve(name)) as any).default

        this.layoutName = name
        next()
      }
      catch (error) {
        next(error)
      }
    },

    data() {
      return {
        layoutName: undefined as string | undefined,
        layouts: shallowReactive(
          Object.create(null) as Record<string, Component>,
        ),
      }
    },

    render(): VNode {
      const layout = this.layoutName && this.layouts[this.layoutName]
      if (!layout)
        return h('span')

      return h(layout as ConcreteComponent, {
        key: this.layoutName,
      })
    },
  })
}
Example #29
Source File: mixin.test.ts    From vue-i18n-next with MIT License 5 votes vote down vote up
describe('beforeCreate', () => {
  test('i18n option', async () => {
    const i18n = createI18n({
      legacy: true,
      locale: 'en',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    const App = defineComponent({
      template: `<p>{{ $t('bye') }}</p>`,
      i18n: {
        locale: 'ja',
        sync: false,
        messages: {
          ja: {
            bye: 'さようなら'
          }
        }
      }
    })
    const { html } = await mount(App, i18n)

    expect(html()).toEqual('<p>さようなら</p>')
  })

  test('__i18n option', async () => {
    const i18n = createI18n({
      legacy: true,
      locale: 'en',
      messages: {
        en: {
          hello: 'hello!'
        }
      }
    })

    const messages = {
      en: {
        bye: 'good bye!'
      }
    }
    const App = defineComponent({
      template: `<p>{{ $t('bye') }}</p>`,
      __i18n: [
        {
          locale: '',
          resource: messages as any // eslint-disable-line @typescript-eslint/no-explicit-any
        }
      ]
    })
    const { html } = await mount(App, i18n)

    expect(html()).toEqual('<p>good bye!</p>')
  })
})