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

Template allow access to global window object for JavaScript Expressions #1353

Closed
ConradSollitt opened this issue Jun 13, 2020 · 4 comments
Closed

Comments

@ConradSollitt
Copy link

ConradSollitt commented Jun 13, 2020

Version

3.0.0-beta.15

Reproduction link

https://codepen.io/conrad-sollitt/pen/RwrRbBb

Steps to reproduce

The codepen includes code for both Vue 2 and Vue 3 and will attempt to render the same simple template. Currently showing a blank page with the Vue 3 error.

To try the working Vue 2 Version comment out:

<script src="https://unpkg.com/vue@next"></script>

And uncomment:

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

What is expected?

This template:

<div v-bind:class="window.getDivClass('red')">Test</div>

Should end up calling window.getDivClass() and display a red div with "test" for the text.

What is actually happening?

It returns the following error:

TypeError: Cannot read property 'getDivClass' of undefined
    at Proxy.render (eval at compileToFunction (vue.global.js:11914), <anonymous>:9:63)
    at renderComponentRoot (vue.global.js:5345)
    at componentEffect (vue.global.js:8158)
    at reactiveEffect (vue.global.js:4166)
    at effect (vue.global.js:4141)
    at setupRenderEffect (vue.global.js:8150)
    at mountComponent (vue.global.js:8109)
    at processComponent (vue.global.js:8066)
    at patch (vue.global.js:7729)
    at render (vue.global.js:8790)

This may or may not be related to the following issue:
#1227

Comments in the HTML section on the code pen contain links to more advanced examples including a custom build of Vue that fixes the issue. I found this when adding support for Vue 3 Beta 15 to a small Routing and SPA framework https://www.dataformsjs.com/ that I created which uses Vue and works well with Vue 2.

I'm happy to provide more details and help if needed assuming this issue is not part of a design change for Vue 3. The custom build I created to work around the issue required only 2 lines to be added to Vue in packages/compiler-core/src/codegen.ts however I realize that the changes could have side effects or unintended consequences and would likely require many unit tests.

@ConradSollitt
Copy link
Author

Additionally global variables under window work in Vue 2 but not Vue 3 which is what my original app was using (basic example below and also commented out on the reference CodePen).

const template = `<div v-bind:class="getDivClass('red')">Test</div>`

The 2-line fix I mentioned earlier was really just for quick testing as additional code would be required to support all global variables. Regardless the code would not be large but would take a lot of testing and time to think about how to best implement it.

I hope this can be supported in Vue 3 because if not it would break compatibility with templates from Vue 2. I'm happy to help out if needed.

@yyx990803
Copy link
Member

yyx990803 commented Jun 15, 2020

Interestingly, this was never meant to work even in Vue 2. Vue template expressions by design should not rely on globals. It only works in your case because you are using a production build of Vue 2 that skips the globals check for performance reasons - it would throw an error if you switch to the dev build. The behavior inconsistency in Vue 2 is probably an issue to be fixed, but the assumption is you'd always develop using the dev build to get proper warnings and errors so some of these checks can be dropped in production.

@ConradSollitt
Copy link
Author

Thanks for the info. I wasn't sure if it was supposed to work or not. Next time I'll try dev versions for 2 and 3 before opening a new issue. I still have a few issues I'm investigating such as differences between Vue.config.errorHandler and app.errorHandler.

Overall I'm happy to report that migrating from Vue 2 to Vue 3 works great in my case and I expect many others that want to migrate an app from Vue 2 to Vue 3. I make use of some or the more advanced Vue 2 API's including undocumented watcher props and so far I was able to get a 90% working version of the same app in Vue 3 within 3 to 4 hours.

@yyx990803
Copy link
Member

@ConradSollitt that's very encouraging to hear! Thanks for the feedback.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants