A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/sudheerj/vuejs-interview-questions below:

sudheerj/vuejs-interview-questions: List of 300 VueJS Interview Questions And Answers

  • How do you disable hot reloading explicitly?

    You can use hotReload: false option to disable the Hot Reload explicitly.

    It can be configured as below,

    module: {
      rules: [
        {
          test: /\.vue$/,
          loader: 'vue-loader',
          options: {
            hotReload: false // disables Hot Reload
          }
        }
      ]
    }

    ⬆ Back to Top

  • How do you use hot reloading?

    The vue loader plugin internally uses hot reloading. If you are scaffolding project with vue-cli, hot reloading comes out of the box but if you are manually setting up the project then hot reloading is enabled by default with webpack-dev-server --hot command.

    ⬆ Back to Top

  • What are state preservation rules in hot reloading?

    Below are the state preservation rules in hot reloading,

    1. When editing the <template> of a component, instances of the edited component will re-render in place, preserving all current private state.
    2. When editing the <script> part of a component, instances of the edited component will be destroyed and re-created in place.
    3. When editing the <style> hot reload operates on its own via vue-style-loader without affecting application state.

    ⬆ Back to Top

  • How to create functional components using vue loader?

    You can create functional components by adding functional attribute to template block,

    <template functional>
      <div>{{ props.msg }}</div>
    </template>

    ⬆ Back to Top

  • How do you access global properties of functional components?

    If you need to access properties defined globally on Vue.prototype then you can access them on parent,

    <template functional>
      <div>{{ parent.$someProperty }}</div>
    </template>

    ⬆ Back to Top

  • How do you perform testing in vuejs?

    You can perform testing in two ways,

    1. Using vue-cli: It offers pre-configured unit testing and e2e testing setups
    2. Manual setup: You can manually setting up unit tests for *.vue files using either mocha-webpack or jest

    ⬆ Back to Top

  • How do you apply linting for css?

    The stylelint linter supports linting style parts of Vue single file components. You can run linter on particular vue file as below,

    stylelint MyComponent.vue

    Other option is configuring stylelint-webpack-plugin in webpack. It can be configured as a dev dependency.

    // webpack.config.js
    const StyleLintPlugin = require('stylelint-webpack-plugin');
    module.exports = {
      // ... other options
      plugins: [
        new StyleLintPlugin({
          files: ['**/*.{vue,htm,html,css,sss,less,scss,sass}'],
        })
      ]
    }

    ⬆ Back to Top

  • How do you use eslint plugin?

    The official eslint-plugin-vue supports linting both the template and script parts of Vue single file components. You can configure plugin in your ESLint config,

    // .eslintrc.js
    module.exports = {
      extends: [
        "plugin:vue/essential"
      ]
    }

    You can run linter on particular component as below,

    eslint --ext js,vue MyComponent.vue

    ⬆ Back to Top

  • What is the purpose of eslint loader?

    You can use eslint-loader for *.vue files in order to automatically linted on save during development. It can be installed as npm module,

    npm install -D eslint eslint-loader

    After that you need to add it as pre-loader,

    // webpack.config.js
    module.exports = {
      // ... other options
      module: {
        rules: [
          {
            enforce: 'pre',
            test: /\.(js|vue)$/,
            loader: 'eslint-loader',
            exclude: /node_modules/
          }
        ]
      }
    }

    ⬆ Back to Top

  • CSS Extraction is used to extract all the processed CSS in all Vue components into a single CSS file. For webpack4, you need to install below npm command,

    npm install -D mini-css-extract-plugin

    You can configure this plugin in webpack as below,

    // webpack.config.js
    var MiniCssExtractPlugin = require('mini-css-extract-plugin')
    
    module.exports = {
      // other options...
      module: {
        rules: [
          // ... other rules omitted
          {
            test: /\.css$/,
            use: [
              process.env.NODE_ENV !== 'production'
                ? 'vue-style-loader'
                : MiniCssExtractPlugin.loader,
              'css-loader'
            ]
          }
        ]
      },
      plugins: [
        // ... Vue Loader plugin omitted
        new MiniCssExtractPlugin({
          filename: 'style.css'
        })
      ]
    }

    ⬆ Back to Top

  • You can define custom language blocks inside *.vue files based on the lang attribute of the block, the block's tag name, and the rules in your webpack config. You can also use resourceQuery to match a rule against a custom block with no lang.

    For example, to match against <message> custom blocks.

    {
      module: {
        rules: [
          {
            resourceQuery: /blockType=message/,
            loader: 'loader-to-use'
          }
        ]
      }
    }

    ⬆ Back to Top

  • What are the features of stylelint?

    Below are the list of major stylelint features

    1. It has more than 160 built-in rules to catch errors, apply limits and enforce stylistic conventions
    2. Understands latest CSS syntax including custom properties and level 4 selectors
    3. It extracts embedded styles from HTML, markdown and CSS-in-JS object & template literals
    4. Parses CSS-like syntaxes like SCSS, Sass, Less and SugarSS
    5. Supports Plugins for reusing community plugins and creating own plugins

    ⬆ Back to Top

  • What are the principles for vuex application structure?

    Vuex enforces below rules to structure any application.

    1. Application-level state is centralized in the store.
    2. The only way to mutate the state is by committing mutations, which are synchronous transactions.
    3. Asynchronous logic should be encapsulated in, and can be composed with actions.

    The project structure for any non-trivial application would be as below,

    ⬆ Back to Top

  • Does Vuex support hot reloading?

    Yes, vuex supports hot-reloading for mutations, modules, actions and getters during development. You need to use either webpack's hot module replacement API or browserify's hot module replacement plugin.

    ⬆ Back to Top

  • What is the purpose of hotUpdate API of vuex store?

    The store.hotUpdate() API method is used for mutations and modules.

    For example, you need to configure vuex store as below,

    // store.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    import mutations from './mutations'
    import myModule from './modules/myModule'
    
    Vue.use(Vuex)
    
    const state = { message: "Welcome to hot reloading" }
    
    const store = new Vuex.Store({
      state,
      mutations,
      modules: {
        moduleA: myModule
      }
    })
    
    if (module.hot) {
      // accept actions and mutations as hot modules
      module.hot.accept(['./mutations', './modules/newMyModule'], () => {
        // Get the updated modules
        const newMutations = require('./mutations').default
        const newMyModule = require('./modules/myModule').default
        //swap in the new modules and mutations
        store.hotUpdate({
          mutations: newMutations,
          modules: {
            moduleA: newMyModule
          }
        })
      })
    }

    ⬆ Back to Top

  • How do you test mutations?

    Since mutations are just functions that completely rely on their arguments it will be easier to test. You need to keep mutations inside your store.js file and should also export the mutations as a named export apart from default export.

    Let's take an example of increment mutations,

    // mutations.js
    export const mutations = {
      increment: state => state.counter++
    }

    And test them using mocha and chai as below,

    // mutations.spec.js
    import { expect } from 'chai'
    import { mutations } from './store'
    
    // destructure assign `mutations`
    const { increment } = mutations
    
    describe('mutations', () => {
      it('INCREMENT', () => {
        // mock state
        const state = { counter: 10 }
        // apply mutation
        increment(state)
        // assert result
        expect(state.counter).to.equal(11)
      })
    })

    ⬆ Back to Top

  • How do you test your getters?

    It is easier to test getters similar to mutations. It is recommended to test these getters if they have complicated computation.

    Let's take a simple todo filter as a getter

    // getters.js
    export const getters = {
      filterTodos (state, status) {
        return state.todos.filter(todo => {
          return todo.status === status
        })
      }
    }

    And the test case for above getter as follows,

    // getters.spec.js
    import { expect } from 'chai'
    import { getters } from './getters'
    
    describe('getters', () => {
      it('filteredTodos', () => {
        // mock state
        const state = {
          todos: [
            { id: 1, title: 'design', status: 'Completed' },
            { id: 2, title: 'testing', status: 'InProgress' },
            { id: 3, title: 'development', status: 'Completed' }
          ]
        }
        // mock getter
        const filterStatus = 'Completed'
    
        // get the result from the getter
        const result = getters.filterTodos(state, filterStatus)
    
        // assert the result
        expect(result).to.deep.equal([
          { id: 1, title: 'design', status: 'Completed' },
          { id: 2, title: 'development', status: 'Completed' }
        ])
      })
    })

    ⬆ Back to Top

  • What is the procedure to run tests in node?

    By proper mocking, you can bundle tests with webpack and run them on node without having depenceny on Browser API. It involves 2 steps,

    1. Create webpack config: Create webpack config with proper .babelrc

      // webpack.config.js
      module.exports = {
        entry: './test.js',
        output: {
          path: __dirname,
          filename: 'test-bundle.js'
        },
        module: {
          loaders: [
            {
              test: /\.js$/,
              loader: 'babel-loader',
              exclude: /node_modules/
            }
          ]
        }
      }
    2. Run testcases: First you need to bundle and then run them using mocha as below,

      webpack
      mocha test-bundle.js

      ⬆ Back to Top

  • What is the procedure to run tests in browser?

    Below are the steps to run tests in real browser,

    1. Install mocha-loader.
    2. Configure webpack config entry point to 'mocha-loader!babel-loader!./test.js'.
    3. Start webpack-dev-server using the config.
    4. Go to localhost:8080/webpack-dev-server/test-bundle to see the test result

    ⬆ Back to Top

  • What is the purpose of strict mode in vuex?

    In strict mode, whenever Vuex state is mutated outside of mutation handlers, an error will be thrown. It make sure that all state mutations can be explicitly tracked by debugging tools. You can just enable this by passing strict: true while creating the vuex store.

    const store = new Vuex.Store({
      // ...
      strict: true
    })

    ⬆ Back to Top

  • Can I use strict mode in production environment?

    No, it is not recommended to use strict mode in production environment. Strict mode runs a synchronous deep watcher on the state tree for detecting inappropriate mutations and it can be quite expensive when you perform large amount of mutations. i.e, It can impact performance if you enable in production mode. Hence, it should be handled through build tools,

    const store = new Vuex.Store({
      // ...
      strict: process.env.NODE_ENV !== 'production'
    })

    ⬆ Back to Top

  • The vuex plugin is an option hat exposes hooks for each mutation. It is a normal function that receives the store as the only argument. You can create your own plugin or use built-in plugins. The plugin skeleton would be as below,

    const myPlugin = store => {
      // called when the store is initialized
      store.subscribe((mutation, state) => {
        // called after every mutation.
        // The mutation comes in the format of `{ type, payload }`.
      })
    }

    After that plugin can be configured for plugins options as below,

    const store = new Vuex.Store({
      // ...
      plugins: [myPlugin]
    })

    ⬆ Back to Top

  • How do you mutate state in plugins?

    Similar to components you can't mutate state directly but they can trigger changes by by committing mutations. This way a plugin can be used to sync a data source to the store.

    For example, createWebSocketPlugin plugin is used to sync a websocket data source to the store.

    export default function createWebSocketPlugin (socket) {
      return store => {
        socket.on('data', data => {
          store.commit('receiveData', data)
        })
        store.subscribe(mutation => {
          if (mutation.type === 'UPDATE_DATA') {
            socket.emit('update', mutation.payload)
          }
        })
      }
    }

    And then configure plugin in vuex store as below

    const plugin = createWebSocketPlugin(socket)
    
    const store = new Vuex.Store({
      state,
      mutations,
      plugins: [plugin]
    })

    ⬆ Back to Top

  • A Vuex "store" is basically a container that holds your application state. The store creation is pretty straightforward.

    Below are the list of instructions to use vuex in an increment application,

    1. Configure vuex in vuejs ecosystem
      import Vuex from "vuex";
      Vue.use(Vuex)
    2. Provide an initial state object and some mutations
      // Make sure to call Vue.use(Vuex) first if using a module system
      
      const store = new Vuex.Store({
        state: {
          count: 0
        },
        mutations: {
          increment (state) {
            state.count++
          }
        }
      })
    3. Trigger state change with commit and access state variables,
      store.commit('increment')
      
      console.log(store.state.count) // -> 1

    ⬆ Back to Top

  • What are the differences of vuex store and plain global object?

    Below are the two major differences between vuex store and plain global object,

    1. Vuex stores are reactive: If the store's state changes then vue components will reactively and efficiently get updated
    2. Cannot directly mutate the store's state: The store's state is changed by explicitly committing mutations to ensure that every state change leaves a track-able record for tooling purpose

    ⬆ Back to Top

  • What is the reason not to update the state directly?

    We want to explicitly track application state in order to implement tools that can log every mutation, take state snapshots, or even perform time travel debugging. So we need to commit a mutation instead of changing store's state directly.

    ⬆ Back to Top

  • What is Single state tree?

    Vuex's single state tree is single object contains all your application level state and serves as the "single source of truth". It does not conflict with modularity when you split state and mutations into sub modules.

    ⬆ Back to Top

  • You can install vuex using npm or yarn as below,

    npm install vuex --save
    (or)
    yarn add vuex

    In a module system, you must explicitly install Vuex via Vue.use()

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)

    (OR)

    You can also install it using CDN links such as unpkg.cpm which provides NPM-based CDN links. Just include vuex after Vue and it will install itself automatically.

    <script src="https://unpkg.com/vue.js"></script>
    <script src="https://unpkg.com/vuex.js"></script>

    Note: You can use a specific version/tag via URLs like https://unpkg.com/vuex@2.0.0. If you don't mention any version then it will point to latest version.

    ⬆ Back to Top

  • Do I need promise for vuex?

    Yes, vuex requires Promise. If your supporting browsers do not implement Promise (e.g. IE), you can use a polyfill library, such as es6-promise using npm or yarn.

    npm install es6-promise --save # NPM
    yarn add es6-promise # Yarn

    After that import into anywhere in your application,

    import 'es6-promise/auto'

    ⬆ Back to Top

  • How do you display store state in vue components?

    Since Vuex stores are reactive, you can retrieve" state from store by simply returning store's state from within a computed property. i.e, Whenever store state changes, it will cause the computed property to re-evaluate, and trigger associated DOM updates.

    Let's take a hello word component which display store's state in the template,

    // let's create a hello world component
    const Greeting = {
      template: `<div>{{ greet }}</div>`,
      computed: {
        greet () {
          return store.state.msg
        }
      }
    }

    ⬆ Back to Top

  • How do you inject store into child components?

    Vuex provides a mechanism to "inject" the store into all child components from the root component with the store option. It will be enabled by vue.use(vuex).

    For example, let's inject into our app component as below,

    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: { Greeting },
      template: `
        <div class="app">
          <greeting></greeting>
        </div>
      `
    })

    Now the store will be injected into all child components of the root and will be available on them as **this.$store **

     // let's create a hello world component
         const Greeting = {
           template: `<div>{{ greet }}</div>`,
           computed: {
             greet () {
               return this.$store.state.msg
             }
           }
         }

    ⬆ Back to Top

  • In Vuex application, creating a computed property every time whenever we want to access the store's state property or getter is going to be repetitive and verbose, especially if a component needs more than one state property. In this case, we can make use of the mapState helper of vuex which generates computed getter functions for us.

    Let's take an increment example to demonstrate mapState helper,

    // in full builds helpers are exposed as Vuex.mapState
    import { mapState } from 'vuex'
    
    export default {
      // ...
      computed: mapState({
        // arrow functions can make the code very succinct!
        username: state => state.username,
    
        // passing the string value 'username' is same as `state => state.username`
        usernameAlias: 'username',
    
        // to access local state with `this`, a normal function must be used
         greeting (state) {
          return this.localTitle + state.username
        }
      })
    }

    We can also pass a string array to mapState when the name of a mapped computed property is the same as a state sub tree name

    computed: mapState([
      // map this.username to store.state.username
      'username'
    ])

    ⬆ Back to Top

  • How do you combine local computed properties with mapState helper?

    You can use object spread operator syntax in order to combine mapState helper(which returns an object) with other local computed properties. This way it simplify merging techniques using utilities.

    computed: {
      localComputed () { /* ... */ },
      // mix this into the outer object with the object spread operator
      ...mapState({
        // ...
      })
    }

    ⬆ Back to Top

  • Do you need to replace entire local state with vuex?

    No, if a piece of state strictly belongs to a single component, it could be just fine leaving it as local state. i.e, Even though vuex used in the application, it doesn't mean that you need to keep all the local state in vuex store. Other than that the code becomes more verbose and indirect although it makes your state mutations more explicit and debuggable.

    ⬆ Back to Top

  • Vuex getters acts as computed properties for stores to compute derived state based on store state. Similar to computed properties, a getter's result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.

    Let's take a todo example which as completedTodos getter to find all completed todos,

    const store = new Vuex.Store({
      state: {
        todos: [
          { id: 1, text: 'Vue course', completed: true },
          { id: 2, text: 'Vuex course', completed: false },
          { id: 2, text: 'Vue Router course', completed: true }
        ]
      },
      getters: {
        completedTodos: state => {
          return state.todos.filter(todo => todo.completed)
        }
      }
    })

    Note: Getters receive state as first argument.

    ⬆ Back to Top

  • What is a property style access?

    You can access values of store's getter object(store.getters) as properties. This is known as property style access.

    For example, you can access todo's status as a property,

    store.getters.todosStatus

    The getters can be passed as 2nd argument for other getters. For example, you can derive completed todo's count based on their status as below,

    getters: {
      completedTodosCount: (state, getters) => {
        return getters.todosStatus === 'completed'
      }
    }

    Note: The getters accessed as properties are cached as part of Vue's reactivity system.

    ⬆ Back to Top

  • What is a method style access?

    You can access store's state in a method style by passing arguments.

    For example, you can pass user id to find user profile information as below,

    getters: {
      getUserProfileById: (state) => (id) => {
        return state.users.find(user => user.id === id)
      }
    }

    After that you can access it as a method call,

    store.getters.getUserProfileById(111); {id: '111', name: 'John', age: 33}

    ⬆ Back to Top

  • What is mapGetter helper??

    The mapGetters is a helper that simply maps store getters to local computed properties.

    For example, the usage of getters for todo app would be as below,

    import { mapGetters } from 'vuex'
    
    export default {
      computed: {
        // mix the getters into computed with object spread operator
        ...mapGetters([
          'completedTodos',
          'todosCount',
          // ...
        ])
      }
    }

    ⬆ Back to Top

  • Vuex mutations are similar to any events with 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.

    For example, the counter example with increment mutation would be as below,

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          // mutate state
          state.count++
        }
      }
    })

    You can't directly invoke mutation instead you need to call store.commit with its type. The above mutation would be triggered as follows

    store.commit('increment')

    ⬆ Back to Top

  • How do you commit with payload?

    You can also pass payload for the mutation as an additional argument to store.commit.

    For example, the counter mutation with payload object would be as below,

    mutations: {
      increment (state, payload) {
        state.count += payload.increment
      }
    }

    And then you can trigger increment commit

    store.commit('increment', {
      increment: 20
    })

    Note: You can also pass primitives as payload.

    ⬆ Back to Top

  • What is object style commit?

    You can also commit a mutation is by directly using an object that has a type property.

    store.commit({
      type: 'increment',
      value: 20
    })

    Now the entire object will be passed as the payload to mutation handlers(i.e, without any changes to handler signature).

    mutations: {
      increment (state, payload) {
        state.count += payload.value
      }
    }

    ⬆ Back to Top

  • What are the caveats with vuex mutations?

    Since a Vuex store's state is made reactive by Vue, the same reactivity caveats of vue will apply to vuex mutations. These are the rules should be followed for vuex mutations,

    1. It is recommended to initialize store's initial state with all desired fields upfront
    2. Add new properties to state Object either by set method or object spread syntax
      Vue.set(stateObject, 'newProperty', 'John')

    (OR)

    state.stateObject = { ...state.stateObject, newProperty: 'John' }

    ⬆ Back to Top

  • Why mutations should be synchronous?

    You need to remember that mutation handler functions must be synchronous. This is why because any state mutation performed in the callback is essentially un-trackable. It is going to be problematic when the devtool will need to capture a "before" and "after" snapshots of the state during the mutations.

    mutations: {
      someMutation (state) {
        api.callAsyncMethod(() => {
          state.count++
        })
      }
    }

    ⬆ Back to Top

  • How do you perform mutations in components?

    You can commit mutations in components with either this.$store.commit('mutation name') or mapMutations helper to map component methods to store.commit calls.

    For example, the usage of mapMutations helper on counter example would be as below,

    import { mapMutations } from 'vuex'
    
    export default {
      methods: {
        ...mapMutations([
          'increment', // map `this.increment()` to `this.$store.commit('increment')`
    
          // `mapMutations` also supports payloads:
          'incrementBy' // map `this.incrementBy(amount)` to `this.$store.commit('incrementBy', amount)`
        ]),
        ...mapMutations({
          add: 'increment' // map `this.add()` to `this.$store.commit('increment')`
        })
      }
    }

    ⬆ Back to Top

  • Is it mandatory to use constants for mutation types?

    No, it is not mandatory. But you might observed that State management implementations such Flux and Redux use constants for mutation types. This convention is just a preference and useful to take advantage of tooling like linters, and putting all constants in a single file allows your collaborators to get an at-a-glance view of what mutations are possible in the entire application.

    For example, the mutations can be declared as below,

    // mutation-types.js
    export const SOME_MUTATION = 'SOME_MUTATION'

    And you can configure them in store as follows,

    // store.js
    import Vuex from 'vuex'
    import { SOME_MUTATION } from './mutation-types'
    
    const store = new Vuex.Store({
      state: { ... },
      mutations: {
        // ES2015 computed property name feature to use a constant as the function name
        [SOME_MUTATION] (state) {
          // mutate state
        }
      }
    })

    ⬆ Back to Top

  • How do you perform asynchronous operations?

    In Vuex, mutations are synchronous transactions. But if you want to handle asynchronous operations then you should use actions.

    ⬆ Back to Top

  • What are differences between mutations and actions?

    Actions are similar to mutations, but there are two main differences,

    1. Mutations perform mutations on the state, actions commit mutations.
    2. Actions can contain arbitrary asynchronous operations unlike mutations.

    ⬆ Back to Top

  • Give an example usage of actions?

    Vuex provides actions property similar mutations property in order to define action handlers. These action handlers receive context object as an argument which has same properties and methods of store instance.

    Let's see counter example to demonstrate increment action which commits respective mutation,

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('increment')
        }
      }
    })

    ⬆ Back to Top

  • How do you dispatch actions?

    Actions are simply triggered with the store.dispatch method as below,

    store.dispatch('increment')

    ⬆ Back to Top

  • Can you dispatch an action using payload or object style?

    Yes, actions support both payload and object style format similar to mutations.

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

    ⬆ Back to Top

  • Can I use Styled Components in VueJS?

    Styled components is a CSS-in-JS library used mainly for ReactJS applications. If you want to use it for VueJS applications, there is a VueJS styled components library port available, however, it is not a common practice.

    ⬆ Back to Top

  • How do you dispatch actions in components?

    You can dispatch actions in components with this.$store.dispatch('action name'), or use the mapActions helper which maps component methods to store.dispatch calls.

    For example, you can dispatch increment actions in counter component as below,

    import { mapActions } from 'vuex'
    
    export default {
      // ...
      methods: {
        ...mapActions([
          'increment', // map `this.increment()` to `this.$store.dispatch('increment')`
    
          // `mapActions` also supports payloads:
          'incrementBy' // map `this.incrementBy(amount)` to `this.$store.dispatch('incrementBy', amount)`
        ]),
        ...mapActions({
          add: 'increment' // map `this.add()` to `this.$store.dispatch('increment')`
        })
      }
    }

    ⬆ Back to Top

  • How do you compose actions?

    You can write multiple actions together to handle more complex async flows either by chaining promises or async/await. i.e, store.dispatch can handle Promise returned by the triggered action handler and it also returns Promise.

    Let's take two actions to see how they are combined and handled async flows,

    actions: {
      actionOne ({ commit }) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            commit('first mutation')
            resolve()
          }, 1000)
        })
      },
      actionTwo ({ dispatch, commit }) {
        return dispatch('actionA').then(() => {
          commit('second mutation')
        })
      }
    }

    As per the above example, When you try to dispatch actionTwo it dispatches actionOne first and then commits respective mutation. You can still simplify with async/await as below,

    actions: {
      async actionOne ({ commit }) {
        commit('first mutation', await getDataAsPromise())
      },
      async actionTwo ({ dispatch, commit }) {
        await dispatch('actionOne') // wait for `actionA` to finish
        commit('second mutation', await getSomeDataAsPromise())
      }
    }

    ⬆ Back to Top

  • What are modules in vuex?

    If you keep all state of our application in a single big state, the store can get really bloated. To solve this problem, Vuex allows us to divide our store into modules. Here, each module can contain its own state, mutations, actions, getters, and even nested modules.

    Let's take an example with multiple modules, configuring them in vuex and accessing different modules,

    const moduleOne = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleTwo = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        one: moduleOne,
        two: moduleTwo
      }
    })
    
    store.state.one // -> `moduleOne's state
    store.state.two // -> `moduleTwo's state

    ⬆ Back to Top

  • What is module local state?

    When you use modules the local state will be available to mutations, getters and actions in different ways.

    1. Both mutations and getters will receive module local state as first argument.
      const moduleOne = {
        state: { count: 0 },
        mutations: {
          increment (state) {
            state.count++; // Here state refers local module state
          }
        },
      
        getters: {
          average (state) {
            return state.count / 2
          }
        }
      }
    2. In actions, local state will be available as first argument.
      const moduleOne = {
        actions: {
          incrementConditional ({ state, commit, rootState }) {
            if (state.count < rootState.count) {
              commit('increment')
            }
          }
        }
      }

    ⬆ Back to Top

  • What is namespacing in vuex?

    ⬆ Back to Top

  • What is the default namespace behavior in vuex?

    By default, actions, mutations and getters inside modules are still registered under the global namespace. Because of that multiple modules react to the same mutation/action type.

    ⬆ Back to Top

  • When do you reuse modules?

    Sometime you may need to create multiple instances of a module.

    For example, it is needed in the below cases,

    1. If multiple stores that use the same module
    2. Register the same module multiple times in the same store.

    In those cases, you need to assign to a variable and export it for reusability,

    const MyReusableModule = {
      // state
      // mutations, actions, getters...
    }

    ⬆ Back to Top

  • What are the principles enforced by vuex?

    Vuex enforces below high-level principles,

    1. The Application-level state need to be centralized in the store
    2. The state should be mutated by committing mutations only(i.e, for synchronous transactions)
    3. The actions should be used for asynchronous transactions.

    ⬆ Back to Top

  • Can I perform mutations directly in strict mode?

    In strict mode, you can't mutate state directly using v-model attribute. If you use v-model it throws an error because mutation is not performed inside an explicit Vuex mutation handler.

    For example, the below input throws an error due to v-model usage

    <input v-model="stateObject.message">

    In this case, you need to bind the 's value. It can be resolved using value attribute as below,

    <input :value="username" @input="updateProfile">
    
    computed: {
      ...mapState({
        username: state => state.user.username
      })
    },
    methods: {
      updateProfile (e) {
        this.$store.commit('updateProfile', e.target.value)
      }
    },
    mutations: {
      updateProfile (state, username) {
        state.user.username = username
      }
    }

    ⬆ Back to Top

  • How to use model directive with two way computed property?

    You can still use model directive using two-way computed property with a setter.

     <input v-model="username">
     computed: {
      username: {
        get () {
          return this.$store.state.user.username
        },
        set (value) {
          this.$store.commit('updateProfile', value)
        }
      }
     }
     mutations: {
           updateProfile (state, username) {
             state.user.username = username
           }
     }

    ⬆ Back to Top

  • Vue CLI is a simple command line interface for scaffolding Vue.js projects. It will be helpful for rapid Vue.js development. You can install the npm package globally as below,

    npm install -g @vue/cli
    # OR
    yarn global add @vue/cli

    You can find the install version using vue --version command. Note: Vue CLI requires Node.js version 8.9 or above (8.11.0+ recommended).

    ⬆ Back to Top

  • What are the features provided by Vue CLI?

    VueCLI provides below major features,

    1. Interactive project scaffolding via @vue/cli
    2. A rich collection of official plugins integrating the best tools in the frontend ecosystem.
    3. A full graphical user interface to create and manage Vue.js projects.
    4. Zero config rapid prototyping via combination of @vue/cli and @vue/cli-service-global
    5. A runtime dependency (@vue/cli-service) built on top of webpack and extensible via plugins
  • What is instant prototyping?

    In Vue CLI, Instant prototyping is known as rapid prototyping with just a single *.vue file with the vue serve( similar to vue create) and vue build commands. But you need to install below global addon for this.

    npm install -g @vue/cli-service-global
    # or
    yarn global add @vue/cli-service-global

    You can also provide entry component for vue serve and target file for vue build using below commands

    vue serve MyComponent.vue
    vue build MyComponent.vue

    ⬆ Back to Top

  • How do you create project using vue CLI?

    You can create project using vue create command

    You can either choose the default preset or select "Manually select features" to pick the features you need.

    The default preset prompt would be as below,

    and the manual select features would be as below,

    ⬆ Back to Top

  • How do you create project using GUI?

    You can also create and manage projects using a graphical interface with the vue ui command. Once you apply this command, it opens a browser window with a GUI that guides you through the project creation process.

    ⬆ Back to Top

  • What are plugins in vue CLI?

    Vue CLI uses a plugin-based architecture where each plugin can modify the internal webpack configuration and inject commands to vue-cli-service. i.e, Each feature is implemented as a plugin. This architecture makes Vue CLI flexible and extensible.

    ⬆ Back to Top

  • How do you install plugins in an existing Vue CLI project?

    You can install a plugin into an already created project with the vue add command.

    vue add @vue/eslint
    (OR)
    vue add @vue/cli-plugin-eslint

    You can also add options for plugin

    vue add @vue/eslint --config airbnb --lintOn save

    If a plugin is already installed, you can skip the installation and only invoke its generator with the vue invoke command.

    ⬆ Back to Top

  • How to access local plugins in a project?

    If you need access to the plugin API in your project without creating a full plugin, you can use the vuePlugins.service option in your package.json file

    {
      "vuePlugins": {
        "service": ["my-service.js"]
      }
    }

    ⬆ Back to Top

  • How do you create UI plugins kind of behavior?

    You can also add files that will behave like UI plugins with the vuePlugins.ui option

    {
      "vuePlugins": {
        "ui": ["my-ui.js"]
      }
    }

    ⬆ Back to Top

  • A Vue CLI preset is a JSON object that contains pre-defined options and plugins for creating a new project without interactive prompts to select them. During project creation(using vue create), the presets will be saved in a ~/.vuerc which can modified at any time.

    For example, the generated JSON object(or preset) would be as below

    {
      "useConfigFiles": true,
      "router": true,
      "vuex": true,
      "cssPreprocessor": "sass",
      "plugins": {
        "@vue/cli-plugin-babel": {},
        "@vue/cli-plugin-eslint": {
          "config": "airbnb",
          "lintOn": ["save", "commit"]
        }
      }
    }

    ⬆ Back to Top

  • What is the versioning behavior in preset plugins?

    You can explicitly specify versions of the plugins being used.

    {
      "plugins": {
        "@vue/cli-plugin-eslint": {
          "version": "^3.0.0",
          // ... other options for this plugin
        }
      }
    }

    For official plugins, the CLI will automatically use the latest version available in the registry

    ⬆ Back to Top

  • How do you allow plugin prompts?

    Each plugin can inject its own prompts during the project creation process irrespective of preset declarations using prompts: true setting

    For example, user can pick their own ESLint config using the below configuration

    {
      "plugins": {
        "@vue/cli-plugin-eslint": {
          // let the users pick their own ESLint config
          "prompts": true
        }
      }
    }

    ⬆ Back to Top

  • You can share a preset with other developers by publishing it in a git repo. The repo can be published in either github, GitLab or BitBucket. The repo will contain below files,

    1. preset.json: The main file containing the preset data and it is required.
    2. generator.js: A generator that can inject or modify files in the project.
    3. prompts.js: A prompts file that can collect options for the generator. You can apply --preset option to use remote presets while creating the project
      # use preset from GitHub repo
      vue create --preset username/repo my-project

    ⬆ Back to Top

  • Yes, Vue CLI will load local presets if the value for the --preset option is a relative or absolute file path, or ends with .json. i.e, You can work with local presets directly. These local presets avoids repeatedly pushing the preset to a remote repo to test.

    // Directory contains preset.json file
    vue create --preset ./my-preset my-project
    (OR)
    vue create --preset my-preset.json my-project

    ⬆ Back to Top

  • What is the purpose of browserslist option?

    The browserslist option is available in package.json file in order to specify a range of browsers the project is supported. This value is going to be used by babel and autoprefixer to transpile javascript features and applying vendor prefixes.

    For example, you can declare it as follows,

    "browserslist": [
        "last 1 version",
        "> 1%",
        "IE 10"
      ]

    ⬆ Back to Top

  • How do you find VueJS version using API?

    The community plugins and components might need different strategies for different versions. In this case, you can use Vue.version which provides installed version of Vue as a string.

    For example, you can implement different logic based on different versions

    let version = Number(Vue.version.split('.')[0])
    
    if (version === 2) {
      // Vue v2.x.x
    } else if (version === 1) {
      // Vue v1.x.x
    } else {
      // Unsupported versions of Vue
    }

    ⬆ Back to Top

  • How do you create reactive objects?

    In version 3.0 you can create a reactive object with the reactive() API.

    const reactiveState = reactive({
    count: 0
     })

    In version 2.6, you can create reactive objects with Vue.observable() global API.

    const reactiveState = Vue.observable({
      count: 0
    })

    These observable objects can be used directly in computed properties and render functions.

    const Demo = {
      render(h) {
        return h('button', {
          on: { click: () => { reactiveState.count++ }}
        }, `count is: ${state.count}`)
      }
    }

    ⬆ Back to Top

  • What is the purpose new slot directive?

    In Vue 2.6 version, the new slot syntax is provided using v-slot directive which aligns syntax with Vue 3.0. This is going to be replacement for old slot syntax.

    The comparison for old and new slot syntax:

    <!-- old -->
    <user>
      <template slot="header" slot-scope="{ msg }">
        text slot: {{ msg }}
      </template>
    </user>
    
    <!-- new -->
    <user>
      <template v-slot:header="{ msg }">
        text slot: {{ msg }}
      </template>
    </user>

    ⬆ Back to Top

  • What is the use of compile method?

    VueJS provides compile method which is used to compile a template string into a render function. This method is only available in the full build.

    For example, you can compile template message:

    var result = Vue.compile('<div><span>{{ msg }}</span></div>')
    
    new Vue({
      data: {
        msg: 'Welcome to Vue world'
      },
      render: result.render,
      staticRenderFns: result.staticRenderFns
    })

    ⬆ Back to Top

  • What does nextTick do in VueJS?

    The nextTick method is just a comfortable way to execute a function after the data has been set, and the DOM has been updated. As an example, the usage is going to be similar to setTimeout:

    // modify data
    vm.msg = 'Welcome to Vue'
    // DOM not updated yet
    Vue.nextTick(function () {
      // DOM updated
    })
    
    // usage as a promise (2.1.0+)
    Vue.nextTick()
      .then(function () {
        // DOM updated
      })

    ⬆ Back to Top

  • What is async error handling?

    From 2.6 version onwards, Vue's built-in error handling mechanism can capture errors inside v-on handlers. Also,if any of your lifecycle hooks or event handlers performs asynchronous operations, you can now return a Promise from the function so that any uncaught errors from that Promise chain are also sent to your error handlers.

    Let's take an example of mounted lifecycle hook,

    export default {
      async mounted() {
        // if an async error is thrown here, it now will get
        // caught by errorCaptured and Vue.config.errorHandler
        this.todos = await api.getTodos()
      }
    }

    ⬆ Back to Top

  • What are Dynamic Directive Arguments?

    In Vue 2.6 release onwards, Directive arguments can now accept dynamic JavaScript expressions. i.e, the specific argument that we want to use is only known at runtime.

    Let's assign dynamic key and event directives for a div element,

    <div v-bind:[key]="value"></div>
    <div v-on:[event]="handler"></div>

    ⬆ Back to Top

  • What are the drawbacks of dynamic directive arguments?

    Apart from the benefits of dynamic directives arguments, it brings two drawbacks or considerations on the usage

    1. Constraints on expressions: When you perform complex JavaScript expressions, make sure that html attribute names cannot contain spaces and quotes. The below expression doesn't work as expected
    <div :[key + 'unique']="value"></div>

    Instead you may need to use string template syntax

    <div :[`${key}unique`]="value"></div>
    1. Custom Directives: The custom directive implementations need to have potential argument changes in addition to value changes.

    ⬆ Back to Top

  • What is the special handling for null values in dynamic directive arguments?

    Dynamic argument values are expected to be strings but it allows null as a special value that explicitly indicates that the binding should be removed. Other types will be treated as mistakes and will trigger a warning. So null value can be applied for v-bind and v-on.

    ⬆ Back to Top

  • Can I use dynamic directive null value for slots?

    No. It can be applied only for v-bind and v-on but not v-slot. This is because v-slot is not a binding and cannot be removed.

    ⬆ Back to Top

  • Vue I18n is an internationalization plugin of Vue.js. It easily integrates some localization features to your Vue.js Application.

    The simple usage with in html would be as below,

    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-i18n/dist/vue-i18n.js"></script>
    
    <div id="app">
      <p>{{ $t("user.message") }}</p>
    </div>

    and after that configure them in javascript

    // Ready translated locale messages
    const messages = {
      en: {
        user: {
          message: 'Good morning'
        }
      },
      de: {
        user: {
          message: 'Guten Morgen'
        }
      }
    }
    
    // Create VueI18n instance with options
    const i18n = new VueI18n({
      locale: 'de', // set locale
      messages, // set locale messages
    })
    
    
    // Create a Vue instance with `i18n` option
    new Vue({ i18n }).$mount('#app')

    The output is going to be like this,

    Guten Morgen

    ⬆ Back to Top

  • What are the types of formatting?

    Basically there are 4 types of formatting available in i18n plugin,

    1. Named formatting: First You need to define the message keys in curly braces({})
      const messages = {
        en: {
          message: {
            greeting: '{msg} Morning'
          }
        }
      }

    After that pass argument value along with key in the template

    <p>{{ $t('message.greeting', { msg: 'Good' }) }}</p>

    It outputs the result as below,

    1. List formatting: First you need to define zero index based keys in the messages,
      const messages = {
        en: {
          message: {
            greeting: '{0} Morning'
          }
        }
      }

    After that pass argument value with in an array

    <p>{{ $t('message.greeting', ['Good']) }}</p>

    Finally it outputs the result as below,

    Note: It also accepts array-like object

    <p>{{ $t('message.greeting', {'0': 'Good'}) }}</p>
    1. HTML formatting: This formatting is required when want to render your translation as an HTML message and not a static string.
      const messages = {
        en: {
          message: {
            greeting: 'Good <br> Morning'
          }
        }
      }

    After that use it in the html directive template as below

    <p v-html="$t('message.greeting')"></p>

    Finally it outputs the result as below

    <p>Good
    <!--<br> exists but is rendered as html and not a string-->
    Morning</p>
    1. Ruby on rails format: First you need to define with percentile and curly braces as below,
      const messages = {
        en: {
          message: {
            greeting: '%{msg} Morning'
          }
        }
      }

    After that pass argument with key similar to named formatting

    <p>{{ $t('message.greeting', { msg: 'Good' }) }}</p>

    Finally it renders the output as below,

    ⬆ Back to Top

  • What is custom formatting?

    You can use custom formatting for some of the formatting cases such as ICU formatting syntax (message "pattern" strings with variable-element placeholders enclosed in {curly braces}). It implement Formatter Interface.

    // Custom Formatter implementation
    class CustomFormatter {
         constructor (options) {
           // ...
         }
    interpolate (message, values) {
           // return the interpolated array
           return ['resolved message string']
         }
    }
    
    // register with `formatter` option
    const i18n = new VueI18n({
      locale: 'en-US',
      formatter: new CustomFormatter(/* here the constructor options */),
      messages: {
        'en-US': {
          // ...
        },
        // ...
      }
    })
    
    // Run!
    new Vue({ i18n }).$mount('#app')

    ⬆ Back to Top

  • How do you handle Pluralization?

    You can translate with pluralization by defining the locale that have a pipe | separator, and define plurals in pipe separator. Remember that template should use $tc() instead of $t().

    First you need to define the messages,

    const messages = {
      en: {
        user: 'user | users',
        friend: 'no friend | one friend | {count} friends'
      }
    }

    And the template can configure the messages with values

    <p>{{ $tc('user', 1) }}</p>
    <p>{{ $tc('user', 10) }}</p>
    
    <p>{{ $tc('friend', 0) }}</p>
    <p>{{ $tc('friend', 1) }}</p>
    <p>{{ $tc('friend', 10, { count: 10 }) }}</p>

    Finally it outputs the result as below

    <p>user</p>
    <p>users</p>
    
    <p>no friend</p>
    <p>one friend</p>
    <p>10 friends</p>

    ⬆ Back to Top

  • How to implement DateTime localization?

    You can localize the datetime with definition formats(e.g. short, long, etc).

    Lets follow below steps to localize date and time,

  • For example, you can add definition formats for English and Jappan locale as below

    const dateTimeFormats = {
      'en-US': {
        short: {
          year: 'numeric', month: 'short', day: 'numeric'
        },
        long: {
          year: 'numeric', month: 'short', day: 'numeric',
          weekday: 'short', hour: 'numeric', minute: 'numeric'
        }
      },
      'ja-JP': {
        short: {
          year: 'numeric', month: 'short', day: 'numeric'
        },
        long: {
          year: 'numeric', month: 'short', day: 'numeric',
          weekday: 'short', hour: 'numeric', minute: 'numeric', hour12: true
        }
      }
    }
  • After that You need to specify the dateTimeFormats option of VueI18n constructor

    const i18n = new VueI18n({
      dateTimeFormats
    })
    
    new Vue({
      i18n
    }).$mount('#app')
  • And then add them to the template

    <div id="app">
      <p>{{ $d(new Date(), 'short') }}</p>
      <p>{{ $d(new Date(), 'long', 'ja-JP') }}</p>
    </div>
  • Finally it outputs the result

    <div id="app">
      <p>May 20, 2019</p>
      <p>2019年5月20日</p>
    </div>
  • How do you implement Number localization?

    You can localize the number with definition formats(e.g. currency, etc)

    Lets follow below steps to localize numbers,

    1. You need to add definition formats. For example, lets add it for English and Japanese locales
       const numberFormats = {
        'en-US': {
          currency: {
            style: 'currency', currency: 'USD'
          }
        },
        'ja-JP': {
          currency: {
            style: 'currency', currency: 'JPY', currencyDisplay: 'symbol'
          }
        }
      }
    1. After that specify the numberFormats option of VueI18n constructor
      const i18n = new VueI18n({
        numberFormats
      })
      
      new Vue({
        i18n
      }).$mount('#app')
    2. Now let's configure them in template
      <div id="app">
        <p>{{ $n(10, 'currency') }}</p>
        <p>{{ $n(50, 'currency', 'ja-JP') }}</p>
      </div>
    3. Finally it outputs the result
      <div id="app">
        <p>$10.00</p>
        <p>¥50</p>
      </div>

    ⬆ Back to Top

  • How do you perform locale changing?

    All child components of a root instance are localized using the locale property of the VueI18n class. You can change the value of the locale property of the VueI18n instance as below.

    const i18n = new VueI18n({
      locale: 'de', // set locale
      ...
    })
    
    // create root Vue instance
    new Vue({
      i18n,
      ...
    }).$mount('#app')
    
    // change other locale
    i18n.locale = 'en'

    You can also use component's VueI18n instance referenced as the $i18n property which will be used to change the locale.

    <template>
      <div class="locale-changer">
        <select v-model="$i18n.locale">
          <option v-for="(lang, i) in langs" :key="`Lang${i}`" :value="lang">{{ lang }}</option>
        </select>
      </div>
    </template>
    
    <script>
    export default {
      name: 'locale-changer',
      data () {
        return { langs: ['de', 'en'] }
      }
    }
    </script>

    ⬆ Back to Top

  • What is Lazy loading translations?

    The loading of all translation files at once is unnecessary and it may impact the performance too. It will be easy for lazy loading or asynchronously loading the translation files when you use webpack. i.e, You can dynamically load or import language translations using webpack as below,

    //i18n-setup.js
    import Vue from 'vue'
    import VueI18n from 'vue-i18n'
    import messages from '@/lang/en'
    import axios from 'axios'
    
    Vue.use(VueI18n)
    
    export const i18n = new VueI18n({
      locale: 'en', // set locale
      fallbackLocale: 'en',
      messages // set locale messages
    })
    
    const loadedLanguages = ['en'] // our default language that is preloaded
    
    function setI18nLanguage (lang) {
      i18n.locale = lang
      axios.defaults.headers.common['Accept-Language'] = lang
      document.querySelector('html').setAttribute('lang', lang)
      return lang
    }
    
    export function loadLanguageAsync (lang) {
      if (i18n.locale !== lang) {
        if (!loadedLanguages.includes(lang)) {
          return import(/* webpackChunkName: "lang-[request]" */ `@/lang/${lang}`).then(msgs => {
            i18n.setLocaleMessage(lang, msgs.default)
            loadedLanguages.push(lang)
            return setI18nLanguage(lang)
          })
        }
        return Promise.resolve(setI18nLanguage(lang))
      }
      return Promise.resolve(lang)
    }

    After that loadLanguageAsync function can be used inside a vue-router beforeEach hook.

    router.beforeEach((to, from, next) => {
      const lang = to.params.lang
      loadLanguageAsync(lang).then(() => next())
    })

    ⬆ Back to Top

  • What is the main difference between method and computed property?

    The main difference between a computed property and a method is that computed properties are cached and invoke/change only when their dependencies change. Whereas a method will evaluate every time it's called.

    ⬆ Back to Top

  • Vuetify is a semantic component material framework for Vue. It aims to provide clean, semantic and reusable components that make building application easier. The installation and configuration is simple as below,

    import Vue from 'vue'
    import Vuetify from 'vuetify' // Import Vuetify to your project
    
    Vue.use(Vuetify) // Add Vuetify as a plugin

    ⬆ Back to Top

  • How do you watch for nested data changes?

    You can use deep watcher by setting deep: true in the options object. This option enables us to detect nested value changes inside Objects.

    vm.$watch('someObject', callback, {
      deep: true
    })
    vm.someObject.nestedValue = 123
    // callback is fired

    Note: This is not required to listen for Array mutations.

    ⬆ Back to Top

  • How to trigger watchers on initialization?

    You can use immediate: true option in order to trigger watchers when the vue instance (or component) is being created. i.e This option will trigger the callback immediately with the current value of the expression.

    watch: {
      test: {
        immediate: true,
        handler(newVal, oldVal) {
          console.log(newVal, oldVal)
        },
      },
    },

    ⬆ Back to Top

  • What is the purpose of comments option?

    When comments option enabled, it will preserve and render HTML comments found in templates. By default, it's value is false. Let's see the action in an example,

    <template>
      <div class="greeting">
        <!--greeting-->
        <h1>{{ msg }}</h1>
      </div>
    </template>
    
    <script>
    export default {
      comments: true,
      data () {
        return {
          msg: 'Good morning'
        }
      }
    }
    </script>

    Note: This option is only available in the full build, with in-browser compilation. i.e, It won't work with Single File Components(SFC).

    ⬆ Back to Top

  • How to identify whether code is running on client or server?

    You can use vm.$isServer method to know whether the current Vue instance is running on the server or client.

    The usage would be as below,

    const Vue = require('vue');
    Vue.prototype.$isServer
    (OR)
    this.$isServer // With in component

    ⬆ Back to Top

  • How do you watch route object changes?

    You can setup a watcher on the $route in your component. It observes for route changes and when changed ,sets the message property.

    watch:{
        $route (to, from){
            this.message = 'Welcome';
        }
    }

    ⬆ Back to Top

  • How do you sync current route in vuex store?

    You can use vue-router-sync library to sync current $route object in vuex store's state.

    The usage is quite straight forward with two steps

    1. Installation:
      npm install vuex-router-sync
    2. Sync router and store:
      import { sync } from 'vuex-router-sync'
      import store from './vuex/store' // vuex store instance
      import router from './router' // vue-router instance
      
      const unsync = sync(store, router) // Returns an unsync callback function
      unsync() // Unsyncs store from router

    ⬆ Back to Top

  • What are navigation guards in vue router?

    The navigation guards of vue-router are used to protect navigations either by redirecting it or canceling it.

    Below are the 3 different ways to hook into router navigations

    1. Global:
    2. Per-route:
    3. In-component:

    ⬆ Back to Top

  • Can I use computed property in another computed property?

    Yes, you can access it directly as you would data props.

    For example, the comboTwo computed property uses comboOne computed property as below,

    data() {
        return {
            propOne: 'prop1',
            propTwo: 'prop2'
        }
    },
    
    computed: {
         comboOne() {
             return this.propOne + ',' + this.propTwo;
         },
    
         comboTwo() {
            return this.comboOne.split(',').join('-');
        }
    }

    ⬆ Back to Top

  • How can I use imported constant in template section?

    The variables need to be exposed on your data in order to use them in template section. i.e, You can't use them directly on template.

    <span>
       CREATE: {{CREATE_PROP}}
       UPDATE: {{UPDATE_PROP}}
       DELETE: {{DELETE_PROP}}
    </span>
    <script>
    import {CREATE_DATA, UPDATE_DATA, DELETE_DATA} from 'constants';
    new Vue({
        ...
        data:{
            CREATE_PROP: CREATE_DATA,
            UPDATE_PROP: UPDATE_DATA,
            DELETE_PROP: DELETE_DATA
        }
        ...
    })
    </script>

    ⬆ Back to Top

  • Is recommended to use async for computed properties?

    No, it is not recommended. Computed properties should be synchronous. But if you still use asynchronous actions inside them, they may not work as expected and can lead to an unexpected behaviour.

    For example, the below usage of async/await is not recommended,

     async someComputedProperty () {
          return await someFunction()
        },

    Note: If you still prefer to use async computed properties for some reason then you can consider using additional plugin such as vue-async-computed.

    ⬆ Back to Top

  • What happens if you use duplicate field names?

    ⬆ Back to Top

  • Why the component data must be a function?

    The component data must be a function instead directly providing the object. This is because each instance needs to maintain an independent copy of the returned data object. Otherwise one component instance data changes will impact the data of all other instances.

    For example, the below code snippets gives an idea on correct approach,

        data: { // Bad
          message: 'Hello'
        }
        data: function () { //Good
          return {
            message: 'Hello'
          }
        }

    ⬆ Back to Top

  • What is the reason for recommendation for multi-word component names?

    Component names should always be multi-word, except for root level or built-in vue components(such as <transition> or <component> etc). This recommendation is to prevent conflicts with existing and future HTML elements, since all HTML elements are a single word.

    Vue.component('user', { //bad approach
      // ...
    })
    Vue.component('user-profile', { //good approach
           // ...
         })

    ⬆ Back to Top

  • What is the best way to re-render a component?

    The best way to force Vue to re-render a component is to set a :key on the component. i.e, Whenever the component to be re-rendered, just change the value of the key then Vue will re-render the component. ⬆ Back to Top

  • How does reactivity works with ref?

    VueJS automatically detects the changes to ref's value and updates the DOM with a dependency-tracking based reactivity system.

    1. When a component is rendered for the first time, it tracks every ref that was used during the render.
    2. Whenever a ref is mutated, it will trigger a re-render of the component.
  • How to use composition API in Vue2.0?

    Vue 2.0 does not have native support for the Composition API, but you can use it via the official plugin: @vue/composition-api.

    Let's see the usage in step-by-step instructions,

    1. Install the Plugin

      npm install @vue/composition-api
      # or
      yarn add @vue/composition-api
    2. Register the plugin in your main.js file,

        import Vue from 'vue';
        import VueCompositionAPI from '@vue/composition-api';
      
        Vue.use(VueCompositionAPI);
      
        new Vue({
          render: h => h(App),
        }).$mount('#app');
    3. Using Composition API in Components You can now use ref, reactive, computed, watch, onMounted, etc., in your Vue 2 components.

      Example: Counter Component
      <template>
        <div>
          <p>Count: {{ count }}</p>
          <button @click="increment">Increment</button>
        </div>
      </template>
      
      <script>
      import { ref } from '@vue/composition-api';
      
      export default {
        setup() {
          const count = ref(0);
      
          const increment = () => {
            count.value++;
          };
      
          return {
            count,
            increment,
          };
        },
      };
      </script>

      Note:

      • The @vue/composition-api plugin is compatible with Vue 2.6+.
      • It does not include all Vue 3 features (e.g., <script setup>, Suspense, Fragments).
      • Great for gradual migration or using modern Vue patterns in Vue 2.

    ⬆ Back to Top

  • The Composition API in Vue 3 is a new way to organize and reuse logic in Vue components. It was introduced to address some limitations of the Options API (used in Vue 2), especially when dealing with large or complex components where logic can become scattered and hard to manage.

    The Composition API is a set of APIs (e.g., setup(), ref, reactive, computed, watch, etc.) that allow developers to compose component logic more flexibly and cleanly, especially when logic is reused across components.

    1. The **setup()** function

      The heart of the Composition API. It's called before the component is created, and it's the place where you declare reactive state, computed properties, methods, and lifecycle hooks.

         <template>
           <button @click="increment">Count is: {{ count }}</button>
         </template>
         <script setup>
         import { ref } from 'vue'
      
         const count = ref(0)
         function increment() {
           count.value++
         }
         </script>
      • ref() creates a reactive reference to a primitive value.
      • count.value is how you access/update the value inside a ref.
    2. Reactive State: **ref()** and **reactive()**

      • Used for primitive values.
        • Wraps a value in a reactive object.

          const message = ref('Hello');
          message.value = 'Hi';
          • Used for objects.
          • Deeply reactive, making every property reactive.
          const user = reactive({  name: 'Alice',  age: 25 });
          user.age++;
    3. Computed Properties Creates values that automatically update when dependencies change.

      import { ref, computed } from 'vue';
      
      setup() {
        const firstName = ref('John');
        const lastName = ref('Doe');
        const fullName = computed(() => `${firstName.value} ${lastName.value}`);
      
        return { fullName };
      }
    4. Watchers

      Both watch() and watchEffect() are used to run side effects when data changes:

        watch(count, (newVal, oldVal) => {
        console.log('Count changed:', newVal);
        });
      
        watchEffect(() => {
        console.log('Count is now', count.value);
        });
    5. Lifecycle Hooks

      Composition API uses new lifecycle hooks imported from Vue.

       import { onMounted, onUnmounted } from 'vue';
      
       onMounted(() => { 
           console.log('Component is mounted'); 
       });
      
       onUnmounted(() => {
           console.log('Component is unmounted');
       });
    6. Reusable Logic with Composables

      You can encapsulate logic in composable functions and reuse across components:

      Example: Reuse logic of counter using useCounter.js

        import { ref } from 'vue';
        export function useCounter(initialValue = 0) { 
          const count = ref(initialValue);
          const increment = () => count.value++;
          const decrement = () => count.value--;
          const reset = () => count.value = initialValue;
          return { count, increment, decrement, reset }; 
        }

      Using it in a component

      <script setup>
       import { useCounter } from '@/composables/useCounter';
      
        const { count, increment, decrement, reset } = useCounter(5);
        </script>
      
        <template>
          <div>
            <p>Count: {{ count }}</p>
            <button @click="increment">+</button>
            <button @click="decrement">-</button>
            <button @click="reset">Reset</button>
          </div>
        </template>

    ⬆ Back to Top

  • What are the benefits of composition API?

    The composition API provides several benefits over the traditional Options API as listed below.

    1. Better logic reuse and code organization:
    2. Better typescript support:
    3. Easier testing
    4. Smaller production bundles

    ⬆ Back to Top

  • What are composition functions?

    Composition API is a set of additive, function-based APIs that allow flexible composition of component logic.

    ⬆ Back to Top

  • The <Teleport> component allows you to render a part of your component's template into a different location in the DOM — outside the current component's hierarchy.

    1. Wrap teleport component around the modal template inside app.vue file
    <template>
    <div>
      <h1>Page Content</h1>
    
      <!-- This modal will render in the #modals element -->
      <teleport to="#modals">
        <div class="modal">
          <p>This is a modal rendered with teleport</p>
        </div>
      </teleport>
    </div>
    </template>
    1. Render modal component inside main index.html file
    <body>
     <div id="app"></div>
     <div id="modals"></div> <!-- This is where the modal will appear -->
    </body>

    In Vue 2, this functionality was possible via the community plugin portal-vue

    1. Modals
    2. Toasts
    3. Tooltips
    4. Context menus
    5. Dropdowns
    6. Anything that needs to break out of DOM nesting

    ⬆ Back to Top

  • What is the purpose of html directive?

    The v-html directive is used to update the inner html of a DOM element with latest data. It is similar to innerHTML property in DOM.

    The example usage of this directive as shown below,

    <div id="app">
       <div>{{ htmlContent }}</div>
       <div v-html="htmlContent"></div>
    </div>

    Note: This directive should be used with trused content only but not on user provided content. Otherwise it can leads to XSS vulnerabilities.

    ⬆ Back to Top

  • What are the key differences between Vue 2 and Vue 3? Feature Vue 2 Vue 3 API Style Options API Composition API + Options API Reactivity System Object.defineProperty() Proxy-based (faster & more reliable) Performance Moderate Improved (~2x faster in some cases) Tree-shaking Limited Fully tree-shakable TypeScript Support Partial Built-in and first-class support Fragment Support Not supported Supported Teleport/Portals Plugin-based Native support Suspense Not available Native support for async components

    ⬆ Back to Top

  • What is watch() and how is it used?

    The watch() function observes a reactive source((like ref, reactive, getter functions or computed values)) and runs a callback function whenever that source changes.

    Syntax:

     watch(source, callback, options ?) 
    Example 1: Watching a ref
    import {ref, watch} from 'vue';
    
    const count = ref(0);
    
    watch(count, (newVal, oldVal) => {
       console.log(`Count changed from ${oldVal} to ${newVal}`);
    });
    count.value = 5; // triggers the watch callback
    Example 2: Watching a function (getter)
    const firstName = ref('Sudheer');
    const lastName = ref('Jonna');
    
    watch(
       () => `${firstName.value} ${lastName.value}`,
       (newFullName, oldFullName) => {
           console.log(`Full name changed from ${oldFullName} to ${newFullName}`);
       }
    );
    Example 3: Watching a reactive object deeply
        import {reactive, watch} from 'vue';
       
        const user = reactive({name: 'Sudheer', age: 38});
       
        watch(
           () => user,
           (newUser, oldUser) => {
               console.log('User object changed:', newUser);
           },
           {deep: true}
        );

    The main uses of watch() are:

    1. Watching route changes
    2. Triggering API calls
    3. Responding to complex data changes
    4. Manually reacting to specific state updates

    ⬆ Back to Top

  • What is watch() and how is it used?

    In Composition API, lifecycle hooks are functions you call inside the setup() function to hook into different stages of a component's lifecycle. These hooks replace the traditional options API lifecycle methods (like created(), mounted(), etc.) with function-based hooks that are imported from Vue.

    Lifecycle Stage Composition API Hook Description Before component creation onBeforeMount() Called right before the component is mounted Component mounted onMounted() Called after the component has been mounted Before update onBeforeUpdate() Called before the component updates the DOM After update onUpdated() Called after the component updates the DOM Before unmount onBeforeUnmount() Called right before the component is unmounted Component unmounted onUnmounted() Called after the component is unmounted Error captured onErrorCaptured() Called when an error from a child component is captured Activated (keep-alive) onActivated() Called when a kept-alive component is activated Deactivated (keep-alive) onDeactivated() Called when a kept-alive component is deactivated

    The above hooks can be imported from vue and used inside setup() function. For example, the usage of hooks will be as follows,

    import {onMounted, onBeforeUnmount} from 'vue'
    
     export default {
     setup() {
         onMounted(() => {
             console.log('Component is mounted!')
         })
    
         onBeforeUnmount(() => {
             console.log('Component is about to unmount')
         })
     }
     }

    ⬆ Back to Top

  • Whats the difference between watch() and watchEffect()?

    Both watch and watchEffect are Composition API functions used for reactivity, but they serve different purposes and behave differently.

    watch: It is used to watch specific reactive sources (like ref or computed) and respond to changes. This function is lazy. i.e, The callback is not called immediately but only on changes. It is useful when you need to access both old and new values, and performs side-effects conditionally.

       watch(count, (newVal, oldVal) => {
          console.log('Count changed:', newVal);
       });

    watchEffect: This function is automatic and eager. It runs a function immediately and tracks its dependencies automatically. It cannot access old values directly.

    watchEffect(() => {
      console.log(`Count is ${count.value}`);
    });

    ⬆ Back to Top


  • RetroSearch is an open source project built by @garambo | Open a GitHub Issue

    Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

    HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4