Questions - Vue

Record some Vue questions.

What are the Advantages/Disadvantages of Vue.js?

Advantages

  • Easy for applications and interfaces development
  • Support Two-way communication as like AngularJs
  • Ability to control the states
  • Natural thought process

Disadvantages

  • Limited scope
  • Single creator
  • Small developer community

Explain the basic logical Vue.js app organization

A Vue.js application consists of a root Vue instance created with new Vue, optionally organized into a tree of nested, reusable components. For example, a todo app’s component tree might look like this:

1
2
3
4
5
6
7
8
Root Instance
└─ TodoList
├─ TodoItem
│ ├─ DeleteTodoButton
│ └─ EditTodoButton
└─ TodoListFooter
├─ ClearTodosButton
└─ TodoListStatistics

All Vue components are also Vue instances.

Explain the differences between one-way data flow and two-way data binding?

In one-way data flow the view part of application does not updates automatically when data Model is change we need to write some code to make it updated every time a data model is changed. In Vue.js v-bind is used for one-way data flow or binding.

In two-way data binding the view part of application automatically updates when data Model is changed. In Vue.js v-model directive is used for two way data binding.

1
2
3
4
5
6
7
8
<div id="app">
{{message}}
<input v-model="message">
</div>
<script type="text/javascript">
var message = 'Vue.js is rad';
new Vue({ el: '#app', data: { message } });
</script>

What are Components in Vue.js?

Components are one of most powerful features of Vue js. In Vue components are custom elements that help extend basic HTML elements to encapsulate reusable code.
Following is the way to register a Vue component inside another component:

1
2
3
4
5
6
export default {
el: '#your-element'
components: {
'your-component'
}
}

What are Directives in Vue.js, List some of them you used?

Vue.js directives provides a way to extend HTML with new attributes and tags. Vue.js has a set of built-in directives which offers extended functionality to your applications.You can also write your custom directives in Vue.js .
Below are list of commonly used directives in Vue.js

  • v-show
  • v-if
  • v-model
  • v-else
  • v-on

Can I pass parameters in computer properties in Vue.js?

You can use a method or computed function.
The method way:

1
2
3
4
5
6
<span>{{ fullName('Hi') }}</span>
methods: {
fullName(salut) {
return `${salut} ${this.firstName} ${this.lastName}`
}
}

Computed property with a parameter way:

1
2
3
4
5
6
computed: {
fullName() {
return salut => `${salut} ${this.firstName}
${this.lastName}`
}
}

How can I fetch query parameters in Vue.js?

You have access to a $route object from your components, that expose what we need.

1
2
//from your component
console.log(this.$route.query.test)

How to use local storage with Vue.js?

You can just do following:

1
2
3
localStorage.setItem('YourItem', response.data)
localStorage.getItem('YourItem')
localStorage.removeItem('YourItem')

What is filters in Vue.js?

Vue.js allows you to define filters that can be used to apply common text formatting. Filters are usable in two places: mustache interpolations and v-bind expressions. Filters should be appended to the end of the JavaScript expression, denoted by the “pipe” symbol:

1
2
3
4
<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>

What are components props?

Every component instance has its own isolated scope. This means you cannot (and should not) directly reference parent data in a child component’s template. Data can be passed down to child components using props. Props are custom attributes you can register on a component. When a value is passed to a prop attribute, it becomes a property on that component instance.

1
2
3
4
5
Vue.component('blog-post', {
// camelCase in JavaScript
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})

nextTick

Vue.nextTick([callback, context]) defer the callback to be executed after the next DOM update cycle. Use it immediately after you’ve changed some data to wait for the DOM update.

1
2
3
4
5
6
7
8
9
10
11
12
// modify data
vm.msg = 'Hello'
// DOM not updated yet
Vue.nextTick(function () {
// DOM updated
})

// usage as a promise (2.1.0+)
Vue.nextTick()
.then(function () {
// DOM updated
})

Lifecycle

img

beforeCreate

Called synchronously immediately after the instance has been initialized, before data observation and event/watcher setup.

created

Called synchronously after the instance is created. At this stage, the instance has finished processing the options which means the following have been set up: data observation, computed properties, methods, watch/event callbacks. However, the mounting phase has not been started, and the $el property will not be available yet.

beforeMount

Called right before the mounting begins: the render function is about to be called for the first time.

mounted

Called after the instance has been mounted, where el is replaced by the newly created vm.$el. Note that mounted does not guarantee that all child components have also been mounted. If you want to wait until the entire view has been rendered, you can use vm.$nextTick inside of mounted:

1
2
3
4
5
6
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}

beforeUpdate

Called when data changes, before the DOM is patched. This is a good place to access the existing DOM before an update, e.g. to remove manually added event listeners.

updated

Called after a data change causes the virtual DOM to be re-rendered and patched.
The component’s DOM will have been updated when this hook is called, so you can perform DOM-dependent operations here. However, in most cases you should avoid changing state inside the hook. To react to state changes, it’s usually better to use a computed property or watcher instead.
Note that updated does not guarantee that all child components have also been re-rendered. If you want to wait until the entire view has been re-rendered, you can use vm.$nextTick inside of updated:

1
2
3
4
5
6
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}

beforeDestroy

Called right before a Vue instance is destroyed. At this stage the instance is still fully functional.

destroyed

Called after a Vue instance has been destroyed. When this hook is called, all directives of the Vue instance have been unbound, all event listeners have been removed, and all child Vue instances have also been destroyed.

Vue Router

mode

  • hash
  • history
  • Declarative
    <router-link :to="...">

  • Programmatic
    router.push(...)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // literal string path
    router.push('home')

    // object
    router.push({ path: 'home' })

    // named route
    router.push({ name: 'user', params: { userId: '123' } })

    // with query, resulting in /register?plan=private
    router.push({ path: 'register', query: { plan: 'private' } })

Vuex

At the center of every Vuex application is the store. A “store” is basically a container that holds your application state. There are two things that make a Vuex store different from a plain global object:

  • Vuex stores are reactive. When Vue components retrieve state from it, they will reactively and efficiently update if the store’s state changes.
  • You cannot directly mutate the store’s state. The only way to change a store’s state is by explicitly committing mutations. This ensures every state change leaves a track-able record, and enables tooling that helps us better understand our applications.

State

Vuex uses a single state tree. This also means usually you will have only one store for each application.

Vuex provides a mechanism to “inject” the store into all child components from the root component with the store option.

1
2
3
4
5
6
7
8
9
10
11
12
const app = new Vue({
el: '#app',
// provide the store using the "store" option.
// this will inject the store instance to all child components.
store,
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})

By providing the store option to the root instance, the store will be injected into all child components of the root and will be available on them as this.$store.

1
2
3
4
5
6
7
8
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}

Getters

Vuex allows us to define “getters” in the store. You can think of them as computed properties for stores. Like computed properties, a getter’s result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.
Getters will receive the state as their 1st argument:

1
2
3
4
5
6
7
8
9
10
11
12
13
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
1
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]

Getters will also receive other getters as the 2nd argument:

1
2
3
4
5
6
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}

Used in any component:

1
2
3
4
5
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}

Mutations

The only way to actually change state in a Vuex store is by committing a mutation. Vuex mutations are very similar to events: each mutation has a string type and a handler. The handler function is where we perform actual state modifications, and it will receive the state as the first argument:

1
2
3
4
5
6
7
8
9
10
11
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// mutate state
state.count++
}
}
})

You cannot directly call a mutation handler. To invoke a mutation handler, you need to call store.commit with its type:

1
store.commit('increment')

Actions

Actions are similar to mutations, the differences being that:

  • Instead of mutating the state, actions commit mutations.
  • Actions can contain arbitrary asynchronous operations.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})

use ES2015 argument destructuring to simplify the code:

1
2
3
4
5
actions: {
increment ({ commit }) {
commit('increment')
}
}

Dispatching Actions
Actions are triggered with the store.dispatch method:

1
store.dispatch('increment')

Remember that mutations have to be synchronous. Actions don’t. We can perform asynchronous operations inside an action:

1
2
3
4
5
6
7
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}

Actions support the same payload format and object-style dispatch:

1
2
3
4
// dispatch with a payload
store.dispatch('incrementAsync', {
amount: 10
})
1
2
3
4
5
// dispatch with an object
store.dispatch({
type: 'incrementAsync',
amount: 10
})

Modules

Due to using a single state tree, all state of our application is contained inside one big object. However, as our application grows in scale, the store can get really bloated.

To help with that, Vuex allows us to divide our store into modules. Each module can contain its own state, mutations, actions, getters, and even nested modules.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}

const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}

const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})

store.state.a // -> `moduleA`'s state
store.state.b // -> `moduleB`'s state

Vue vs React

Similarities

  • utilize a virtual DOM
  • provide reactive and composable view components
  • maintain focus in the core library, with concerns such as routing and global state management handled by companion libraries

Differences

  • In Vue, a component’s dependencies are automatically tracked during its render, so the system knows precisely which components actually need to re-render when state changes.
  • Vue choose Templates
  • More easy to get started