loading...
Cover image for VueJS is dead, long live VueJS!

VueJS is dead, long live VueJS!

stefandorresteijn profile image Stefan Dorresteijn ・4 min read

With the release of the VueJS 3 "Request for Comment" documentation about two weeks ago, Evan You introduced the VueJS function-based API and has set the VueJS community ablaze. These new ideas are still in the "Request for Comments" stage, so they're far from set in stone, but because the RFC introduces such significant changes, I made a quick summary of what you need to know.

NB: All this information and much more is in the RFC, so I do suggest you read that.

Setup

VueJS 3 departs from the option-based API we've grown to love and introduces the setup() function, which will be where all the magic happens. This function single-handedly sets up the the logic for our component and returns data that's exposed to the template. The option-based API will continue to work even in VueJS 3, but this new function-based API will be the new standard.

For all the functionality we're used to from VueJS like reactive data, computed values, methods and watchers, we import functions from vue and use them in our setup() function. Here's a basic example from the RFC:

<template>
  <div>
    <span>count is {{ count }}</span>
    <span>plusOne is {{ plusOne }}</span>
    <button @click="increment">count++</button>
  </div>
</template>

<script>
import { value, computed, watch, onMounted } from 'vue'

export default {
  setup() {
    // reactive state
    const count = value(0)
    // computed state
    const plusOne = computed(() => count.value + 1)
    // method
    const increment = () => { count.value++ }
    // watch
    watch(() => count.value * 2, val => {
      console.log(`count * 2 is ${val}`)
    })
    // lifecycle
    onMounted(() => {
      console.log(`mounted`)
    })
    // expose bindings on render context
    return {
      count,
      plusOne,
      increment
    }
  }
}
</script>

But why?

If that example doesn't make it clear why this change was introduced, or if it feels like a step back in terms of usability, I understand. I had the same initial reaction and it took me a bit of time to figure out why this change was necessary. The v2.x API is widely loved and is often the reason why people move to VueJS from other frameworks like ReactJS or AngularJS, so a change this drastic seems like a strange idea.

Encapsulation is king

The component API was created in part to make it easier to reuse code across your application. While VueJS is seriously modular and uses components, the current option-based API doesn't allow for an easy extraction of functionality that relates to a single piece of functionality or data. You need to define your data(/state), computed values and methods separately, while they might all be related. This gets confusing when components grow and methods deal with different pieces of data.

This is where the new function-based API comes in. It allows you to extract all code related to a piece of logic and put it together in what they call a "composition function", which returns reactive state. An example given in the RFC uses one of those composition functions to extract the logic of listening to the mouse position:

function useMouse() {
  const x = value(0)
  const y = value(0)
  const update = e => {
    x.value = e.pageX
    y.value = e.pageY
  }
  onMounted(() => {
    window.addEventListener('mousemove', update)
  })
  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })
  return { x, y }
}

// in consuming component
const Component = {
  setup() {
    const { x, y } = useMouse()
    return { x, y }
  },
  template: `<div>{{ x }} {{ y }}</div>`
}

If we compare this to how we would write this functionality in the v2.x API, we can see that the functionality related to using the mouse position is all over the place, where in the v3.x API, it's quite nicely grouped in a singular function:

<template>
    <div>
        {{ x }} {{ y }}
    </div>
</template>

<script>
export default {
  data() {
    return {
      x: 0,
      y: 0,
    };
  },
  mounted() {
    window.addEventListener('mousemove', this.update);
  },
  beforeDestroy() {
    window.removeEventListener('mousemove', this.update);
  },
  methods: {
    update(e) {
      this.x = e.pageX;
      this.y = e.pageY;
    },
  },
};
</script>

And more

Encapsulation isn't the only reason why these changes are useful, so here are two other reasons why this change might be what VueJS needs.

The current option-based API in VueJS has an issue in that it doesn't properly support TypeScript type inference. The proposed changes fix this issue, and achieve full typing support, with TS code looking almost the same as JS code as a cherry on top of an already very useful pie.

VueJS is loved for its extremely small bundle size and this change shrinks that bundle even more. Since function and variable names can be shortened with standard minification (while object/class methods and properties can't), the code simply compresses better.

Thoughts?

Initial reactions to the RFC have been mixed, with some users comparing these changes to React and suggesting VueJS is losing its edge. My first response was far from positive too, but the longer I look at it, the more the encapsulation advantage starts to outweigh the cleanliness of the current API.

What are your thoughts?

Discussion

pic
Editor guide
Collapse
jaakidup profile image
Jaaki

It feels to me like all the front-end frameworks are constantly trying to scratch an itch that "maybe/probably doesn't exist".

It's all good that everyone is striving to make things better, but these types of changes don't only affect the projects you are still going to do, but also those you've already done. Then a few months later there will be another change, further removing various Vue (or any other FE framework) projects from one another.

In that respect I don't like that the whole development community is the guinea pig for framework development. ie. just as you figure out how a pencil works, someone goes and changes it :)

I guess I want the option to use the current or the next version whenever I want, to infinity. To much to ask?

Collapse
avieru profile image
av

Couldn't agree more. That's what separated Vue from others, a good common sense one way of building components, where you could hop from one code base to another an find the same approach because the framework had an opinion and consistency.

Now, the setup method will turn common way of doing things to be much like React, where each code base is different and largely a mess. Unfortunately components along don't solve having messy code bases.

Collapse
rhymes profile image
rhymes

I forgot about this aspect, I really liked the idea that most Vue apps were structured the same way! Maybe there was a compromise to be found between the current version and the needs explored by the new one. I don't know, it's too easy to comment from afar

Thread Thread
vonheikemen profile image
Heiker

If i had to guess i would say that is because 90% of tutorials begins with "let's install the vue cli and create a project."

One thing Vue got right was give the users freedom to do whatever they want but still provide a recommended way of doing things.

Is like a jedi mind trick, imagine Evan telling you "listen, i won't tell you how to live your life but if you do this thing and use those other things you will find money and happiness."

Collapse
matteorigon profile image
Matteo Rigon

You will be able to use 2.x API for all 3.x lifecycle and even beyond if community still heavily uses it. Otherwise they are very likely to release a compatibility plugin to let you use 2.x API for as long as you need

Collapse
dseeker profile image
D See Ker

yeah great, we can remain in "compatibility" box forever while Vue team only improves for the people adopting the new API.

NO. This should be a branching into a sister project, TypeVue.js, not a 3.x deprecating the original (eventually)

Thread Thread
omaraziz profile image
Omar Aziz

PREACH 🙌🏼

Collapse
seanmclem profile image
Seanmclem

these changes seem more like additions than breaking changes. Like react hooks were

Collapse
j133y profile image
Alexandre Santos

Well said! Agreed

Collapse
gerreth profile image
Gerret Halberstadt
const { x, y } = useMouse()

Like you wrote poeple did already compare, it reminds me quite a bit of React's hooks. But that's not a critique, having started with a new React project and having used hooks, I found them to be pretty useful. Vue should not shut themselves away from good concepts just to distinguish itself from other libraries/frameworks. I think incorporating good concepts and making proposals for new ones helps everybody.

Collapse
stevetaylor profile image
Steve Taylor

The difference is that hooks are in the component and executed on every render. Vue 3’d setup function would only be executed when the component is created.

Hooks is predicated on an assumption that creating functions is cheap, which isn’t always the case, especially in some old and/or embedded environments. This change seems to solve the same problems as hooks but in a more efficient manner.

Collapse
pringels profile image
Peter Ringelmann

You're writing single page apps in embedded environments?

Thread Thread
stevetaylor profile image
Steve Taylor

Yes. Smart TV apps tend to run in a browser and there isn’t a whole lot of horsepower to work with.

Thread Thread
puritanic profile image
Darkø Tasevski

Are you using Vue for building TV apps? I would love to hear your experiences with it if you did!

I was working on the Vue app built for TV last year and it was terrible in terms of performance and general usability. I guess that team that passed it to us was partly to blame because the code was a god damn spaghetti mess.

We're currently building apps for a few TV vendors and React is working fine, the only thing that Vue does better is the animations IMO.

Thread Thread
stevetaylor profile image
Steve Taylor

I’m using React, but if it was up to me, I’d probably use Svelte instead.

Thread Thread
stevetaylor profile image
Steve Taylor

I’m using React, but if the choice was mine, I’d love to try Svelte instead. It doesn’t use a virtual DOM, so there’s less overhead.

Thread Thread
pineapplethief profile image
pineapplethief

Svelte could be great for embedded since bundle size is a non-issue and no runtime gives performance boost

Collapse
ju66ernaut profile image
Chris

I have been using Vue for a few years now and have several medium to large projects in production and I have never felt the need for what this change provides. The examples used in the RFC feel like outliers or made to be more common than they actually are.

Collapse
matteorigon profile image
Matteo Rigon

So you've never used a mixin once on a big project? I really find it hard to believe.

Collapse
ju66ernaut profile image
Chris

I use mixins all the time. I am not sure what you are referring to. I didn't mention mixins.

Thread Thread
matteorigon profile image
Matteo Rigon

That's exactly the point. Mixins are the same composition pattern that 3.x API introduces, but with greater problems, for example :

  • Multiple mixins can clash when using the same properties
  • global mixins let you use properties and methods without even knowing where they are declared.

You can read more on the rendered RFC, but the point is that there can be quite many improvements that the 3.x API can give to applications, especially if they are big

Thread Thread
ju66ernaut profile image
Chris

I have never had an issue where two mixins clash and if so it sounds like a design problem more than a problem with the core API/framework and it should be addressed during dev time.

And the times I have been reviewing a component's logic and saw a prop or method being used and cant find it declared in that component I look in the mixins because thats likely the place its coming from.

Again I don't feel like these are common issues I have come across in the 3 years I have been using Vue professionally but that may just be me.

Thread Thread
rhymes profile image
rhymes

To be honest I hadn't had a problem either but I've never worked on a massively large Vue app either. Maybe they could have just introduced a different way to alias mixins so that methods had a prefix instead of adding a completely new way of using Vue

Thread Thread
amcsi profile image
Attila Szeremi⚡

You can get clashes in the Function API too, if you spread together the return values of several useXXX() functions and return them in setup().

Thread Thread
matteorigon profile image
Matteo Rigon

@ju66ernaut It is a design problem, but for example if you have two mixins both fetching a remote API, you need to be extra creative on the isLoading property name to avoid clashing, and check every other mixin to be 100% safe. Another problem is that if you use two third party libraries as mixins and they both declare a property, computed, or method with the same name you are pretty much out of options.

@amcsi Yes, but with the spread operator you are explicitly merging the keys and somehow take full responsibility of what can potentially clash 😄. With mixins your only option is to rename one of the properties, which can be problematic or even not possible if mixins come from 3rd party libs.

I don't wanna convince you that 3.x API is 100% better than the current, but as you can see the current implementation has some issues that cannot be solved easily

Thread Thread
amcsi profile image
Collapse
dseeker profile image
D See Ker

Me too.. I have SSR and Hybrid applications running on Android and iOS, always was able to go around any limitations I found. I haven't even had any issues with typecasting, what am I doing wrong?? hahaha

Collapse
dseeker profile image
D See Ker

Perhaps people writing huge projects that are crapping out because of lack of organization or bad design should investigate using microservices approaches instead?? just a suggestion

Collapse
puritanic profile image
Darkø Tasevski

Poor organization and project structure plus spaghetti code are so much worse once developers introduce mixins to it. I was working on at least two enterprise apps written in Vue with a bunch of overly complicated mixins. If the code is bad - it can be refactored, project structure can be reorganized, but when you have components with a logic that is really tightly coupled with mixins logic it is hell on earth. In the end, we had to rewrite the whole app...

Collapse
ivanbuncic profile image
Ivan Buncic

We should all just go Vanilla. At least I'm trying. Did a lot with React, Angular, Vue, now digin Svelte but I'm tired od learning.

Bein' selfemployed gives me the posibility to choose the stack and that is awesome.

Collapse
mickhaelcannon profile image
Max Cannon

My view maybe a bit simplistic, but I think I have a few points to make. While I've been seriously looking a Svelte 3.0 (compiler, not a framework that's similar in Vue2.0 syntax), I still love the current Vue from top to bottom. However, new complexity "just because" is not what I wanted from Vue - simplicity is. It's not the fact that I will be able to continue to use Vue as I use it now in 3.0. It's really the fact that "NOT EVERYONE USING VUE WILL BE ON THE SAME PAGE" - this can cause fragmentation in the development community, on dev teams and confuse, or even turn off, new Vue adopters seeking to learn the framework. Add the RFC as an optional plug-in, not a core change. Kind of like how we can write JSX within Vue. I'm not looking to defend my remarks - just wanting to state my opinion...period...

Collapse
rhymes profile image
rhymes

This reminds me that sometimes I feel tired that over the years I've been learning so many technologies to do the same exact thing :D

Collapse
clickys profile image
Clickys

What do you think about svelte?

Collapse
jwkicklighter profile image
Jordan Kicklighter

VueJS 3 departs from the option-based API we've grown to love and introduces the setup() function, which will be where all the magic happens.

This isn't exactly correct, and is actually a huge topic of debate on the RFC currently. The current format is not disappearing, it will be offered alongside the new setup() function. And it will stay this way if users continue to show that they use the "old" way throughout the lifetime of Vue v3.

Collapse
stefandorresteijn profile image
Stefan Dorresteijn Author

While that's absolutely true, my point was more to say that the RFC introduces an API that departs from the option-based API, even if that API will continue to be available.

Collapse
jwkicklighter profile image
Jordan Kicklighter

Yes, definitely. With the large amount of misunderstanding on Reddit, HN, and even the RFC thread itself, I'm just trying to help clear any confusion :)

The poor core team seems like they're dealing with a lot during this comment period.

Thread Thread
stefandorresteijn profile image
Stefan Dorresteijn Author

Oh yeah, I (and I'm sure they) appreciate it. I'll update the article to reflect that too :)

Collapse
beggars profile image
Dwayne Charrington

I don't think the issue here is solely the RFC, it's the way the Vue team communicates these changes to the community and responds to criticism from people. The way I have seen the Vue team interact with the community and criticism, it's not a good look in my opinion.

Just look at that RFC, people are worried and confused, and I don't think Evan is doing a very good job quelling the fire, to be honest.

One of the biggest reasons people either choose Vue over React or move to it from React was the fact it's cognitively a lot simpler. React gets messy and complex once you start building large apps with it.

All people see with this new RFC is the Vue team making more work for developers and introducing code changes that make Vue look more like React.

Coupled with the fact Evan has been showing a demo of v3 (a secretive prototype not publicly available) and some impressive benchmark numbers, but it seems to me that Vue 3 is nowhere near done and won't be done in 2019.

There seems to be a lot of uncertainty, and the perception to me is they're stuck between a rock and a hard place. They don't know how Vue 3 will look, they want to improve it, but at the same time, they're being held back by their own success (see Angular 1.x).

It raises the question many others are asking: why Vue 3 instead of React?

Collapse
levi_donaldson profile image
Levi Donaldson

Maybe the best comment yet. EXACTLY

Collapse
terabytetiger profile image
Tyler V. (he/him)

Thanks for taking the time to write this out. As a beginner, I suspected there were benefits to the change and this helped clear up the pieces that I was missing!

Personally, I kinda like the way setup() looks 👀

Collapse
liximomo profile image
liximomo

You can start using it right now with vue-function-api in vue2.

Collapse
rhymes profile image
rhymes

That's quite a change. I'm all for functional composition, Vue mixins are quite limited.

Was there a real need for it? Probably not as @jaakidup hinted at. Is it better than the current version? Yes.

I wonder how long "support" for Vue 2.x will go on because I don't see companies rewriting overnight.

Collapse
dseeker profile image
D See Ker

It's already stated in the RFC post that 2.x API is DEPRECATED, it's just that it will be included as compatibility mode for 3.x not gonna be improved any longer. So any of the updates and benefits the team makes will not come to the people who want to do the 2.x API

Collapse
stefandorresteijn profile image
Stefan Dorresteijn Author

I believe support for 2.x would run until 4.x, but none of this is set in stone either

Collapse
antoniosminas profile image
Antonios Minas

Stefan, I completely agree with your view (pun intended).

To be frank, I don't understand the frustration around these changes. I'm sure it's pretty clear to the devs right now that they'll need keep supporting the old API so I'm not at all afraid that I'll have trouble maintaining my current projects.

The useMouse example is a brilliant enough reason to use the new API in my future projects. Anything that boasts reusability, I'm for it.

Collapse
eli profile image
Eli Bierman

Great post! I think people initially missed the benefits of encapsulation and type inference that you explained so well because the syntax looks so different. I love these changes and think they make Vue simpler overall, and the smaller bundle size you mentioned is great. Also I think the Vue team is very responsive to the community and they’ve handled changes to the framework really well in the past, so I don’t think people need to be super worried about backwards compatibility. The fact that this conversation is all happening before even a beta release reflects the Vue team’s proactive approach to communicating about its development.

Collapse
levi_donaldson profile image
Levi Donaldson

NOOOOOO. Are you freaking kidding me? This is terrible. I don't care if it shaves .2 milliseconds off load time. This just sucks. C'mon Evan seriously? The reason vue was great is because it wasn't trying to be reacts bff.

This should NOT be a new version, this should be a split off entirely. Because you know what will happen....this will eventually fall into the old unsupported version.

Its already happening on the mobile side. Vue native is nothing more than react native with some syntax changes at this point. Why are you heading that way? Vue is fantastic like it is, just leave it alone. This might be one of the biggest blunders in all of software development. So disgusted by this.

Collapse
mrdionjr profile image
Salomon Dion

The Vue Core team has listened to the community feedback and decided to keep the current API and provide the new API as a plugin as stated in this tweet by Guillaume Chau twitter.com/Akryum/status/11431148....

Collapse
rhymes profile image
rhymes

Great decision making, it takes courage to change course!

Add it as a plugin, see if the community likes it, fixes the problems and then maybe merge it in the mainline.

Collapse
abdurrkhalid333 profile image
Abdur Rehman Khalid

As Far As I am concerned that VUE.JS was the First JavaScript Framework that I learned and it is quite simple for new beginners to get into the JavaScript Frameworks as well. After learning this I jumped to the Angular 2 at that time and it is also have its own benefits as well.

If a new comer goes directly into React or Angular then it can be a kind of overwhelming and he or she can fed-up from all this JavaScript frameworks and so on.

So as far as I know VUE.Js is still used and new beginners should start their JavaScript Journey From Here :)

Collapse
squidbe profile image
squidbe

I like it! Been using Vue for about 2 years and love it, but the composition function definitely reduces cognitive load for me. Separating logic based on lifecycle/config constraints usually increases cognitive load by having to jump through the code to understand what a specific user action results in. The less time I spend just trying to find out where the relevant code is located, the more time I can spend thinking about how to efficiently provide solutions and fix problems.

Collapse
kmayne profile image
Kian Mayne

A couple of thoughts:

  1. This seems like something that sounds like it has some good advantages but it's definitely something that needs testing out. Why make this the standard method straight away? Why not release it as an option and get feedback on what it's actually like to use in the real world?

  2. This is clearly a transition from declarative to imperative. There are numerous, well-documented reasons for why declarative syntax is better.
    Do the advantages of composing behaviours really outweigh these?

Collapse
dietergeerts profile image
Dieter Geerts

Lol. this is by no means a transition to imperative code. It's actually the other way around... With this setup function, we can go full FP, no more 'this' etc...

Collapse
rosslew76343051 profile image
Ross Lewis

It seems that the new Vue can be really useful for small startups as it allows them to develop an MVP as fast as possible. It's a quick and easy yet powerful tool to build a working prototype, as well as to add originality to a bigger project. I've found a captivating piece dedicated to VueJS 3 features and modifications and how your project can benefit from them.

Collapse
khalyomede profile image
Khalyomede

This is gonna be great for encapsulation indeed. Also like the fact that Vue still stick with their philosophy of providing different approaches. Hopefully they keep the old SFC API, because like you folks said, it help keep some kind of consistancy.

Just a question, it this new API going to make Vuex deprecated? I see that we can now declare states, and mutations/actions might be imported functions.

Collapse
rickmacgillis profile image
Rick Mac Gillis

Clean code is crucial to software engineering of any kind. Without it it makes maintenance a nightmare.

Don't get me wrong, I'm all for encapsulation in part BECAUSE of that reason, but using mixins to keep code in a different file sounds like a better compromise. The trade off is that mixins are like traits, but (AFAIK) they don't have the ability to rename their methods on import. So, they pollute the class with the extra methods instead of using their own class.

Unless VueJS 3 provides considerable value, or they deprecate VueJS 2 far too early, then people aren't going to migrate, even for new projects.

Collapse
mickhaelcannon profile image
Max Cannon

My view maybe a bit simplistic, but I think I have a few points to make. While I've been seriously looking a Svelte 3.0 (compiler, not a framework that's similar in Vue2.0 syntax), I still love the current Vue from top to bottom. However, new complexity "just because" is not what I wanted from Vue - simplicity is. It's not the fact that I will be able to continue to use Vue as I use it now in 3.0. It's really the fact that "NOT EVERYONE USING VUE WILL BE ON THE SAME PAGE" - this can cause fragmentation in the development community, on dev teams and confuse, or even turn off, new Vue adopters seeking to learn the framework. Add the RFC as an optional plug-in, not a core change. Kind of like how we can write JSX within Vue. I'm not looking to defend my remarks - just wanting to state my opinion...period...

Collapse
veebuv profile image
Vaibhav Namburi

Firstly this is purely an addative API - you don't need to use it, nor will you be forced to use it. The beauty about Vue is you can use the strong API given to you as default per 2.6.x or you can opt in to use the 3.x API.

Their need to intro this to fix mixins due to name clashes (i.e solve it using hooks principle) - doesn't make too much sense to me but hey Evan's, made some pretty good decisions so far.

You can always resolve to custom naming convensions with your mixins to derive source and prevent clashes

Collapse
jloic profile image
Loic Jeannin

Vue.js maintainers, for the sake of your project talk to Python core devs about python3 and learn from their mistakes. It looks like you are going down the same path and it's not a pleasant one...

Collapse
levi_donaldson profile image
Levi Donaldson

that's exactly when i jumped track

Collapse
anoop_ananthan profile image
🇮🇳 Anoop P A

I feel like I wasted a couple of my years. I should have chosen React. At least that would have given me a milage in the job market. I chose Vue just because of the love of it. We're not engaging in Vue projects. One debacle with Angular is enough already :(

Collapse
kevinnth profile image
KevinNTH

Encapsulation provided by this new syntax is awesome and addresses some of my current implementations in a better way.

I haven't read the RFC so far but this introduction to the new setup syntax looks really neat to me.

👍

Collapse
liximomo profile image
liximomo

You could try it with vue-function-api in vue2.

Collapse
liximomo profile image
liximomo

Actually, you can start using the new API right now with vue-function-api in vue2.

Collapse
wormss profile image
WORMSS

To be honest, both of these look horrible. I am so used to doing
@Component() export class MyApp extends Vue { blar blar }

Collapse
seanmclem profile image
Seanmclem

I like this format much better than the current 2.X Vue. I never really liked it before

Collapse
arxpoetica profile image
Robert Hall

The format reminds me quite a bit (in some ways) of Svelte 2 syntax.

Collapse
_zeushimself profile image
zeus himself

why are developers too clumsy, evan yu has not even released vue js 3 yet

Collapse
qm3ster profile image
Mihail Malo

Wow, so react hooky!

Collapse
lc profile image
Lucas Coupez

I was totally hooked on React hooks. Seeing this in Vue makes me really REALLY want to try Vue, and honestly makes me feel a little scared I will like it way too much.