Universal Navigation Search Component for Vue Router

Just starting out with Vue and frontend development.

I'm attempting to create a universal navigation bar in Vue Router using bootstrap vue, complete with a search bar feature.

However, because I have placed my navigation bar in App.vue, I am encountering difficulties passing the search function to specific routes.

Here is a snippet of what I currently have in my App.vue file:

<div id="app">
    <b-navbar toggleable="lg" variant="light" type="light" class="justify-content-between">
      <b-navbar-brand><router-link to="/">Brand</router-link></b-navbar-brand>
      <b-collapse class="nav-collapse" is-nav>
        <b-nav-item><router-link to="/about">Route 1</router-link></b-nav-item>
      </b-collapse>

      <b-navbar-nav class="ml-auto">
        <b-nav-form>
          <b-form-input class="form-control mr-sm-2" v-model="search_term" placeholder="Search..."></b-form-input>
          <b-button variant="outline-success my-2 my-sm-2" type="submit" v-on:click="getSearch(search_term)">Search</b-button>
        </b-nav-form>
      </b-navbar-nav>
    </b-navbar>

    <router-view/>

  </div>

The router functions are within their own class.

The search functionality under b-nav-form was originally implemented on a specific page where the functions exist. Placing it within individual pages would require re-rendering each time the user navigates. Therefore, I opted to include it in the App.vue page for permanent rendering.

Is there a way to pass the search term to its respective function on its designated page while keeping the navbar universal? Is this feasible, or would it be simpler to keep the navbar on its own page?

Answer №1

If you're looking for the best way to share a navigation bar across your entire app and access its data from any route component, consider keeping it at the App.vue level just as you had initially thought. The key challenge then becomes accessing the search functionality in the route components, but this can be easily done using a Vuex store.

The Vuex store serves as a centralized source of truth for your application. Any component, no matter how deeply nested within your app's structure, can retrieve data from it using this.$store or other API methods (Check out the documentation)

All you need to do is store your search value in the Vuex store and have all your components access it when necessary.

See a minimal example below:

const mainComponent = Vue.component("mainComponent", {
  computed: {
    search() {
      return this.$store.state.search
    }
  },
  template: "<div><div>Main component</div><div>Search: {{ search }}</div><div><router-link to='/other'>Go to Other</router-link></div></div>"
});
const otherComponent = Vue.component("otherComponent", {
  computed: {
    search() {
      return this.$store.state.search
    }
  },
  template: "<div><div>Other component</div><div>Search: {{ search }}</div><div><router-link to='/'>Go to Main</router-link></div></div>"
});

const store = new Vuex.Store({
  state: {
    search: ''
  },
  mutations: {
    search(state, payload) {
      state.search = payload;
    }
  }
});

const router = new VueRouter({
  routes: [{
      path: "*",
      redirect: "/"
    },
    {
      path: "/",
      component: mainComponent
    },
    {
      path: "/other",
      component: otherComponent
    }
  ]
});

new Vue({
  el: "#app",
  store,
  router,
  data: {
    searchValue: ''
  },
  methods: {
    submitSearch() {
      this.$store.commit("search", this.searchValue);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.5.1/vuex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.4.8/vue-router.min.js"></script>
<div id="app">
  <div class="search-bar">
    <form @submit.prevent="submitSearch">
      <input type="text" v-model="searchValue" placeholder="search" />
      <input type="submit" value="search" />
    </form>
  </div>
  <router-view />
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to enable drag and drop functionality on a dynamically created table using AJAX?

I have been successfully using the TableDnD plugin for drag and drop functionality on table rows. However, I am now facing an issue with dynamically generated tables via AJAX. The code doesn't seem to work as expected when it comes to drag and droppin ...

Troubleshooting: Issue with Nested jQuery UI Accordion Implementation

I am having issues with the menu collapsing incorrectly. While the top level functions properly, the sub menus do not collapse as expected. I am unsure about the correct approach to fix this problem. Can anyone provide guidance? jquery $(function() { ...

Personalizing the look of Stripe Payment Component in a React Application

Currently, I have integrated the Stripe Payment Element into my React application using the code snippet below: import { useStripe, useElements, PaymentElement, } from '@stripe/react-stripe-js' export const PaymentDetails = () => { const st ...

Using $.get inside of a .click event handler

I'm a bit confused about what's happening with this particular piece of code. I have a button element that in theory should trigger the script below when clicked. When I try it in Chrome, everything seems fine - the button works, but the file isn ...

I need help accessing data from a REST API and displaying it in a table

How can I call all the data in "md" and display it in a table? I've tried multiple values but none seem to work. Can someone guide me on how to use the "md" value to display in a table? <script src="https://ajax.googleapis.com/ajax/libs/jquery/ ...

Triggering unexpected syntax error upon clicking the dropdown menu in the navigation bar

I encountered an error when attempting to click the dropdown list on my website. The error message reads as follows: Uncaught Syntax error, unrecognized expression: #. This error only seems to occur when using Chrome or Edge browsers. Currently, I am usi ...

Could there possibly exist a counterpart to .cloneNode?

I'm currently working on a recipe website submission form, and I've successfully implemented code that allows me to add more ingredients dynamically. addIngredientsBtn.addEventListener('click', function(){ let newIngredients = ingre ...

How can I populate a dropdown list in JavaScript with JSON data from a file?

I am experiencing difficulties when it comes to parsing JSON files for use in a dropdown list. JSON: { "BD": "Bangladesh", "BE": "Belgium", "BF": "Burkina Faso", "BG": "Bulgaria", "BA": "Bosnia and Herzegovina" } The goal is to populate the dropdownlist ...

vue Error: Attempting to access properties of an undefined object (specifically, 'NormalModule')

Working on a small web app written in vue, I utilize two different machines for testing and development. Github serves as a convenient platform for me to seamlessly switch between the two. Previously, I encountered no issues while working on my macos mach ...

Is there a way to get an iframe to mimic the behavior of other media elements within a horizontal scrolling container?

Take a look at this code snippet: $(document).ready(function() { $('.scrollable-area').on('wheel', function(e) { var scrollLeft = $(this).scrollLeft(); var width = $(this).get(0).scrollWidth - $(this).width(); var delta ...

Is there an issue with the proper execution of keypresses/updates in the code

I'm currently stuck while trying to develop a game in Javascript. My challenge lies in detecting keypresses and constantly checking if they are being held down to move the character. Below is the code I have been using: var THREE; var keys; var updat ...

Exploring the textures of an imported 3D model mesh with multiple materials in A-Frame and Three JS

Currently, I am exploring A-Frame using a 3D model imported from Blender. Some parts of this model contain multiple meshes with two or more materials assigned to them. It is easy for me to adjust the material properties of meshes with just one material. ...

The type does not have a property named 'defaultProps'

I have a Typescript React class component structured like this: import React, { Component } from 'react'; interface Props { bar?: boolean; } const defaultProps: Partial<Props> = { bar: false, }; class Foo extends Component<Props& ...

The unique capabilities of services and factories in Angular 1 - understanding their differences and what each excels at

After extensively combing through numerous stackoverflow posts and articles, the consensus seems to be that an angular service returns an instance, while an angular factory returns any desired object. This raises the question: what unique capabilities do ...

Why does my node-js API's second endpoint not function properly?

Currently working on my first API project. Everything was going smoothly, until I encountered an issue with my second route, app.route('characters/:characterId'). For some reason, none of the endpoints are functioning, while the first route, app. ...

The deletion function necessitates a switch from a server component to a client component

I built an app using Next.js v13.4. Within the app, there is a server component where I fetch all users from the database and display them in individual cards. My goal is to add a delete button to each card, but whenever I try to attach an event listener t ...

center text above images in flexbox when page is resized

When resizing the page, I'm facing an issue where the links overlap with the images in a flexbox layout. It seems like the padding and margin between the images and links are not working due to them not being "related" or connected. I believe I need t ...

display different vue component based on screen size

I am in search of a method to implement responsive components in Vue.js (Nuxt). I have developed this mix-in but encountering an error: export const mediaQuery = { data() { return { breakpoints: { sm: 576, md: 768, lg: ...

Ways to prompt for user input using JavaScript

How can I collect user input using JavaScript for a website that saves the input into a text file? Below is the code I am currently using: <button type="button" onclick="storeEmail()">Enter Email</button> <script> ...

Vue has detected an error during rendering: "TypeError: state.actionInfo.find is not a function"

Using vue.js's cli, I created a basic data register application. The application utilizes lookback.js api with vue cli. The application consists of three pages: show, add, and edit. While the show and add pages function correctly, issues arise when ...