Giter Club home page Giter Club logo

composition-api's People

Contributors

antfu avatar brenner8023 avatar chearon avatar dev-itsheng avatar digitorum avatar djaler avatar edwardnyc avatar hyf0 avatar jspoetry avatar kahirokunn avatar kidonng avatar kiroushi avatar leafstark avatar liaoyinglong avatar linusborg avatar liximomo avatar mannil avatar minatohikari avatar mister-hope avatar pikax avatar popolan1986 avatar posva avatar sapphi-red avatar shaonialife avatar sodatea avatar twithers avatar webfansplz avatar xiaoxiangmoe avatar ygj6 avatar yoyo930021 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

composition-api's Issues

Typescript props type inference is incorrect

The type of msg should be string, but is inferred to be of type StringConstructor

import { createComponent } from 'vue-function-api'

    const MyComponent = createComponent({
        props: {
            msg: String
        },
        setup(props) {
            console.log(props.msg == '1'); // string | undefined
           // Error:(13, 25) TS2367: This condition will always return 'false' since the types 'StringConstructor' and '"1"' have no overlap.
        }
    })

The new watch is different from the old

create demo with cli, add code into App.vue

import { watch } from 'vue-function-api'

export default {
  watch: {
    $route: {
      handler: function (val, oldVal) {
        console.log('oldWatch: ', val)
      },
      immediate: true
    }
  },
  setup (props, ctx) {
    const { $route } = ctx.root

    watch(() => $route, (val, oldVal) => {
      console.log('newWatch: ', val)
    })
  }
}

the browser console output:
深度截图_选择区域_20190801110429

Local Component Access on Context Param

I've been playing with the new API the past couple days and really enjoy it. Thank you for all the work.

I may have missed it, or there is an alternate method to access the local component from within the setup function, but I have not been able to determine it.

From the RFC, it makes sense:

setup() {
  function onClick() {
    this // not the `this` you'd expect!
  }
}

The request is to either make it more clear how to access the local component for less astute people such as myself or add the functionality. Or perhaps help me understand why I wouldn't want to. An example.

[TypeScript] Props type infer

I met a problems here. And here is my solution. I wonder if there is any other solution which is better?

props:{
  src: { type: String, required: true }
},
setup(props){
    onMounted(() => {
      const img = new Image(); // Create new Image instance

      img.src = props.src as unknown as string;

      ...
    });
}

How to extends the context with e.g. $axios?

How to extend the context with own attrs? I use the Quasar framework with TypeScript and I can extends Vue instance with prototype inheritance.


export default async ({ Vue }) => {
  Vue.prototype.$axios = axios
}

declare module 'vue/types/vue' {
  interface Vue {
    $axios: AxiosStatic;
  }
}

Unfortunately, context.root contains Vue instance but it does not contain any prototyped extensions. :(

the `components` option in createComponent() doesn't support vue2 options

After I updated to 2.2.0, I found that when I run npm run serve, the develop server console ouput is just like this:

And I cannot run npm run build, the process will crash because of the error.

However, the browser console didn't show any errors, and it can run normally. So I cannot simply reproduce it online... In fact, I just create the project with vue-cli3, and change App.vue to this:

<script lang="ts">
    import {createComponent} from 'vue-function-api';
    import HelloWorld from './components/HelloWorld.vue';

    export default createComponent({
        components: {HelloWorld}
    });
</script>

I read the RFC again, and maybe 3.x will continue to be compatible with the 2.x components option?

And when I went back to 2.1.2, the type error disappeared. Did I go something wrong? Or how can I import and use *.vue components correctly?

How to access the element (aka $el) reference?

This is more a clarification on how would one (or should one?) access what's now presented as the this.$el HTML root template element.

Have I missed it in the RFC?

My workaround is to manually add an ref="el" to the root template element and use context.refs.el in, say, the onMounted callback.

Using vue-function-api in a new project

We are new in vue and we want start a new project in next three months. Well we want to make sure that we are choosing the best environment which will be compatible with Vue future development path. And we want to be Vue3 compatible (as much as possible).

According to this plugin and a complete description at related rfc , the next VueJs movement will be toward function API and the Class API RFC is moved a way.

So using Typescript in a vue project ( for example sample mentioned at https://sobolevn.me/2019/06/really-typing-vue ) will not be a good idea.
Am I correct ?

Is it recommended to use function api and typescript together? And is there any sample which can help to get start.

PS: I have read this comment some where (Vue@3 will have improved typescript support), is it still correct?!

按照api写的watch不能正常工作

const route = ctx.root.$route;
const parentDeptID = computed(() => route.params.id);
watch(parentDeptID, () => {
console.log(parentDeptID.value);
});

路由更改时候却没有执行console

Cannot work with CSS Modules

<script>
  export default {
    props: {
      themeName: String
    },

    computed: {
      $theme () {
        return this[this.themeName]
      }
    }
  }
</script>

<style module="$a">
  .wrapper {
    background: #000;
  }
</style>

<style module="$b">
  .wrapper {
    background: #fff;
  }
</style>

setup (props, context) cannot work with CSS Modules, because context does not has property $a or $b.

"x" get called outside of "setup()" error if you have different versions of `vue-function-api`

I am using a library X that uses [email protected] and my own app uses [email protected]

this creates 2 separate vue-function-api.

one in node_modules/vue-function-api (v2.1.2)
and another one in node_modules/X/node_modules/vue-function-api (v2.1.1)

I noticed vue-function-api uses a variable that is scoped within the package, when library X uses inject or provide, and you use it in your app, it will error out.

e.g.

// library X using [email protected]
export function useX() {
  const provider = inject<XProvider>(X_PROVIDER_KEY);
  if (!provider) {
    throw new Error('Unable to find provider');
  }
  return provider.value;
}

// app that uses [email protected]
export default Vue.extend({
  setup(props, context) {
    useX() // error, inject is called outside of setup
  }
});

Refs are undefined in setup() outside of lifecycle method

As a follow-up to liximomo/vue-function-api#10 (comment), the refs are now injected, but they can only be accessed inside of a lifecycle method. I don't believe this is the desired usage.

For example, I have a custom hook that binds and removes an event listener to the DOM node passed into it as a parameter. Because my custom hook cannot be called inside of a lifecycle method (because it has lifecycle methods inside of it), I can only call my custom hook at the first level of setup(). I like this functionality, and the errors were clear.

console.log("outside:");
console.log(context.refs.elementKeypress); // undefined

onMounted(() => {
  console.log("inside:");
  console.log(context.refs.elementKeypress); // <div data-v-763db97b="" class="element-keypress-demo">Ref</div>
});

// hook fails to bind event listener to 'undefined'
useElementKeypress("u", context.refs.elementKeypress, () => {
  console.log("clicked!");
});

See my CodeSandbox example

My problem is that the ref is undefined when passing it into the custom hook.

the onErrorCaptured() hook is not working as expected

I tried to use the the onErrorCaptured hook just as I used it in 2.x: code in CodeSandbox , outputs are in console.

The result is not in line with my expectation. Actually, the error was not captured, and because I usedVue.config.warnHandler, I found that the error was treated as a warn, onErrorCaptured was not called. But if I used it as 2.x, using errorCaptured hook, it works properly. Did I get something wrong? Thanks.

And sorry for my poor English.

Type error with string key using provide/inject.

Here is the declaration file:

import { AnyObject } from '../types/basic';
import { Wrapper } from '../wrappers';
export interface Key<T> extends Symbol {
}
export declare function provide(data: AnyObject): void;
export declare function provide<T>(key: Key<T>, value: T | Wrapper<T>): void;
export declare function inject<T>(key: Key<T>): Wrapper<T> | void;

But the doc says:

provide, inject

▸ provide(key: string | symbol, value: any)

▸ inject(key: string | symbol)

Equivalent with provide and inject from 2.x

So when I use string instead of exporting and importing symbols accross file, I got type error.

Can I use functional api with vuex?

Hi,

I am really eager to try this new api and especially the typescript integration. But can I use this api with vuex? If so could anybody provide an example? 🙂

Thanks!

[vue-function-api] "onMounted" get called outside of "setup()"

I am trying to create a hook:

import { value, computed, watch, onMounted } from 'vue-function-api';

export function useIntersectionObserver() {

    let intersectionObserver;

    const entry = value({});

    const callback = (entries) => {
        if (entries.length > 0) {
            entry.value = entries[entries.length - 1];
        }
    };

    onMounted(() => {
        intersectionObserver = new IntersectionObserver(callback);
        ...
    });

    onUnmounted(() => {
        intersectionObserver.disconnect();
    });

    return {
        isIntersecting: computed(() => entry.isIntersecting)
    };
}

And use that in some component:

  import { value, computed, watch, onMounted } from 'vue-function-api';
  import useIntersectionObserver from '...';

  export default {
    setup() {

      useIntersectionObserver();
    }
  }

Yet, I get the error:

[vue-function-api] "onMounted" get called outside of "setup()" 

Why is that, and how can I prevent this?

this.nextTick()

I have been relying on this for a significant part of a QA application I have been writing. Will this be available in some form or another in Vue 3? or should I begin rewriting things in .then()?

Thanks

Examples with vuex (mapState), router inside setup()

In Vue 2.x we can use this.$store and this.$router, inside setup, we should use context.store or something? The only way I could use it is import the store in every SFC, but I prefer have global access, like in Vue 2.x if it's possible... thanks!

Define reactive state for return of setup() automatically

When setup() return some plain props like this:

const Test = Vue.extend({
  render(h) {
    return h('div', [
      h('span', this.count),
      h('button', {
        on: {
          click: () => this.count++,
        },
      }, 'Increment'),
    ]);
  },
  setup() {
    return { count: 0 };
  },
});

count is not reactive but is attached to vm, so that it becomes a "immutable" state? Anyway, it might confuse the user.
Consider following implemention in src/setup.ts at line 58:

    Object.keys(binding).forEach(name => {
      let bindingValue = binding[name];
      if (!isWrapper(bindingValue)) {
        bindingValue = value(bindingValue);
      }
      bindingValue.setVmProperty(vm, name);
    });

Vue-Router navigation guards?

vue-function-api currently lacks support for vue-router in-component navigation guards (beforeRouteEnter, beforeRouteUpdate, and beforeRouteLeave). Any plans to implement them in the near future, or it's out of scope of this project?

Move to @vue/

Wouldn't it make more sense to move this package to @vue/function-api to keep in line with the other official Vue packages?

Wrapped array value dont work correctly

codesandbox here

versions: "vue-function-api": "^2.1.1"

<script lang="ts">
import { createComponent, value, Wrapper } from "vue-function-api";

export default createComponent({
  setup(props, context) {

    const tabs: Wrapper<string[]> = value(["tab2"]);
    tabs.value.push("tab3"); // ['tab2', 'tab3']

    // should ['tab1', 'tab2', 'tab3'] but ['tab2', 'tab2', 'tab3']
    tabs.value.unshift("tab1");

    // worked correctly
    const tabs2: string[] = ["tab2"];

    tabs2.push("tab3");

    // ['tab1', 'tab2', 'tab3']
    tabs2.unshift("tab1");

    return {
      tabs,
      tabs2
    };
  }
});
</script>

by the way, version 2.0.6 worked fine

Component created with createComponent() throws a type error when used in a render function

This sandbox reproduces the error I get in App.tsx

https://codesandbox.io/s/vue-function-api-typescript-issue-vrycw

For some reason the sandbox fails to import the components, but the code actually works when opened in vscode.

The code actually works without issue, it's just that typescript complains that JSX element type 'HelloWorld' does not have any construct or call signatures. when using a component declared with createComponent and a render function

[vue-function-api] "setup" must return a "Object", get "Function"

When using the plugin I get this error
[vue-function-api] "setup" must return a "Object", get "Function"

But the RFC says you can return a function from setup for manual renders https://github.com/vuejs/rfcs/blob/function-apis/active-rfcs/0000-function-api.md#usage-with-manual-render-functions

like this

import { value, createElement as h } from 'vue'

const MyComponent = {
  setup(initialProps) {
    const count = value(0)
    const increment = () => { count.value++ }

    return (props, slots, attrs, vnode) => (
      h('button', {
        onClick: increment
      }, count.value)
    )
  }
}

Call plugin function

Excuse me, I can't find how call plugin in new Vue API.

import myPlugin from './myPlugin';
Vue.use(myPlugin);

const myPlugin = {
	install(Vue) {
		Vue.prototype.$test = 'test string';
	}
}
export default myPlugin;
<script>
	export default {
		name: 'test',
		setup(props, vm) {
			console.log(vm.$test); //??
		}
	}
</script>

lack of life cycle method `serverPrefetch`

There is no life cycle method serverPrefetch , so can not be fully used on SSR.

In order to support SSR, the only choice is to remain serverPrefetch() method. And then, all methods and data properties used by serverPrefetch() has to be remained. And then, very little code can be ported into setup() method. And the code is in "mixed style", very ugly.

Component API in refs

Hey! There is some way to use component methods, when you get it from refs?. Example:

// Input component
export default createComponent({
  setup() {
    function validate() { awesome validation }
    return { validate };
  }
})

// in some components with inputs

export default createComponent({
  setup(props, vm) {
    function create() {
      // This refs hasn't my validate method
      vm.refs.myCustomInputComponent.validate();
    }
    return { create };
  }
})

How to access $scopedSlots?

Context supplied to setup only contains slots and this.$scopedSlots doesn't work inside setup.

Is there an official way to access scoped slots?

what dose setCurrentVM function doing

Hey gays, I am learning the source code.
and i see the setCurrentVM uesd in setup.ts like:

...
    let preVm = getCurrentVM();
    setCurrentVM(vm);
    try {
      binding = setup(props, ctx);
    } catch (err) {
      logError(err, vm, 'setup()');
    } finally {
      setCurrentVM(preVm);
    }
...

I not sure why here need to set the vm before call setup and reset the vm in finally section .

Can anyone help me to understand waht this is doing?
thx.

provide / inject not found , overwrite by plugins.

Hi team!

i am using vue-function-api as proxy to make project in Vue2 with Vue3 api style. Today i found issue with provide / inject:

first please see this code snippet :
provide / inject failed jsfiddle demo

step:

  1. run code, the preview box show white card html withthout any content.
  2. in js box remove / comment the line : Vue.use(VeeValidate, { inject: false }).
  3. run code, now inside white card show content injected.

Please see that in vee-validate plugin they allow disable auto-inject feature with option inject: false. But i dont know why provide() result replaced by other plugin, and dont know what vee-validate did underground.

other attention is: if use Vue2.x provide style :

{
    provide: {
       T: { ok: true }
    }
}

then we can inject use inject() at any child component no issue!

createComponent in TypeScript not inherit from Vue ComponentOptions

from Vue 2.x , when use with TypeScript we always write shims file d.ts whichs support static type property used inside vue component object.
ex: in Nuxt, each component use as page need defined $options.layout = 'layout name' like this:

{
    name: 'page',
    layout: 'myLayout'
}

To typesafe this custom property, they provide d.ts:

// ComponentOptions is declared in types/options.d.ts
declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    layout?: string
  }
}

For now vue-function-api provide function createComponent to help TS's developer can inherit typesafe from package. View d.ts file i see function defined:

export declare function createComponent<PropsOptions, RawBindings>(options: ComponentOptions<PropsOptions, RawBindings>): VueProxy<PropsOptions, RawBindings>;

export interface ComponentOptions<PropsOptions = ComponentPropsOptions, RawBindings = Data, Props = ExtractPropTypes<PropsOptions>> {
    props?: PropsOptions;
    setup?: SetupFunction<Props, RawBindings>;
}

This not inherit from Vue ComponentOptions , so we lost all typesafe from shims file.

A modify d.ts code will help a lot to inherit from Vue 2.x setup env .
Thankyou!

how use filters

"export 'filters' was not found in 'vue-function-api';
how use filters api in vue-function-api

Error: [vue-function-api] "onCreated" get called outside of "setup()"

The hook is not working properly

import {value, computed, watch, onMounted, onDestroyed, onCreated, state, createComponent} from 'vue-function-api';
    import Vue from 'vue';

    const MessageComponent = {
        setup() {
            const msg = value('hello');
            onMounted(() => console.log('hello'));
            return {
                msg
            };
        }
    };
    export default createComponent({
        setup() {
            const Message = Vue.extend(MessageComponent);
            const message = new Message();
            onCreated(() => console.log('create message'));
            return {};
        }
    });

Error: [vue-function-api] "onCreated" get called outside of "setup()"

Methon breaking changes in release and make this package vue2compatable

It has been 3 days after I commented in #62.
In my option, there should fewer breaking change. We should not start a breaking change as long as we can solve it, not open as much changes as we can. For examaple the name and components options , will probably inherited from vue 2, while now this package force us to hack it.

I really you should consider it carefully. Some users like me couldn't afford hacking and rehacking again and again while releasing new version.

unit test with typescript guide

How to make unit test using jest / mocha with typescript?
@vue/test-utils/shallowMount(component) => wrapper.vm.* does not contain type definitions which are returned from component so I cannot access anything even if returned data from setup exists in the browser when logging component to console.
Could someone provide an example please?

For example how to test returned values from setup?

export default {
  setup(){
    return { testThis: true };
  }
}

Do you support TypeScript-only Props Typing?

This specification.
https://github.com/vuejs/rfcs/blob/function-apis/active-rfcs/0000-function-api.md#typescript-only-props-typing

This component's props will be an empty object.

<template>
  <div> <!-- There is a div to prevent inheritance -->
    <button :type="type" :disabled="disabled"><slot /></button>
  </div>
</template>

<script lang="ts">
import { createComponent } from 'vue-function-api';

type Props = {
  type?: 'button' | 'submit';
  disabled?: boolean;
};

export default createComponent({
  setup(props: Props) {
    console.log(props); // Empty object {}
    const { type = 'button', disabled = false } = props;
    return {
      type,
      disabled,
    };
  },
});
</script>

provide() can be called only once per component

I've been testing out this new API, and found that provide() can be called only once per component. If there are more than one call to provide() (whether in setup() or hook functions), the latest provide() call seems to override all changes made by previous provide() calls. I believe this should be fixed.

To test this out, you can take a look at App.vue inside my code sandbox. If you uncomment the second provide() line, the app will spit out injection error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.