Vue's Global mixins causing repetitive fires

In an effort to modify page titles, I have developed a mixin using document.title and global mixins.

The contents of my mixin file (title.ts) are as follows:

import { Vue, Component } from 'vue-property-decorator'

function getTitle(vm: any): string {
  const title: string = vm.title
  if (title) {
    return `${title} | site.com`
  }
  return 'Admin panel | site.com'
}

@Component
export default class TitleMixin extends Vue {
  public created(): void {
    const title: string = getTitle(this)
    if (title) {
      document.title = title
    }
  }
}

Next, I registered this mixin globally in main.ts:

import titleMixin from '@/mixins/title'
Vue.mixin(titleMixin)

To set up the title in a specific Vue component, follow these steps:

@Component
export default class Login extends Vue {
  public title: string = 'New title'
}

My project consists of approximately 5 components. By utilizing console.log within the mixin, I can observe that it is invoked in each component sequentially, eventually setting the document.title based on the last component's created() hook.

Is there a more proper way to establish the title for the CURRENT page?

Answer №1

Just like you mentioned, implementing a global mixin will impact all components within your Vue application. This means that the code to update the document.title will execute in the created hook of every component throughout your app.

If you are seeking a more targeted approach, you might want to consider utilizing VueRouter's beforeRouteEnter hook. This particular hook is part of the navigation guards provided by VueRouter and allows you to execute logic just before transitioning to a specified route.

To achieve this specific functionality, your implementation could resemble the following:

@Component
export default class TitleMixin extends Vue {
  public beforeRouteEnter(to, from, next): void {
    next(vm => {
      const title: string = getTitle(vm)
      if (title) {
        document.title = title
      }
    })
  }
}

In the above code snippet, note that we are passing a callback function to the next method, which includes a reference to the component's instance (vm). We then utilize this reference within the getTitle function instead of using this, as the beforeRouteEnter hook does not have direct access to this. For further insights, feel free to explore the documentation link provided.

Answer №2

Instead of relying on a global mixin, consider utilizing the power of a route meta field in conjunction with a global resolve guard.

To implement this approach, begin by setting up a meta field for each RouteConfig object within the /router/routes.ts file:

import { RouteConfig } from 'vue-router'

export default [
  {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: 'login-view' */ '@views/Login.vue'),
    meta: {
      title: 'Login', // Define the view title
    },
  },
  // ... Add the title meta field to every `RouteConfig`
] as RouteConfig[]

Next, establish a global resolve guard that updates the document title based on the title meta field, located in the /router/index.ts file:

import Vue from 'vue'
import Router, { Route } from 'vue-router'
import routes from './routes'

Vue.use(Router)

const router = new Router({
  // ... Specify RouterOptions
})

// Before resolving each route...
// Resolve guards are invoked just before confirming navigation,
// following resolution of all in-component guards and async route components.
router.beforeResolve((routeTo, routeFrom, next) => {

  const documentTitle = getRouteTitle(routeTo)

  // If the target `Route` has a meta property with a defined title meta field,
  // update the document title accordingly
  if (documentTitle ) {
    document.title = documentTitle 
  }

  // Proceed with navigation by calling `next`...
  next()

  function getRouteTitle(route: Route): string {
    const title: string = route.meta && route.meta.title
    if (title) {
      return `${title} | site.com`
    }
    return 'Admin panel | site.com'
  }
})

export default router

Answer №3

To ensure proper usage, the mixin should only be applied in the parent component of your webpage (the one governing the entire page).

When utilizing vue-property-decorator, follow this format:

import { Vue, Component, Mixins } from 'vue-property-decorator';

@Component
export default class Login extends Mixins(titleMixin) {
  public title: string = 'New title'
}

Avoid globally importing it using Vue.mixin(titleMixin). This will apply the mixin to all components throughout your project.

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

Encountering an error when using Angular Material virtual scroll in conjunction with Angular-UI

Trying to incorporate Angular material's virtual scroll feature on angular-ui-tree is proving to be a bit challenging. The error message that keeps popping up is: Controller 'uiTree', which is required by directive 'uiTreeNode', ...

Navigating after submitting a form using the Location header in jQuery

Seeking a way to utilize the Location header in jQuery 1.7 for redirection to a target. The current code is structured as follows: $('#creationLink').click(function(){ $.ajax({ type: 'POST', url: '/', success: ...

Having trouble establishing a connection between VueJS 3 and Socket.io

I am new to the world of Socket.IO and backend technologies. Although I have experience with Vue, I am currently facing a challenge in creating a basic multiplayer game. My stumbling block lies in connecting vueJS with SocketIO for my project. Here is th ...

Using JSON data in an ArrayBuffer with TypeScript

I am currently struggling with converting the received ArrayBuffer data from a server via Websocket into another format. Below is the WebSocket code snippet: let ws = new WebSocket('wss://api.example.com/websocket'); ws.binaryType = 'arrayb ...

Is there a way to append a URL parameter after a link is clicked using Vue.js?

I am currently working on integrating heading links on my website's sidebar that are linked to the main content using scrollspy. This allows users to easily navigate to different sections of the main content by clicking on the corresponding headings i ...

"Error encountered: Unable to resolve dependency tree" message appears when attempting to run npm install

Encountering dependency errors while trying to execute the npm install command for my Angular application. As a newcomer to TypeScript and Angular, I'm unsure of the next steps to take. Any suggestions? Attempted solutions include clearing the npm ca ...

What are the steps to effectively utilize npm warnings within tslint?

After using eslint for javascript files, I am now transitioning to tslint for TypeScript linting. With eslint, I could specify some errors as NPM warnings, such as console logging. https://i.sstatic.net/BNhy6.png I realize that my "warnings" are generat ...

Troubleshooting issues with the delete functionality in a NodeJS CRUD API

I've been struggling to implement the Delete functionality in my nodejs CRUD API for the past couple of days, but I just can't seem to get it right. As I'm still learning, there might be a small detail that I'm overlooking causing this ...

Can we create a collection of Vue highcharts components in a library format?

I am in search of an answer, with hope that it lies here. I have used the following: "vite": "^2.7.13", "highcharts": "^9.3.3", "highcharts-vue": "^1.4.0" I aim to create a library of Vue compon ...

The powerful combination of harp.gl and Angular NG

We've integrated harp.gl into our ng Angular application, but we're encountering issues when trying to connect to data sources that previously worked in our yarn demo. The datasource is created as follows: const dataSource = new OmvDataSour ...

Executing JavaScript code within ASP.NET Visual Basic

My current web application uses jQuery and JavaScript, but I want to add more features that are supported in ASP.net VB. However, I am unsure if the JavaScript can run after the VB code. Essentially, I would like the web app to follow this sequence: ...

Automatic popup updates when submitting a form in a Chrome extension

Looking to develop a chrome extension popup window that, when clicked, will present a form for users to input their name and college. The goal is to save this data in chrome storage and then replace the popup with a new window displaying a greeting message ...

Can PHP's CURL handle cookies?

Recently, I set up a poll using PHP that allows voting without the need for an account. However, I became concerned about the possibility of the poll being vulnerable to hacking and spam votes. I discovered that I could potentially vote multiple times by ...

Encountering a 404 error indicating that the file cannot be found while attempting to log into an authentication system developed using express and node

Currently, I am in the process of developing a demonstration banking application that facilitates user sign up and sign in functionality using express.js and node.js. The API created accepts POST requests to /signup and /authenticate routes successfully wh ...

What steps should I take to resolve the 'buffer' issue in my jsonwebtoken?

As I am still new to ReactJS and the MERN stack in general, the code in Activate.js below essentially means that when the useEffect() hook is triggered, we will receive the jwt token extracted from the route parameter/url using the {match} props. This toke ...

Avoid changing the regex pattern if it is surrounded by a specific character

I want to change all occurrences of strings enclosed by - with strings enclosed by ~, unless the string is again surrounded by *. For instance, consider this string... The -quick- *brown -f-ox* jumps. ...should be altered to... The ~quick~ *brown -f-ox ...

I encountered an error while using the router: TypeError: Cannot read property 'use' of undefined

Hello everyone, I am new to node.js and seeking help from experts. I am currently working on a code for user synchronization using node.js + AWS Cognito + Facebook Login. I followed an example from this link. Everything was going smoothly until I reached ...

Creating a Select component in React without relying on the Material-UI library involves customizing a dropdown

Is there a way to achieve a material UI style Select component without using the material UI library in my project? I'm interested in moving the label to the top left corner when the Select is focused. export default function App({...props}) { retu ...

Having trouble with passing props to data() in Vue.js?

I'm facing an issue where I am unable to pass props to data() in my Vue inline template: <network-index inline-template> ... <network-list :data="networks"></network-list> ... </network-index> Inside the Index.vue file, here ...

Utilizing the indexOf Method in AngularJS

Here is my array: emp=["111","56"]. This is the code I have: <input type="text" placeholder="Enter" class="form-control" name="Emp" ng-model="myModel.Emp" ng-required="currentStep ==2"/> <input type="text" placeholder="Enter" class="form-contro ...