Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

this undefined in filters #5998

Closed
callumacrae opened this issue Jun 29, 2017 · 9 comments
Closed

this undefined in filters #5998

callumacrae opened this issue Jun 29, 2017 · 9 comments

Comments

@callumacrae
Copy link

Version

2.3.4

Reproduction link

https://jsfiddle.net/xweeqtuw/1/

Steps to reproduce

open the fiddle

What is expected?

this to be the component

What is actually happening?

this is undefined in commonJS and window in jsfiddle.


Is this intentional, or should this be the component? I'd expect it to be the component.

Is this a good candidate for my first PR? 😄

@yyx990803
Copy link
Member

This is intentional in 2.x. Filters should be pure functions and should not be dependent on this context. If you need this you should use a computed property or just a method e.g. $translate(foo)

@yobyzal
Copy link

yobyzal commented Jul 13, 2017

You can take this as a parameter for your filter function.

Also, I think it's better to support this context that we can take advantage of pipe style.

For example, if we have fn1, fn2 and fn3, and the code like this {{ somevalue | fn1| fn2 | fn3 }} is clearer and simpler than {{ fn3(fn2(fn1(somevalue))) }}.

@askhat
Copy link

askhat commented Apr 1, 2018

I think I encountered a case in which it would be nice to have a context in a filter. I'm creating an geometry–visualization app, the core module is a projection of a real coordinate space on the screen. And there are objects at this space represented as vue components. I though filters would do the trick:

<canvas-component>
  <cavas-object
    :x="x | toPixelX"
    :y="y | toPixelY"/>
</canvas-component>

Props x and y are given in real unit, like meter, so to compute a filtered value, I need values of viewport's dimensions and some previously generated scale value.

I understand that I can use methods, and I'm actually using 'em. But I'm wondering if there are some options in my case.

@JounQin
Copy link
Contributor

JounQin commented Apr 2, 2018

I believe that there are some use cases that we need to access this in filter, for example in a SSR project: When we are implementing a translate filter, we need to create different translate instances for every request for different languages, and we can only access different instance via this.$ssrContext on server, so we have a workaround that change filter to method, but some people prefer a translate filter.

And we can also implement it in a hacky way which overwrite Vue.prototype._f method: https://github.com/JounQin/vue-translator/blob/master/lib/index.ts#L123-L137

However, it is just something we can do, but not recommended to do, because .call(this) is slower than direct calling.

Filter related source codes:
https://github.com/vuejs/vue/blob/master/src/core/instance/render-helpers/index.js#L23
https://github.com/vuejs/vue/blob/master/src/core/instance/render-helpers/resolve-filter.js#L8
https://github.com/vuejs/vue/blob/master/src/core/util/options.js#L401

@askhat
Copy link

askhat commented Apr 2, 2018

I'm absolutely convinced that filters must have a way access the context. The question's what core team is going to do about it?

@uiii
Copy link

uiii commented Aug 10, 2018

Yes I agree, there should be an option to use vue context in the filter, similar to child components. E.g. to be able to access parent component. I don't see the reason why filters should be pure functions. The pipe syntax looks better and is more readable than method calling, e.g. in number formatting where I need to access locale set on parent component: {{price | currency}} vs. {{currency(price)}}

@am05mhz
Copy link

am05mhz commented Sep 15, 2018

i also agree with component context in filters, if not, there is no point in providing per-component filters as opposed to global filters.

my point is, you should be able to access the component from a component filter, but not able to access component from a global filter

@Justineo
Copy link
Member

i also agree with component context in filters, if not, there is no point in providing per-component filters as opposed to global filters.

Actually there is. Different third-party components may use different filters with the same name. You need this isolation to prevent collisions.

@yyx990803
Copy link
Member

I'm absolutely convinced that filters must have a way access the context. The question's what core team is going to do about it?

Sorry but my opinion has not changed: filters should not, and will not have access to context. If you need context, use a method.

@vuejs vuejs locked as resolved and limited conversation to collaborators Sep 16, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants