• Translated by: The Vue Composition API proposal once caused a big debate in the community. A few days ago, I read this issue and saw the comments from Vue users and the reply from Yuxi. I have a deeper understanding of the design philosophy and problem solving of Composition API and React Hooks. Hereby translated.
  • Original text: github.com/vuejs/rfcs/…

@abalashov:

At the request of @yxx990803, open an issue here with my original comment under #42:

I am the author of “love letter” to the Vue: www.evaristesys.com/blog/love-l…

As a big promoter of Vue who appreciates its distinctive features and its performance on par with competing frameworks, I must say THAT I am disturbed and disappointed by the function API proposal. I agree with the above post that there are no serious problems worth fixing with such radical changes, and essentially this proposal amounts to chasing the shiny new thing. Admittedly, there are some code-breaking and modularity issues that need to be rerouted. But not all theoretical problems are worth changing.

One of the great things about Vue, as I mentioned in the article, is that, in 2019, it’s still written pretty much the same as it was when I first encountered it in late 2016. This is in stark contrast to the speed of modification and deprecation that is common in the JS/ Web world. Frank Chimero high level and keen view on this issue is worth to mention here: frankchimero.com/writing/eve…

From a principled and philosophical perspective, I think it is important to understand that introducing any form of radical API change is incompatible with any project, and that providing backward compatibility with older apis does not solve this problem. While acknowledging the fact that the 2.x API has not been deprecated and is at pains to emphasize, you still think of it as a sunset in the overall ecosystem. 2. X API is no longer a first-class citizen. A new way of doing things, which means favoring new ways of doing things, sample code, tutorials, books, etc., will inevitably adapt to it over time, resulting in management and direction disasters for those who invest in the vast Vue code. The new API inevitably becomes a statement of ideas and weakens the old API — indeed, “old” vs “new” exists — there is a thought valence.

When change is inevitable, people want to follow “best practices” to try to avoid bit rot, and there is psychological pressure to accept the current ethos. So, providing old option API support is not that helpful; This RFC guarantees backward compatibility with the 2.x option API and will slowly derail over time, as with The Mir space station. In effect, you are ruling that there is a new way of doing things, and they should be done that way.

I also agree with the criticisms in the shortcomings section above: worry about the obscurity of this approach and the tendency to lead to complex “spaghetti code.” One of Vue’s biggest selling points is its ease of use. It’s static enough, a major Vue’s organizational promise of shelf life and durability rather than evaporating in the hand, while too many other javasjavascript related promises capriciously change apis and architectures.

So the technical debate about code organization and modularity, from a business and ecological health perspective, should be played down in the RFC, I think, and the downside of improvement (small personal views) should be carefully and judiciously valued. I don’t see a problem compelling enough to merit such a radical solution, though for some time the Route 2.X promise was watched warily. It’s not worth throwing away the things that make Vue good.

I was born and raised in Russia, and there’s an old political anecdote about it:

Lazar Karganovich presented Stalin with a scaled-down replica of Moscow, a grand global socialist capital of Stalin’s imagination (like a copy of Hitler and Speer’s thousand-year-old German architecture). Most of the symbolic features of pre-revolutionary Moscow’s history have been destroyed, replaced by grand squares and huge buildings that highlight the class-conscious proletarian revolution, the grand marshal’s vision of the future and the enthusiasm, aesthetics and idealism of breaking away from the capitalist edifice.

Stalin asked, “Lazar, where is st. Basil’s Church?”

“It has been removed, it will be demolished.”

Stalin sighed and rolled his eyes.

“Lazar, put it back.”

@yyx990803:

I respect your opinion so please don’t take the following personally.

Are there any serious problems worth fixing with such radical changes, and essentially, the proposal amounts to chasing shiny new things

I strongly disagree with this. Logical composition can be one of the most serious problems with large projects. To quote what I said in another post:

  • The RFC post was also filled with users expressing how they found the RFC to be an immediate solution to the problem they were facing. And they mention that the current object-based syntax is the bottleneck that keeps their project from scaling. I admit that there are plenty of people like you who have probably never experienced this experience (totally doable, that’s great!). But if an aesthetic choice arises from a real maintenance burden (admittedly only on certain types of projects), then it is no longer just a matter of aesthetics. Denying some people better abstractions to solve their problems because of other people’s aesthetic preferences seems like a wrong deal.

Vue started small, but today it is used on a very wide range of projects, with varying levels of complexity and business domains. Users dealing with different types of projects encounter different requirements, some of which can be handled easily with object-based apis, while others cannot. The main example is

  1. Large components (hundreds of lines) that encapsulate multiple logical tasks
  2. The need to reuse this logic across multiple components

For (1), each logical task is forced to split between option types. For example, a simple data fetching task might require prop, data properties, computed properties, Mounted hooks, and Watcher to work together. This means that when you take the component and try to understand its data retrieval logic, you’re constantly jumping up and down the options list trying to locate the relevant code snippets. Also, when you scan an attribute, even though you know its type, it’s a little harder to say which logical task it’s used for. The more logical topics are added to the component, the worse it gets. Under the new API, by contrast, all data retrieval logic can be organized together and, more importantly, cleanly extracted into a single function, or even a single file.

Similar to this problem is file organization in a project. Many of us agree that organizing files by file type (such as splitting everything into HTML, JS, and CSS folders) does not support scaling. The code related to a feature will have to be spread across 3 folders simply because of the false impression of “separation of concerns”. The key here is that “concerns” are not defined in terms of file types. Instead, most of us choose to organize our files in terms of functions and responsibilities. This is why people love Vue single-file components. SFC is a way of organizing code functionally. Ironically, when SFC was first introduced, many people resisted it because they thought it violated separation of concerns, until they realized that SFC was actually a more reasonable way to separate concerns.

Point (2) has been explained at length in the RFC motivation section, showing that it implements what mixins/higher-order components/local slots can do but avoids their disadvantages.

In view of React Hooks, we have found some features that help these users solve the above problems. This is the fundamental reason why we put forward this proposal. It is indeed “new”, but we accept new things because they represent a solution to problems with objects, not just because they are “new”. In the long run, the utility of the new API will pay huge dividends in terms of time savings for developers dealing with these issues.

Type safety is also an important consideration – again, something that many users desperately want but may not show much value to those who don’t use TS. That’s understandable – but I think it’s a little selfish to claim that it didn’t solve anything because the problem was solved didn’t affect his behavior.

Introducing any form of radical API change is incompatible with any project, and providing backward compatibility with older apis does not solve this problem

“Incompatible” is defined as users being forced to change their code. Since users will not have to modify their existing code, it is not incompatible. I don’t see anything else to argue about in this regard.

Even if backward compatibility isn’t enough, then you’re essentially saying that a project should never introduce any radical new ideas, ever. I think this is a program policy argument, and if I vote, I will firmly vote against it. We will keep in mind that we will do our best to ensure the best interests of our users, but the project will evolve.

Concerns about the obscurity of this approach and the tendency to lead to complex “spaghetti code”. One of Vue’s biggest selling points is its ease of use. It’s static enough, a major Vue’s organizational promise of shelf life and durability rather than evaporating in the hand, while too many other javasjavascript related promises capriciously change apis and architectures.

Instead, the motivation for this proposal is precisely to improve the maintainability of long-term Vue projects.

If we look at any JavaScript project, the entire code starts with an entry file, which is essentially an implicit “main” function that gets called when your application starts. If a single function entry leads to noodle code, then all JavaScript projects should be noodle code – obviously not. Why is that? Because as developers we learn to organize code into modules or functions.

One of the core features of function-based API design is that understanding the code inside Setup () is no different from understanding conventional JavaScript code, and any techniques you use to organize regular JavaScript code can be used to organize setup() functions. Any knowledge/style guide/code review process your team writes that applies to normal code can be applied to the Vue Setup () function.

I agree that there is theoretically a low code quality floor with the new API, but as mentioned it can be mitigated by doing everything you already do to prevent spaghetti code in the non-Vue part of the code base. On the other hand, code written with the new API will have a generally higher code quality upper limit. Any code written in the new API can be rewritten into much higher-quality code than the option-based equivalent, given that you’ll have to mix and deal with its flaws.

I also want to point out that this RFC is not about trading simplicity for maintainability. We should be aware that we are comparing the impression of an API that you may have been using for years with an API that you are seeing for the first time. Basically, it’s how you think about changes in components:

  • Option-based apis assume that a component is defined by the type of property/method/option it contains.
  • A function-based API considers a component to be defined by the logical topic it encapsulates.

Many users lament the “loss of simplicity,” which is actually the loss of the ability to examine components as option types. But under the new API, it should be quite straightforward to implement a component parser that provides a view that allows you to view components with property types. In other words we can look at components from two perspectives, given that the options API is limited to only one (because the logical theme is lost when scattered among the options).

It’s not worth throwing away the things that make Vue good

I am tired of repeating “nothing is thrown away”. But we try to define what is really “what makes Vue good”. Many users who object to this RFC seem to define it as object syntax, as if to take away object syntax is to take away everything that makes Vue more Vue. But let’s see what’s left intact:

  • Template syntax is the same (and better!)
  • Responsive systems work the same way
  • The concepts of calculated properties, Watcher & component life cycle remain unchanged
  • The SFC format has not changed
  • CLI has not changed
  • The incremental nature of the framework has not changed
  • The team’s commitment to providing better development tools has not changed
  • Technically, even the object format hasn’t changed: everything that worked before will still work

Vue’s object syntax has been around since day one. Many of the above were added later along the way, and each contributed to Vue’s growth. If you believe object syntax is all that matters to you, I sincerely ask you to take a step back and rethink what really makes Vue. After all, this RFC is not such a radical change as it may seem.