Categories
React Tips

React Tips — HTML, State Arrays, and Images

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

How to Pass HTML Tags in Props

There are several ways to pass HTML tags as props.

One way is to pass JSX expressions as props.

For instance, we can write:

myProp={<div><Foo />Some String</div>}

We can also pass in an HTML string:

myProp="<div>This is some html</div>"

Then we can render it as HTML by writing:

<div dangerouslySetInnerHTML={{ __html: this.props.myProp }}></div>

We set the dangerouslySetInnerHTML prop to render HTML as-is.

It only works with simple HTML and not JSX expressions, components, or other things.

We can also pass in an array of JSX elements:

myProp={["foo", <span>Some other</span>, "bar"]}

We have both strings and HTML in our myProp array.

We can then render this array the way we want.

Also, we can pass in components as the children of another component.

For instance, we can write:

<Foo>
  <div>Some content</div>
  <div>Some content</div>
</Foo>

We have the Foo component that’s wrapped around 2 divs.

In Foo we can render the components inside by referencing this.props.children for class components.

And in function components, we get the children property from the props parameter, which is the first one.

We can also use a fragment:

<MyComponent myProp={<React.Fragment>This is an <b>HTML</b> string.</React.Fragment>} />

Then we can pass in multiple elements without rendering a wrapper.

Implement Authenticated Routes in React Router

We can implement authenticated routes with our own components.

For instance, we can write:

const PrivateRoute = ({ component: Component, authed, ...rest }) => {
  return (
    <Route
      {...rest}
      render={(props) => authed
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
    />
  )
}

We created our own PrivateRouter component that takes the component that we want to protect.

We renamed the component prop to Component to make it uppercase.

Then we render the component if authentication credentials are valid.

Otherwise, we return the Redirect component to redirect to an unprotected page.

Then we can use it by writing:

<PrivateRoute authed={this.state.authed} path='/profile' component={Profile} />

We pass in the component that we want into PrivateRouter to protect it.

React.cloneElement vs this.props.children

We need to use React.cloneElement if we need to do anything other than rendering the children components.

This is because this.prop.children is only a descriptor of the children.

For instance, if we have the following:

render() {
  return(
    <Parent>
      <Child>First</Child>
      <Child>Second</Child>
      <Child>Third</Child>
    </Parent>
  )
}

Then to add a prop to it, we need to write:

render() {
  return (
    <div>
      {React.Children.map(this.props.children, child => {
        return React.cloneElement(child, {
          onClick: this.props.onClick })
      })}
    </div>
  )
}

We’ve to call React.cloneElement to make a clone of each child to add an onClick handler to each child component.

Push into State Array

We can puts into a state array by concatenating the new entries to it.

This way, we don’t mutate the original array.

We don’t want to change the original since it’ll be overwritten on the next render.

For instance, we can write:

const arr = this.state.myArray.concat('new');
this.setState({ myArray: arr })

We can also use the spread operator:

this.setState({ myArray: [...this.state.myArray, 'new'] })
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] })

The first one adds a single entry as we have above.

The 2nd merged the 2nd array into the first one and return it.

If we need to set the new array value based on the current array’s value, we can call setState with a callback that returns a new array based on the previous one.

For instance, we can write:

this.setState(prevState => ({
  myArray: [...prevState.myArray, "new"]
}))

We return the state with a new array.

Load Local Images with React

We can load local images by importing the image as a module.

For instance, we can write:

import React from 'react';
import logo from './logo.png';

function Header() {
  return <img src={logo} alt="Logo" />;
}

We import the image as a module and we put it straight into the src prop.

We can also do the same with require :

<img src={require('./logo.png')} />

Conclusion

We can add images by importing them.

There are several ways to pass HTML as props.

React.cloneElement is required for adding props to children.

There are several ways to push new data to a state array.

Categories
Top Vue Packages

Top Vue Packages for Adding YouTube Videos, Autofill Box, and More

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at the best packages for adding drag and drop items, YouTube videos, an input box with autofill, and a custom scrollbar.

Vue Smooth DnD

Vue Smooth DnD is an easy to use Vue library for making drag and drop lists.

To use it, we run:

npm i vue-smooth-dnd

Then we can use it by writing:

<template>
  <div>
    <div>
      <Container>
        <Draggable v-for="item in items" :key="item.id">
          <div>{{item.data}}</div>
        </Draggable>
      </Container>
    </div>
  </div>
</template>

<script>
import { Container, Draggable } from "vue-smooth-dnd";
export default {
  name: "Simple",
  components: { Container, Draggable },
  data() {
    return {
      items: Array(50)
        .fill()
        .map((_, i) => ({ id: i, data: `Draggable ${i}` }))
    };
  }
};
</script>

We use the Container and Draggable components to make the draggable container and items.

Container is the container.

Draggable are the draggable items.

We can change the classes of the items, the animation duration, drop placeholder, and other options.

vue-simple-suggest

As its name suggests, vue-simple-suggest is a simple package for adding an input box with autofill suggestions,

To use it, we run:

npm i vue-simple-suggest

Then we use it by writing:

<template>
  <div>
    <vue-simple-suggest v-model="chosen" :list="simpleSuggestionList" :filter-by-query="true"></vue-simple-suggest>

<p>{{ chosen }}</p>
  </div>
</template>

<script>
import VueSimpleSuggest from "vue-simple-suggest";
import "vue-simple-suggest/dist/styles.css";

export default {
  components: {
    VueSimpleSuggest
  },
  data() {
    return {
      chosen: ""
    };
  },
  methods: {
    simpleSuggestionList() {
      return ["apple", "orange", "grape"];
    }
  }
};
</script>

We import the component and CSS to display the input box.

Then we specified the simpleSuggestionList to return the suggestions.

v-model binds the selected choice to the chosen state.

It also works with async data and others has many other options for changes.

We can return a promise in our suggestion function to use async data as our suggestion source:

<template>
  <div>
    <vue-simple-suggest v-model="chosen" :list="simpleSuggestionList" :filter-by-query="true"></vue-simple-suggest>
    <p>{{ chosen }}</p>
  </div>
</template>

<script>
import VueSimpleSuggest from "vue-simple-suggest";
import "vue-simple-suggest/dist/styles.css";

export default {
  components: {
    VueSimpleSuggest
  },
  data() {
    return {
      chosen: ""
    };
  },
  methods: {
    async simpleSuggestionList() {
      return Promise.resolve(["apple", "orange", "grape"]);
    }
  }
};
</script>

We return a promise instead of an array.

vue-youtube

vue-youtube is a Vue package that let us embed YouTube videos in our Vue app.

To use it, we run:

npm i vue-youtube

to install it.

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VueYoutube from "vue-youtube";

Vue.use(VueYoutube);
Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div>
    <youtube ref="youtube" :video-id="videoId" :player-vars="playerVars" @playing="playing"></youtube>
  </div>
</template>

<script>
export default {
  data() {
    return {
      videoId: "NnsHhqAdOiM",
      playerVars: {
        autoplay: 1
      }
    };
  },
  computed: {
    player() {
      return this.$refs.youtube.player;
    }
  },
  methods: {
    async playVideo() {
      await this.player.playVideo();
    }
  }
};
</script>

We have the youtube component to embed the videos.

All we have to do is to specify the ID of the video and set a few options to play videos.

Vue 2 Scrollbar

Vue 2 Scrollbar is a custom scrollbar component for Vue apps.

To use it, we run:

npm i vue2-scrollbar

to install it.

Then we write:

<template>
  <div>
    <vue-scrollbar ref="Scrollbar" classes="my-scrollbar">
      <div class="scroll-me">
        <div v-for="n in 100" :key="n">{{n}}</div>
      </div>
    </vue-scrollbar>
  </div>
</template>

<script>
import VueScrollbar from "vue2-scrollbar";
import "vue2-scrollbar/dist/style/vue2-scrollbar.css";

export default {
  components: { VueScrollbar }
};
</script>

<style>
.my-scrollbar {
  max-height: 300px;
}
</style>

We add the vue-scrollbar component with the styles.

Also, we set the height of the container to 300px max.

Then we should see the scrollbar from the package displayed.

Conclusion

Vue Smooth DnD is a drag and drop component for Vue apps.

vue-simple-suggest lets us add an input box with autofill suggestions.

vue-youtube is a YouTube component for Vue apps.

Vue 2 Scrollbar provides us with a custom scrollbar.

Categories
Top Vue Packages

Top Vue Packages for Adding File Uploaders, Draggable Dialog, Slides, and Lightbox

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at the best packages for adding a file uploader, draggable dialog, slides, and lightbox.

Vue-Transmit

Vue-Transmit is a handy file uploader widget for Vue apps.

To use it, we run:

npm i vue-transmit

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VueTransmit from "vue-transmit";
Vue.use(VueTransmit);

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <vue-transmit tag="section" v-bind="options" ref="uploader">
      <div>
        <button class="btn btn-primary" @click="triggerBrowse">Upload Files</button>
      </div>
      <template slot="files" slot-scope="props">
        <div v-for="(file, i) in props.files" :key="file.id" :class="{'mt-5': i === 0}">
          <div class="media">
            <img :src="file.dataUrl" class="img-fluid d-flex mr-3">
          </div>
        </div>
      </template>
    </vue-transmit>
  </div>
</template>

<script>
export default {
  data() {
    return {
      options: {
        acceptedFileTypes: ["image/*"],
        url: "./upload",
        clickable: false
      }
    };
  },
  methods: {
    triggerBrowse() {
      this.$refs.uploader.triggerBrowseFiles();
    }
  },
  filters: {
    json(value) {
      return JSON.stringify(value, null, 2);
    }
  }
};
</script>

We use the vue-transmit component to add an upload button with a preview.

To display the preview, we populate the files slot to display the preview by using the dataUrl property.

We set the options for the modal by passing in the options with v-bind .

We set the acceptedFileTypes to set the file types the uploader accepts.

url is the URL to upload the data to.

It takes many other customization options that we can use to change how it behaves.

Drag and drop are also supported.

vue-dialog-drag

vue-dialog-drag is a draggable dialog for Vue apps.

To use it, we run:

npm i vue-dialog-drag

Then we write:

<template>
  <div id="app">
    <dialog-drag id="dialog-1">
      <p>Test dialog</p>
    </dialog-drag>
    <drop-area [@drop](http://twitter.com/drop "Twitter profile for @drop")="drop">
      <p>Drop Here</p>
    </drop-area>
  </div>
</template>

<script>
import DialogDrag from "vue-dialog-drag";
import DropArea from "vue-dialog-drag/dist/drop-area";

export default {
  name: "app",
  components: {
    DialogDrag,
    DropArea
  },
  methods: {
    drop(id) {
      console.log(id);
    }
  }
};
</script>

<style src="vue-dialog-drag/dist/vue-dialog-drag.css"></style>
<style src="vue-dialog-drag/dist/drop-area.css"></style>
<style src="vue-dialog-drag/dist/dialog-styles.css"></style>

to use it.

We use the built it dialog-drag and drop-area components with the built-in styles.

Now we can drag the dialog to the drop zone.

Vueper Slides

Vueper Slides is a slides library for Vue apps.

To install it, we run:

npm i vueperslides

Then we can use it by writing:

<template>
  <div id="app">
    <vueper-slides>
      <vueper-slide v-for="n in 10" :key="n" :title="`title ${n}`" :content="`slide ${n}`"/>
    </vueper-slides>
  </div>
</template>

<script>
import { VueperSlides, VueperSlide } from "vueperslides";
import "vueperslides/dist/vueperslides.css";

export default {
  components: { VueperSlides, VueperSlide }
};
</script>

We use the vueper-slides component to show the slides.

Also, we have to import the CSS to load the style of the slides.

vueper-slide renders the slides.

We pass in the title to display the title and content to display the content.

vue-easy-lightbox

vue-easy-lightbox is a simple lightbox component for Vue apps.

To use it, we run:

npm i vue-easy-lightbox

to install it.

Then we write:

<template>
  <div id="app">
    <div>
      <div v-for="(src, index) in imgs" :key="index" class="pic" @click="() => showImg(index)">
        <img :src="src">
      </div>
    </div>
    <vue-easy-lightbox :visible="visible" :imgs="imgs" :index="index" [@hide](http://twitter.com/hide "Twitter profile for @hide")="handleHide"></vue-easy-lightbox>
  </div>
</template>

<script>
export default {
  data() {
    return {
      visible: false,
      index: 0,
      imgs: [
        "https://placeimg.com/300/300/any",
        "https://placekitten.com/300/300"
      ]
    };
  },
  methods: {
    showImg(index) {
      this.index = index;
      this.visible = true;
    },
    handleHide() {
      this.visible = false;
    }
  }
};
</script>

to add the images and the lightbox.

vue-easy-lightbox has the lightbox component.

We click on the image and we’ll see the image.

To customize it, we can populate various slots to change the lightbox content.

The toolbar slot changes the toolbar.

next-btn slot changes the next button.

prev-btn slot changes the previous button.

close-btn slot changes the close button.

We can also listen to the events that are emitted by the lightbox.

Conclusion

Vue-Transmit is an easy to use uploader component.

vue-dialog-drag is a draggable dialog box.

Vueper Slides lets us add slides to our app.

vue-easy-lightbox is a handy lightbox component.

Categories
Top Vue Packages

Top Vue Packages for Adding Charts, Unique IDs, Sliders, and Scroll Lock

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at the best packages for adding charts, unique IDs, sliders, and scroll lock.

vue-unique-id

vue-unique-id lets us add a unique ID to our Vue component.

To use it, we run:

npm i vue-unique-id

to install it.

Then we write:

main.js

import Vue from "vue";
import App from "./App.vue";
import UniqueId from "vue-unique-id";
Vue.use(UniqueId);

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app"></div>
</template>

<script>
export default {
  created() {
    console.log(this.uid);
  }
};
</script>

We register the plugin and use the this.uid property to get the unique ID.

Also, we can get the ID with the $id method.

For instance, we can write:

<template>
  <div id="app"></div>
</template>

<script>
export default {
  created() {
    console.log(this.$id("foo"));
  }
};
</script>

to get an ID with the 'foo' suffix added to it.

VueVisible

VueVisible is a directive that lets us display something conditionally.

To use it, we run:

npm i vue-visible

to install it.

Then we use it by writing:

<template>
  <div id="app">
    <div v-visible="isVisible">I'm visible</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    };
  }
};
</script>

We just use the v-visible directive like the v-show directive to conditionally display something.

v-scroll-lock

v-scroll-lock lets us add a scroll lock to our Vue component to prevent scrolling.

To use it, we run:

npm i v-scroll-lock

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VScrollLock from "v-scroll-lock";

Vue.use(VScrollLock);

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

Modal.vue

<template>
  <div>
    <div class="modal" v-if="open">
      <button @click="closeModal">X</button>
      <div class="modal-content" v-scroll-lock="open">
        <p v-for="n in 100" :key="n">{{n}}</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Modal",
  data() {
    return {
      open: true
    };
  },
  methods: {
    openModal() {
      this.open = true;
    },
    closeModal() {
      this.open = false;
    }
  }
};
</script>

App.vue

<template>
  <div>
    <modal></modal>
  </div>
</template>

<script>
import Modal from "./components/Modal";
export default {
  components: { Modal }
};
</script>

We have the Modal component with the v-scroll-lock directive applied to the content.

Now we won’t be able to scroll even though we have lots of content that overflow the screen.

Vue Glide

Vue Glide is a slider component for Vue apps.

To use it, we run:

npm i vue-glide-js

to install it.

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import VueGlide from "vue-glide-js";
import "vue-glide-js/dist/vue-glide.css";

Vue.use(VueGlide);
Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <vue-glide>
      <vue-glide-slide v-for="i in 10" :key="i">Slide {{ i }}</vue-glide-slide>
    </vue-glide>
  </div>
</template>

<script>
import { Glide, GlideSlide } from "vue-glide-js";

export default {
  components: {
    [Glide.name]: Glide,
    [GlideSlide.name]: GlideSlide
  }
};
</script>

We use the vue-slide and vue-glide-slide component to display slides on the screen.

vue-chartist

vue-chartist is a chart library based of Chartist.js.

To use it, we run:

npm i vue-chartist chartist

to install it.

We use chartist for the CSS.

Then we write:

main.js

import Vue from "vue";
import App from "./App.vue";
Vue.use(require("vue-chartist"));

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <chartist ratio="ct-major-second" type="Line" :data="chartData" :options="chartOptions"></chartist>
  </div>
</template>

<script>
import "chartist/dist/chartist.css";

export default {
  data() {
    return {
      chartData: {
        labels: ["A", "B", "C"],
        series: [[1, 3, 2], [4, 6, 5]]
      },
      chartOptions: {
        lineSmooth: false
      }
    };
  }
};
</script>

to use it.

We use the chartist component to create the graphs.

type is the kind of graph we want to create.

data has the labels and series data.

labels is for the x-axis, and series is for the y-axis.

chartOptions has the options. We set lineSmooth to false to disable line smoothing.

Conclusion

vue-unique-id creates a unique ID for our Vue components.

VueVisible is a directive that works like v-show.

v-scroll-lock disables scrolling in our elements.

Vue Glide lets us create a slider.

vue-chartist lets us create graphs with little effort.

Categories
Top Vue Packages

Top Vue Packages for Adding Input Masks, Modals, Date Manipulation, and More

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at the best packages for adding input masks, modals, manipulating dates, and autocomplete dropdowns.

Vue IMask Plugin

Vue IMask Plugin is a Vue plugin that adds an input mask into our app.

We install it by running:

npm i vue-imask

Then we write:

<template>
  <imask-input
    v-model="numberModel"
    :mask="Number"
    radix="."
    @accept="onAccept"
    placeholder="Enter number"
  />
</template>

<script>
import { IMaskComponent } from "vue-imask";

export default {
  data() {
    return {
      numberModel: "",
      onAccept(value) {
        console.log(value);
      }
    };
  },
  components: {
    "imask-input": IMaskComponent
  }
};
</script>

to add the input with the mask.

It emits the accept event when the input is valid.

mask sets the format.

In our example, it’s a number.

v-model binds the value to a model state.

placeholder is the placeholder.

radix is the decimal separator.

@trevoreyre/autocomplete-vue is an easy to use autosggest component for Vue apps.

To use it, we run:

npm i @trevoreyre/autocomplete-vue

to install it.

Then we write:

main.js

import Vue from "vue";
import App from "./App.vue";
import Autocomplete from "@trevoreyre/autocomplete-vue";
import "@trevoreyre/autocomplete-vue/dist/style.css";

Vue.use(Autocomplete);
Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <autocomplete :search="search"></autocomplete>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fruits: ["apple", "orange", "grape", "banana"]
    };
  },
  methods: {
    search(input) {
      if (input.length < 1) {
        return [];
      }
      return this.fruits.filter(f => {
        return f.toLowerCase().startsWith(input.toLowerCase());
      });
    }
  }
};
</script>

to use it.

We register the plugin and import the CSS.

Then we add the autocomplete component to add the autocomplete input.

The search prop takes a function that lets us search for an item from an input value.

We pass the search method as the value.

input has the inputted value.

It returns an array of items that match.

The function can also return a promise.

We can also denounce the callback, change the base class, and set the default value.

vue-date-fns

vue-date-fns is a Vue wrapper for the vue-date-fns library.

To use it, we first install it by running:

npm i vue-date-fns

Then we can use it by writing:

<template>
  <div id="app">
    <div>{{ new Date() | date }}</div>
  </div>
</template>

<script>
import { dateFilter } from "vue-date-fns";

export default {
  filters: {
    date: dateFilter
  }
};
</script>

We register the filter and use it.

date formats the date into a date string.

We can also use the $date method to manipulate dates.

It also comes with locale data so we can switch to different locales.

We can also change the date format:

<template>
  <div id="app">
    <div>{{ new Date() | date('dd MMMM yyyy') }}</div>
  </div>
</template>

<script>
import { dateFilter } from "vue-date-fns";

export default {
  filters: {
    date: dateFilter
  }
};
</script>

We just pass in an argument into the filter function.

Vue my dropdown component

Vue my dropdown component is an easy to use dropdown component.

To use it, we run:

npm i vue-my-dropdown

to install it.

Then we write:

<template>
  <div id="app">
    <dropdown :visible="visible">
      <span class="link" @click="visible = !visible">click here</span>
      <div slot="dropdown" class="dialog">hello</div>
    </dropdown>
  </div>
</template>

<script>
import dropdown from "vue-my-dropdown";

export default {
  components: { dropdown },
  data() {
    return {
      visible: false
    };
  }
};
</script>

to use it.

It doesn’t come with any styles so we’ve to add them ourselves.

We populate the content of the dropdown slot to populate the dropdown.

We can set the position, add animation, and more.

Vuedals

Vuedals is a modal component for Vue apps.

To use it, we run:

npm i vuedals

to install it.

Then we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import { default as Vuedals } from "vuedals";

Vue.use(Vuedals);
Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <button @click="showModal()">show modal</button>
    <vuedal></vuedal>
  </div>
</template>

<script>
import {
  default as Vuedals,
  Component as Vuedal,
  Bus as VuedalsBus
} from "vuedals";

export default {
  components: {
    Vuedal
  },
  methods: {
    showModal() {
      VuedalsBus.$emit("new", {
        name: "modal",
        component: {
          name: "modal",
          template: `
            <div>
              <p>modal</p>
            </div>
          `
        }
      });
    }
  }
};
</script>

to use it.

We call the Vuedals.$emit method to open the modal.

The content is populated by a component.

Conclusion

Vue IMask Plugin is a simple input mask component.

@trevoreyre/autocomplete-vue is an autocomplete component for Vue apps.

vue-date-fns is a wrapper for date-fns for Vue apps.

Vue my dropdown component is a dropdown that we can customize.

Vuedals is a simple modal.