1. Forwarding all props of a parent component to a child component

If you are a Vue.js developer, at some point you will surely be writing a component which is merely “wrapped” around another component. A so-called wrapper component will often be accepting all props that the component which it wraps also accepts. You would then want to “forward” those props to the wrapped component. Instead of doing this:

<template>
  <child-component :someprop1="someprop1"
                   :someprop2="someprop2"
                   :someprop3="someprop3"
                   :someprop4="someprop4"
                   ...
  />
</template>

You can simply forward all of the props of the wrapper component at once by doing this:

<template>
  <child-component v-bind="$props"/>
</template>

2. Ensuring two components accept the same props

This trick can be powerfully combined with Trick #1. Now that it’s known how to forward all props to a wrapped component, one might wonder how to make sure that the wrapper component accepts the same props as the wrapped component in the first place. In the wrapper component, one would most likely write something like this:

<template>
  <child-component v-bind="$props"/>
</template>

<script>
  import ChildComponent from '@/components/ChildComponent'
  
  export default {
    props:{
      someProp1: String,
      someProp2: String,
      someProp3: String,
      // and so on
    }
  }
</script>
test

This has some disadvantages. One of them is, if you rewrite ChildComponent and maybe add some new props, you would have to make changes in the wrapper component as well. Another disadvantage is code duplication and generally bad code aesthetics. Fortunately, there is a very simple solution to this problem:

<template>
  <child-component v-bind="$props"/>
</template>

<script>
  import ChildComponent from '@/components/ChildComponent'
  
  export default {
    props:{
      ...ChildComponent.options.props
    }
  }
</script>

3. Forwarding all event listeners of a parent component to a child component

You do not need to do this if the child component you want to pass the event listeners to is at the root of the parent component, as it gets all the listeners per default then. However, if that is not the case, like in the following example, you can do this:

<template>
  <div>
    ...
    <child-component v-on="$listeners"/>
    ...
  </div>
</template>

4. Beautiful slot syntax

Since Vue 2.6, there is a shorthand for slot names, just like there is for events e.g @click instead of v-on:click`` . If you have a component which has a slot calledrow, which has a slot-prop called item, you can now pass a piece of template to it and access theitem` prop this way:

<template>
  ...
  <my-table>
    <template #row="{ item }">
      /* some content here. You can freely use 'item' here */
    </template>
  </my-table>
  ...
</template>

5. Dynamic directive arguments

This might be the most impressive and powerful feature Vue 2.6 offers: to dynamically pass directive arguments to a component. Suppose that you have a <my-button> component. For some reason, sometimes you want to listen to a click event on it, but other times you want listen to dblclick . You could solve that using dynamic directives like this:

<template>
  ...
  <my-button @[someEvent]="handleSomeEvent()"/>
  ...
</template>

<script>
  ...
  data(){
    return{
      ...
      someEvent: someCondition ? "click" : "dblclick"
    }
  },
  
  methods:{
    handleSomeEvent(){
      // do something
    }
  }
  ...
</script>

Dynamically providing event listeners is just one of the many things you can do with this — you can apply the same pattern to dynamic HTML attributes, props and much more!

6. Dynamic image src

A frequent use case of this is when you need to display a locally stored image which path is stored in some variable or some object’s property. While there are multiple solutions to this, the one I prefer is using webpack’s require function. Suppose that in your Vue component’s data you have an object which looks like this:

data(){
  return{
    company: {
      name: "CashMoney Inc.",
      logo: "cashmoneylogo.png"
    }
  }
}

The path of the image you want to display is stored in the logo property of the company object. In this example, we’ll assume that all your images of your project are in src/assets , which is where it is recommended you place your images anyway. There is also a subfolder called logos, containing a bunch of logo images. So the full path of your image in this case would be: src/assets/logos/cashmoneylogo.png.

Therefore, in the <template> of your component, you would create an <img> tag and provide the src attribute dynamically:

<template>
  ...
  <img :src="require(`@/assets/logos/${company.logo}`)"/>
  ...
</template>

A few things to consider here:

  • The string path passed to the require function is a ES6 template string with backticks (). This way, you can put in a variable neatly using ${...} instead of concatenating using the + operator.

  • The [require](https://webpack.js.org/api/module-methods/) function will not work with a path that is purely dynamic**,** as webpack needs to know which files to bundle already at compile time. You need to provide a partially static path expression. Webpack will then bundle all files which potentially match that expression*. This is why the @/assets/logos part is hard-coded in our example. By the way, the @ essentially means “relative to the src folder”. You can use it no matter where the file you’re typing that is and I’d strongly recommend using it instead of declaring ugly paths in relative form such as ./../../../ . Another advantage: if you later decide to move your file somewhere else, the path using @will still remain valid.

  • Note: This could impact performance if there are a lot of files which match the path expression you provided. If that is the case, make sure your path expression is as narrowly defined as possible or look up possible optimizations offered by Webpack.

#vue-js #javascript #web-development

5+ Vue.js Tricks You Should Know
24.35 GEEK