Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 21, 2019 12:33 pm GMT

Vue's Darkest Day

Today I was amazed to see the usually positive and friendly VueJS community descend into a bitter war. Two weeks ago Vue creator Evan You released a Request for Comment (RFC) for a new function-based way of writing Vue components in the upcoming Vue 3.0. Today a critical Reddit thread followed by similarly critical comments in a Hacker News thread caused a flood of developers to flock to the original RFC to voice their outrage, some of which were borderline abusive. It was claimed in various places that

  • All Vue code would have to be rewritten in a totally new way because the existing syntax was being removed and replaced with something else;
  • All the time people had spent learning Vue had been wasted given everything was about to change;
  • The new syntax was worse than the old, did not enforce structure, and would lead to spaghetti code;
  • The Vue Core team had suddenly implemented a huge breaking change without any consultation;
  • Vue is turning into React!
  • No, Vue is turning into AngularJS/Angular!
  • All HTML now needs to be written as a giant string!

With walls of negative comments on the Reddit Thread one may be surprised to discover on going to the RFC page that You's RFC has an overwhelmingly high ratio of positive to negative emoji reactions, and many of the initial comments were quite positive. Indeed, the very first comment is particularly full of praise.

I was the person who wrote that first comment. I happened to get a notification that there was a new RFC, read it straight away, saw that it was just what I wanted from Vue 3.0 and that it would help immensely, and left the first comment within 15 minutes of the RFC being published to express my gratitude. I hope to expand here on why I think the new proposal is such a great idea, but first, to address some of the criticism.

I suspect that many people got a little worked up after reading the Hacker News or Reddit threads which had some somewhat misleading comments, and voiced their outrage without reading the original proposal. Evan You has now updated the proposal with a Q&A that addresses many of the issues people have, but to summarise,

  • You don't need to rewrite any code if you don't want to - the new syntax is additive, and the old syntax will remain valid throughout Vue 3.0 and as long as it is still widely used. Even if it eventually gets removed from the Core code, plugins could easily allow the old syntax to be still 100% valid.
  • Time spent learning Vue was not wasted - the new component syntax uses the same concepts that you spent time learning, and other concepts such as Single File Components, templates, and scoped styles work exactly the same.
  • A change hasn't been made without consultation - the RFC is the consultation. The new syntax is still a long way from being released.
  • And no, HTML code doesn't need to be written as a giant string.

A slightly more subjective point is that the new syntax is inferior to the old, and will lead to less structured code. I hope to demonstrate with a simple example why I got so excited when I saw the RFC, and why I think it is superior and will lead to better structured code.

Consider the following fun component that allows a user to enter details of their pet and changes aspects of the form as they enter details. Note that

  • The header text will change based on the pet name they type;
  • The border color will change based on the pet colour they select, including with a shadow whose color is calculated based on the selected color;
  • The header text size and the border style will change based on the pet size that the user selects.The rendered componentYou can try out a demo of the component here and can view the full code using Vue 2.x here (see components/Vue2.vue).

Consider part of the JavaScript of this component:

  data() {    return {      petName: "",      petColor: "#000",      petSize: ""    };  },  computed: {    header: function() {      if (this.petName) {        return "My Pet " + this.petName;      }      return "Enter Pet Details";    },    petColorDarker: function() {      return tinycolor(this.petColor)        .darken()        .toString();    },    shadow: function() {      return "2px 2px " + this.petColorDarker;    },    borderStyle: function() {      switch (this.petSize) {        case "Small":          return "dotted";        case "Medium":          return "dashed";        default:          return "solid";      }    },    headerSize: function() {      switch (this.petSize) {        case "Small":          return "12px";        case "Large":          return "60px";        default:          return "30px";      }    }  }

Essentially we have some data, and various properties computed off that data. And notice that in Vue 2.x there is no way to keep related things together. We can't keep the data declaration petColor next to the petColorDarker computed property because in Vue 2.x things are grouped by type.

Of course this doesn't matter too much for a small example like this. But imagine a bigger example, that had a piece of functionality that needed data, computed, methods, and even a watcher or two. There's currently no good way to keep related things together! One might use something like Mixins or Higher Order Components but these have issues - it's hard to see where properties are coming from and there are issues with namespace clashing.

Rather than organising components by option type, the new proposal allows us to organise components by actual functionality. It's similar to how you organise your personal files on your computer - you usually don't have a 'spreadsheets' folder and a 'word documents' folder, instead you might have a 'work' folder and a 'holiday plans' folder. Consider the above component written in the proposed syntax (as best as I am able to without seeing the output - let me know of any bugs you see!):

  setup() {    // Pet name    const petName = value("");    const header = computed(() => {      if (petName.value) {        return "My Pet " + petName.value;      }      return "Enter Pet Details";    });    // Pet color    const petColor = value("#000");    const petColorDarker = computed(() => {      return tinycolor(petColor.value)        .darken()        .toString();    });    const shadow = computed(() => "2px 2px " + petColorDarker.value);    // Pet size    const petSize = value("");    const borderStyle = computed(() => {      switch (petSize.value) {        case "Small":          return "dotted";        case "Medium":          return "dashed";        default:          return "solid";      }    });    const headerSize = computed(() => {      switch (petSize.value) {        case "Small":          return "12px";        case "Large":          return "60px";        default:          return "30px";      }    });    // All properties we can bind to in our template    return {      petName,      header,      petColor,      shadow,      petSize,      borderStyle,      headerSize    };  }

Note that

  • It's ridiculously easy to group related things together;
  • By looking at what gets returned by the setup function we can easily see what we have access to in our template.

On top of that, the new syntax easily allows full TypeScript support which was difficult to achieve in the Vue 2.x object-based syntax. And we can easily extract out reusable logic into reusable functions. Something like

function usePetName() {  const petName = value("");  const header = computed(() => {    if (petName.value) {      return "My Pet " + petName.value;    }    return "Enter Pet Details";  });  return {    petName,    header  };}function usePetColor() {  const petColor = value("#000");  const petColorDarker = computed(() => {    return tinycolor(petColor.value)      .darken()      .toString();  });  return {    petColor,    petColorDarker  };}function petSizeToBorderStyle(sizeWrapper) {  const borderStyle = computed(() => {    switch (sizeWrapper.value) {      case "Small":        return "dotted";      case "Medium":        return "dashed";      default:        return "solid";    }  });  return { borderStyle };}function petSizeToHeaderSize(petSizeWrapper) {  const headerSize = computed(() => {    switch (petSizeWrapper.value) {      case "Small":        return "12px";      case "Large":        return "60px";      default:        return "30px";    }  });  return { headerSize };}export default {  setup() {    const { petName, header } = usePetName();    const { petColor, petColorDarker } = usePetColor();    const shadow = computed(() => "2px 2px " + petColorDarker.value);    const petSize = value("");    const { borderStyle } = petSizeToBorderStyle(petSize);    const { headerSize } = petSizeToHeaderSize(petSize);    return {      petName,      header,      petColor,      shadow,      petSize,      borderStyle,      headerSize    };  }};

In Vue 2.x I often find myself writing a "monster component" that is hard to break up into smaller pieces - it can't be decomposed into other components because there is too much happening based on a small amount of state. However using the proposed syntax it's easy to see how big components could have logic broken up into smaller reusable pieces, moved into separate files if necessary, leaving you with small, easy-to-understand functions and components.

Is this Vue's darkest day so far? It looks like it. What was until now a community mostly united behind the project's direction has splintered. But I have hope that people will take another look at a proposal that doesn't break anything, still allows them to group things by option type if that's what they like doing, but allows for so much more - clearer code, cleaner code, more interesting library possibilities, and full TypeScript support.

Finally, when using open source software, it's good to remember that the maintainers are putting a lot of effort into something that you get to use for free. Some of the borderline abusive criticism seen today is something that they really shouldn't have to put up with. Thankfully the disrespectful comments were a minority (albeit a sizeable one) and many were able to express themselves in a more respectful manner.


Original Link: https://dev.to/danielelkington/vue-s-darkest-day-3fgh

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To