In this article we will discuss a great front-end framework Vue.js. As you can see, the article is called “Vue.js for Doubters”, and if you still could not decide to try Vue.js in practice, then I hope that after reading you still decide on this.
Frameworks are designed to simplify our lives and free us from writing the same type of code. But, as the codebase of some frameworks grows heavily, they begin to add their share of complexity to the project. Because of this, when planning the development, we must consider two factors:
')
- the complexity of our application
- the complexity of the framework that we use
We abstract a little and call it internal complexity (that is, complexity that we cannot get rid of during development) and complexity of the tool with which we achieve a particular goal. Naturally, we can only manipulate the complexity of the tool.
From the above, we have two options for choosing a tool:
- Option failure . When the tool is not enough to cover the internal complexity. The functions necessary for the implementation of the application are absent in the framework, and we have to manually refine and add the necessary tools.
- Redundancy option When necessary for the application functionality overlaps only a small part of the tool. The rest of the toolkit hangs like a dead weight and only creates problems for us: design constraints, slow application loading, and so on.
So what to do? Perhaps I will be a little Captain Obvious, but we must act according to the principle: “For each goal - its own tool” When planning, we need to look for a middle ground so that the complexity (and, therefore, the functionality) of the applications are on the same level.
About Vue.js and author
So, let's look at Vue and how it can make it easier for us to develop an application.
The creator of Vue.js is Evan You, a former Google employee and Meteor Dev Group. He began to develop the framework in 2013, and in February 2014, the first public release took place. Vue is widely used among Chinese companies, for example: Alibaba, Baidu, Xiaomi, Sina Weibo, etc. It is included in the core of Laravel and PageKit. Recently, the free repository management system GitLab also switched to Vue.js.
At the end of September 2016, Vue.js 2.0 was released, even cooler and with an emphasis on performance — virtual DOM is now used, server rendering is supported, the ability to use JSX, etc. Although now it is supported only by the community, it keeps up with dignity even at the level of products of such giants as Google and Facebook (Angular2 and React 15), and gradually catches up with their popularity.
Consider the simplest example:
app.js
var demo = new Vue({ el: '#demo', data: { message: 'Hello, Singree!' } })
- create a new instance via new Vue
- in el, we define which element is being watched
- in data we have a state object
app.html
<div id="demo"> <p>{{message ? message : "no content"}}</p> <input v-model="message"> </div>
- in html, naturally, we should have an element with the selector we need
- We derive the data from the state in the mustache (mustache after all) syntax. Here we have the usual ternary expression
- The input is associated with the message value of the state object using the v-model directive.
//codepen.io/Demetrius/embed/KNaJLW/?height=468&theme-id=16150&default-tab=result
Vue.js concepts
The main concepts of Vue are:
- constructor
- Components
- directives
- transitions
In the first version there were still filters, but, as far as I know, in the current version they are considered deprecated.
Constructor
app.js
new Vue({ el: '<jQueryStyleSelector>', template: '<id || inline template>', data: { props: ' ', first_name: "", last_name: "" }, computed: { full_name: function(){ return this.first_name + this.last_name; // } }, methods: { // beforeCreate: function(){}, created: function(){}, beforeMount: function(){}, mounted: function(){}, beforeUpdate: function(){}, updated: function(){}, beforeDestroy: function(){}, destroyed: function(){}, customMethodsAlso: function(){ // data } } })
Working with Vue.js begins with creating a new instance new Vue. In el, we have an element that Vue is following. An element has been selected (or registered inline) in the template where Vue will render. The data stores the current state of the instance, and the computed method provides us with computed properties.
In the example, the calculated property full_name tracks first_name and last_name as dependencies and automatically synchronizes.
In methods, the following custom methods and methods of the Vue life cycle can be distinguished:
- beforeCreate - watches data and initializes events
- created - looks, whether there is an el or template. If so, it renders in them; if not, it searches for the render method.
- beforeMount - creates vm. $ el and replaces them with el
- mounted - the element is rendered
When the state changes:
- beforeUpdate - renders the VDOM again and compares with the real DOM, applies the changes
- updated - changes rendered
- beforeDestroy - complete dismantling of watchers, internal components and event listeners
- destroyed - called when the operation stops
Directives
Directives are special attributes for adding additional functionality to html elements.
Consider some built-in directives (who worked with Angular, they will seem very familiar to them):
- V-bind - dynamically associated with one or more attributes.
- V-cloak - hides “baleen” expressions, until the data is pulled
- v-if - condition for rendering the element
- V-else - means “else block” for v-if
- V-for - loop through an array of objects
- V-model - connects the state with the input element
- V-on - connects the event listener with the element
- V-once - renders an element only at the beginning and no longer tracks it.
- V-pre - does not compile the element and its children
- V-show - toggles the visibility of the element, changing the CSS display property
- V-text - updates the textContent element
All Vue directives have the prefix “v-”. A directive is passed some state value, and the arguments can be html attributes or events.
html
<div v-my-directive="someValue"></div>
js
Vue.directive('my-directive', { bind: function () { // // , // }, update: function (newValue, oldValue) { // - }, unbind: function () { // // , bind() } })
Components
Components help to extend the basic html elements and implement reusable code. In essence, the components are reusable parts of the UI. At the design stage, we split our application into independent parts and get the tree structure of the components.
In Vue.js, there are no special requirements for the names of the components, but it is good practice to follow the W3C rules for custom components, that is, lower case letters and hyphenation.
app.js
Vue.component('simple-counter', { template: '<button v-on:click="counter += 1">{{ counter }}</button>', data: function () { return { counter: 0 } } }) new Vue({ el: '#demo' })
A new component is declared using Vue.component, and in the first argument we pass the name of the new tag (in our case, simple-counter)
//codepen.io/Demetrius/embed/ObgyQP/?height=468&theme-id=16150&default-tab=result
Communication between vue components is carried out according to the principle of “Props in, Events out”. That is, from the parent element to the child information is transmitted through props, and back - events are triggered.
Also in Vue.js there are so-called single-file components. We create a file with the .vue extension and write styles, pattern and logic there. And you can write on any convenient preprocessor (SASS, Stylus, PostCSS, Jade, ...) and language compiled in JS (CoffeeScript, TypeScript).
app.js
// comment.vue <style lang="sass"> button { border: 1px solid gray; &.blue { border-color: blue; } } </style> <template lang="jade"> avatar(:user='user') input(type='text', v-model='content') button.blue(@click='submitComment') </template> <script> import Comment from '../models' import avatar from './components/avatar.vue' export default { props: ['user'], components: { avatar }, data () { return { content: '' } }, methods: { submitComment (e) { e.preventDefault(); var comment = new Comment(this.content) comment.save().then(() => { alert('o_O') this.content = '' }) } } } </script>
Transitions
Vue provides various ways to apply animation effects when elements are drawn, updated, or deleted from the DOM. They include tools for:
- automatically applying classes for CSS transitions and animations
- integration of third-party libraries for CSS animations, such as Animate.css
- use javascript to manipulate DOM
- integration of third-party JavaScript libraries for animations, such as Velocity.js
Consider a simple example:
html
<div id="demo"> <button @click="show = !show">Toggle show</button> <transition name="bounce"> <p v-if="show">Look at me!</p> </transition> </div>
js
new Vue({ el: '#demo', data: { show: true } })
//codepen.io/Demetrius/embed/ZByQzx/?height=490&theme-id=16150&default-tab=result
Framework ecosystem
Routing
In Vue.js, a separate vue-router package is responsible for routing. It supports nested routes to nested components, offers a simplified API for navigation hooks, managed scrolling behavior, and advanced navigation controls.
Here is a small example:
app.js
import Vue from 'vue' import VueRouter from 'vue-router' import App from './app.vue' import ViewA from './view-a.vue' import ViewB from './view-b.vue' Vue.use(VueRouter) const router = new VueRouter() router.map({ '/a': { component: ViewA }, '/b': { component: ViewB } }) router.start(App, '#app')
app.vue
<div> <h1> , </h1> <router-view></router-view> </div>
Ajax requests
To work with Ajax requests, there is a vue-resource plugin. It provides capabilities for creating web requests and processing responses using XMLHttpRequest or JSONP. Also a feature of the plugin is support for Promise API and URI templates.
Example:
js
{
State management
Vuex is a pattern and state management library for applications on Vue.js. It provides a centralized overall state for all components in the application and rules that ensure a predictable change of state.
The image below shows the application on Vue + Vuex with the following parts:
- State (State), which is the only data source for components.
- Vue components (Vue components), which in essence are merely a declarative state representation.
- Actions (Actions) that catch the event that occurred, collect data from the external API and trigger the necessary mutations.
- Mutations (Mutations) - the only part that can change the state and, after receiving data from the Actions, applies them to the state.
Build System and Developer Tools
For debugging in the browser, there is
Vue-devtool s (unfortunately, so far only for Chrome), which allows you to see what components are in our application and their current state.
It also works great with Vuex and allows you to perform so-called time-travel debugging: in the browser we can see the history of the states and switch between them.
Why should I use it
Vue is amazing! I think it's great that I can just connect it on the page and start working without having to shamanize with the build system or CLI. It's very easy to start working with it, even if you have never worked with JavaScript frameworks. It is the perfect combination of convenience and power. Consider a few more arguments in his favor:
- Now it is even smaller. Runtime build Vue.js 2.0 weighs only 16kb, and together with vue-router and vuex - 26kb (about the same as the kernel of the first version).
- He is even faster. Vue.js has always paid a lot of attention to speed. The rendering layer is rewritten to a lightweight implementation of the virtual DOM — a fork of Snabbdom .
- Vue 2.0 supports server rendering. To do this, there is a module V ue-server-renderer that supports other tools from the Vue ecosystem (vue-router and vuex). It is now much easier to create isomorphic applications.
- The guys from Alibaba are working on Weex , a cross-platform native mobile UI (like ReactNative and NativeScript). From now on, Vue-components can be used for web, Android and iOS.
Vue went from a small amateur project to a widely used project with a large community, and I hope that I managed to dispel your doubts about whether to use this framework or not.
Thanks for attention!
The article was prepared by:
greebn9k (Sergey Gribnyak),
Dmitry-Ivanov (Dmitry Ivanov),
silmarilion (Andrey Khakharev)