Converting a mention tag text to a <router-link> in VUEJS: Step-by-step guide

I have a body property in my data

data(){
 return{
  body:'Hello! I am @user3 and @user4'
 }
}

I am looking to transform each @user into a clickable link that redirects to their specific URL path.

<router-link :to="`/${username1}`">@{{username1}}</router-link>

My Attempt

<span v-html='bodyReplaced'>
  computed: {
    bodyReplaced(){
      return this.body.replace(
        /@\w+/g, 
        (user) => '<router-link :to="`/${username1}`">@{{username1}}</router-link>'
      )
    }
  }

Outcome of the code:

  1. The transformation was successful in the DOM but not visible in the view
  2. I am struggling with replacing the @ symbol after the match so it can be used in the 'to' attribute like: "`/${username1}

Answer №1

It seems like you are searching for a code snippet similar to:

<template v-for="part of body.split(/(@\w+)/g)">
  <router-link v-if="part[0] == '@'" :to="`/${part.slice(1)}`">{{part}}</router-link>
  <template v-else>{{part}}</template>
</template>

new Vue({
  el: 'main',
  data: {
    body:'Hello im @username1 and @username2'
  },
  router: new VueRouter({
    routes: []
  }),
})
<main>
  <template v-for="part of body.split(/(@\w+)/g)">
    <router-link v-if="part[0] == '@'" :to="`/${part.slice(1)}`">{{part}}</router-link>
    <template v-else>{{part}}</template>
  </template>
</main>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

Answer №2

Develop a custom component named mention and provide the username as a prop. One method is to follow the approach used by @Bergi, alternatively, you can utilize a computed property where you replace the mention user with an a element that can be parsed differently from a router-link :

Vue.component('mention', {
  template: `<router-link :to="'/'+user">@{{user}}</router-link>`,
  props: ['user']
})
const Foo = {
  template: '<div>im foo</div>'
}
const Bar = {
  template: '<div>im bar</div>'
}
const routes = [{
    path: '/foo',
    component: Foo
  },
  {
    path: '/bar',
    component: Bar
  }
]

const router = new VueRouter({
  routes, // short for `routes: routes`,

})

// 4. Establish and initialize the root instance.
// Remember to include the router using the router option in order for the
// entire app to recognize the routing.
const app = new Vue({
  router,
  data() {
    return {
      body: 'Hello im @foo and @bar'
    }
  },

  computed: {
    tokens() {
      return this.body.split(' ');
    },
    bodyReplaced() {
      return this.body.split(' ').map(w => {
        return w.startsWith('@') ? `<a href="#/${w.slice(1)}">${w}</a>` : w;
      }).join(' ')
    }
  }
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <div>********The first solution********</div>

  <template v-for="token in tokens">
    
     <mention v-if="token.startsWith('@')" :user="token.slice(1)"></mention>
     <template v-else>&nbsp;{{token}}&nbsp;</template>
  </template>
  <div>********The second solution********</div>
  <span v-html='bodyReplaced'></span>
  <router-view></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

Issues persist with AngularFire login authentication and redirect

After spending countless hours scouring various websites, documentation, and numerous pages on Stack Overflow, I am still struggling to wrap my head around these issues. Despite my efforts over the past few days, I have made little progress. My project in ...

When dealing with arrays, the parentElement.remove() function may not be defined

Query: e1.parentElement.remove(); is not defined debug: e1 contains a value. e1.remove() removes a button, however, I need to remove a group of buttons. global variable and function execution var x = 0; AllResponses(null, null); primary function featuri ...

Error message thrown on the login page: "Attempting to access property 'push' of an undefined object"

I'm currently working on a login page using JWT and I'm facing an issue with trying to redirect the user to the home page after successful login. I am using this.props.history.push("/") for redirection but I keep getting an error: TypeError: Cann ...

Can you explain the functionality of the following Express router?

In the tutorial I am currently following, there are 2 router methods used to retrieve articles from the database. router.param('article', function(req, res, next, slug) { Article.findOne({ slug: slug}) .populate('author') .th ...

Finished drawing remains on the iPad canvas within the browser

When it comes to clearing sketches on a canvas, I am experiencing some confusion. Despite successfully clearing the sketch from the canvas, as soon as I click to draw something new, the cleared sketch reappears in its original position. It seems like the ...

Tips for continuing a count from where it left off

I have encountered an issue with the input fields in my form. I used the counter method to add input fields and saved the form. However, when I try to add more fields, the counter starts from 0 again. For example, I initially added 5 input fields with mod ...

Determine image size (pre-upload)

One of the requirements for a project I am working on is to verify the dimensions (width and height) of images before uploading them. I have outlined 3 key checkpoints: 1. If the dimensions are less than 600 X 600 pixels, the upload should be rejected. ...

Leveraging the 'require' method in Node.js for linking with external JavaScript files

Recently, I've been experimenting with using the require function in nodejs to access JavaScript files containing simple scripts. My objective is to require the script and then output its return value to the console. Here's an example of what I c ...

Transform the JSON response from MongoDB into a formatted string

var db = mongoose.connection; const FoundWarning = db.collection('warning').find({UserID: Warned.user.id, guildID: message.guild.id}).toArray(function(err, results) { console.log(results); }) I have been attempting to ...

I am being thrown an npm ERR! by Heroku because it says there is a missing script called "start"

I'm facing issues while trying to deploy a simple app on Heroku. The application keeps crashing and these errors keep popping up. In my setup, I have included: "start": "node app.js", The Procfile also contains the command &a ...

The Ember.run.throttle method is not supported by the Object Function as it does not have a throttle method within the Ember.Mixin

I have a controller that has an onDragEvent function: controller = Em.Object.create( { onDragEvent: function() { console.log("Drag Event"); } }); Additionally, I have a Mixin called 'Event': Event = Ember.Mixin.create( { at ...

Adjust the number of columns based on the minimum screen resolution using columnizer

Currently, I am utilizing the columnizer jQuery plugin to divide my content into columns on a responsive website with a fluid width container. I have implemented different JavaScript functions based on the minimum screen resolutions, similar to CSS media q ...

How can I access properties of generic types in TypeScript?

Converting the generic type to any is a valid approach (The type E could be a typescript type, class, or interface) of various entities like Product, Post, Todo, Customer, etc.: function test<E>(o:E):string { return (o as any)['property' ...

Tips for positioning text on the left and right sides of a div in HTML styling

I am struggling with positioning two pieces of text within a div. Despite having some styling already in place, the text is currently displaying one after the other on the left-hand side. I want to position one piece of text to the left and another to the ...

What is the best way to upgrade to a specific version of a child dependency within a module?

npm version: 7.24.2 Looking for assistance on updating a child dependency. The dependency in question is: vue-tel-input This dependency relies on libphonenumber-js with version ^1.9.6 I am aiming to update libphonenumber-js to version ^1.10.12. I have ...

Validating an Element Directive in AngularJS: A Step-by-Step Guide

I have developed a directive for handling numbers function numberInputDirective() { return { restrict: 'E', scope: { model: '=', disabled: '=?', decimals: ...

Can you guide me on setting a background image URL for rails using javascript?

Within my Rails application, I have a collection of content paired with image buttons (each piece of content has an associated image). When a user clicks on one of these buttons, my goal is to display the corresponding image. All of my images are stored u ...

Vue: the placeholder option in the select input is no longer visible once v-model is added

<select class="cursoruser-pointer p-2 w-full rounded-full "> <option class="rounded-full " disabled selected value="">Language to learn</option> <option class="rounded-ful ...

Omit specific TagNames from the selection

How can I exclude <BR> elements when using the statement below? var children = document.getElementById('id').getElementsByTagName('*'); Is there a special syntax for getElementsByTagName that allows me to achieve this, or is the ...

Troubleshooting: Angular.js error when Typescript class constructor returns undefined

I'm currently trying to create a simple TypeScript class, however I keep encountering an error stating this is undefined in the constructor. Class: class MyNewClass { items: string; constructor(){ this.items = 'items'; ...