Customized Vuetify: Step-by-step guide to set up VueRouter for opening links in a new tab

I've set up a navbar with a menu that users can interact with by clicking on the links. Some of these links should open in a new tab, but I'm having trouble getting it to work properly.

<template>
    <nav>
        <v-app-bar text app color="blue">
            <v-app-bar-nav-icon class="white--text" @click="drawer = !drawer"></v-app-bar-nav-icon>
            <v-app-bar-title class="text-uppercase white--text">
                <span class="font-weight-light">Logo</span>
                <span>Global</span>
            </v-app-bar-title>
        </v-app-bar>

        <v-navigation-drawer v-model="drawer" app class="grey lighten-1">
            <v-list>
                <img class="ml-5 mb-3" src="../assets/Logo-Blue.png" width="70" />

                <v-list-item v-for="link in links" :key="link.text" router :to="link.route" @click="go(link)">
                    <v-list-item-action>
                        <v-icon>{{ link.icon }}</v-icon>
                    </v-list-item-action>
                    <v-list-item-content>
                        <v-list-item-title> {{ link.text }} </v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
            </v-list>
        </v-navigation-drawer>
    </nav>
</template>
<script>
export default {
    data() {
        return {
            drawer: true,
            links: [
                { icon: 'home', text: 'Dashboard', route: '/dashboard', newTab: false },
                { icon: 'leaderboard', text: 'Stats', route: 'www.google.com ', newTab: true },
            ]
        }
    },
    methods: {
        go(link) {
            console.log('Handling link click...')
            console.log(link)
            console.log(process.env.APP_URL)

            if (!link.newTab) {
                this.$router.push({ path: link.route })
            } else {
                window.open(link.route)
            }
        }
    }
}
</script>

src/router/index.js

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
})

export default router

Could you please review my code? It seems like opening a new tab works, but it's adding my localhost URL prefix.

Answer â„–1

Avoid using a click event handler with the v-list-item component as it interferes with the anchor tag used for routing purposes and may impact accessibility. Instead, utilize the built-in props of v-list-item for routing:

  • href: Use the href prop to create an external link with <v-list-item>. For internal links, use the to prop.

  • target: To open the link in a new window, add the target="_blank" prop.

For an external link with v-list-item, use the href prop like this:

<v-list-item href="https://example.com">Example</v-list-item>

To open a link in a new tab, add the target="_blank" prop:

<v-list-item target="_blank" href="https://example.com">Example</v-list-item>

Internal links should use the to prop instead of href:

<v-list-item to="/dashboard">Dashboard</v-list-item>

You can also open internal links in a new tab by adding target="_blank":

<v-list-item target="_blank" to="/dashboard">Dashboard</v-list-item>

Solution

If you need to conditionally bind the mentioned props to an array of items, you can achieve this using v-bind with an object that computes values based on each item's properties:

  1. Create a computed property called computedLinks that includes the necessary linking props:
export default {
  computed: {
    computedLinks() {
      return this.links.map(link => {
        const isExternalLink = url => /^((https?:)?\/\/)/.test(url)
        const linkProps = {
          [isExternalLink(link.route) ? 'href' : 'to']: link.route,
        }
        if (link.newTab) {
          linkProps.target = '_blank'
        }
        return {
          ...link,
          linkProps,
        }
      })
    },
  },
}
  1. Update the template to utilize computedLinks and bind each link's linkProps to its respective v-list-item:
<v-list-item v-for="link in computedLinks" :key="link.text" v-bind="link.linkProps">
                                   👆                                        👆

Live Demo

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

Resolve problem with npm peerDependencies for specific package

One issue my application is facing involves a set of domain packages that all have the core as a peer dependency. The structure of these domain packages is as follows: "name": "domain-a-pckg", "peerDependencies":{ "core-p ...

React Intersection Observer not functioning properly

Hey there! I'm trying to create an animation where the title slides down and the left element slides to the right when scrolling, using the intersection observer. Everything seems to be fine in my code, but for some reason it's not working. Any t ...

How can you establish a specific limit for digits between two numbers using vee-validate?

I'm looking to limit the number of digits a user can input to between 3 and 6. For some reason, I haven't been able to figure out how to do that. This is the code I currently have in place to require the user to input only three digits: <in ...

Running complex operations within a sorting function just once

I am facing the challenge of sorting an array of objects based on multiple date fields, with the added complexity of excluding certain dates depending on the category. In order to optimize performance, I want to minimize the number of times the getUsefulJo ...

What is the best way to manage rotation with TrackBallControls in three.js?

I've been working on this app. By clicking the top left tab, you can view the assistant cube and use trackBallControls to move the camera by dragging your mouse around the screen. However, when toggling between showing and hiding the assistant cube, t ...

Updating the count property of an object using setState in React

I have an array of integers ranging from 0 to 6 as my input. My goal is to create an object that gives the count of each number in the array. edition = [6, 6, 6, 1, 1, 2]; const [groupedEdition, setGroupedEdition] = useState([{"0": 0, "1&quo ...

"Common Errors Encountered When Running 'npm start'

Each time I attempt to initiate my react project, it presents me with these errors npm ERR! code ENOENT npm ERR! syscall open npm ERR! path C:\Users\Mohamed Badrawy\Desktop\reactjs-basics-master\package.json npm ERR! errno -4058 n ...

Node.js 'BLOB containing [object File]'

I am currently attempting to retrieve a BLOB from a request. The request object is created using FormData in Angular. const buffer = fs.readFileSync(fileFromRequest); The above code is resulting in an error: Error: ENOENT: no such file or directory, ope ...

Semantic UI dropdown field not displaying selected option text

I've encountered an issue while working with React Semantic UI. I'm trying to render a dropdown and have configured it so that the selected option's text should display in the field. However, when I choose an option from the dropdown, instea ...

Is there a different option instead of using the exit() function?

I am attempting to modify the class of a button based on a condition not being met (if(strlen($username) < 5)). Here is my code: if( strlen($username) < 5 ){ echo '<span class = "glyphicon glyphicon-remove" style = "color:red"> ...

Is the Angular Library tslib peer dependency necessary for library publication?

I have developed a library that does not directly import anything from tslib. Check out the library here Do we really need to maintain this peer dependency? If not, how can we remove it when generating the library build? I have also posted this question ...

The error message "node Unable to iterate over property 'forEach' because it is undefined" appeared

I am facing an error and unable to find the solution. I believe my code is correct. It is related to a video lesson where I attempt to display popular photos from Instagram using the Instagram API. However, when I try to execute it, I encounter this issue. ...

`Why won't the checkbox uncheck when the dropdown is changed in jQuery?`

I have a roster of users, each with a unique checkbox for selection. When I adjust the dropdown menu, a new group of users is chosen and marked as selected. However, I am struggling to uncheck the previously selected checkboxes based on the last dropdown c ...

Ways to automatically scroll the page to the top when new content is loaded on a Single Page Application

I've recently integrated the Single Page Application Plugin in my website built with octoberCMS and also included smooth-scrollbar.js. While most things are working smoothly, there's one issue I'm facing - smooth-scrollbar doesn't auto ...

Randomly choose one of 5 pages and insert an HTML element at different intervals using JavaScript, jQuery, MySQL, or PHP

Suppose we have the following HTML element: <img src="icon.png"> Our website consists of 5 pages: index.php products.php register.php about.php terms.php How can we randomly place this HTML element on one of the pages, ensuring it stays there for ...

Arranging asynchronous functions using async/await in Node.js/JavaScript

When it comes to organizing my code in js/nodejs, I frequently rely on this pattern. (async function(){ let resultOne = await functionOne(); let resultTwo = await functionTwo(); return { resultOne: resultOne, resultTwo: resul ...

Issues with closures in JavaScript

Struggling to grasp closure with 3 levels of scopes. https://jsfiddle.net/Ar2zee/wLy8rkyL/1/ How can I retrieve the value of parameter "g" within the level3 function? var a = 10; function level1(b) { var c = 1; function level2(f) { var d = 2 ...

I am perplexed as to why my useEffect function is executing twice within my NextJs client

I am currently working on a NextJs program and using a function called useAsync on my website. However, I have noticed that this function runs twice every time it is called. I suspect that the useEffect calling the useAsyncInternal might be causing this be ...

Using VueJs and BootstrapVue, you can easily set up a table to delete items only on the

I have set up a page showcasing all my items in a BootstrapVue b-table. Each item has the option to be deleted. However, I encountered an unexpected issue when I enabled pagination using the b-pagination element and :per-page attribute. The problem arises ...

Convert the onChange event in JavaScript to a SQL query

Trying to figure out the best way to achieve this, but I'm hitting a roadblock in my code. Essentially, I want the user to have the ability to select time intervals in increments of 30 minutes up to a maximum of 5 hours (which would be 10 options). Ea ...