What is the best way to create clickable text in an HTML string and set up an @click function in VueJS 2?

I have an array of strings that I want to transform by turning certain words like "User object", "Promise", etc into clickable links. Here is the initial array:

var strings = ['This returns a promise containing a User Object that has the id', 'next string']

The desired outcome should look like this:

<div class="wrapper">
    <div class="item" v-for="str in strings" v-html="str"></div>
</div>

The challenge lies in replacing specific words like "User object", "Promise" and attaching a @click event for my application to handle.

If rendered as intended, it would appear as follows (manually recreated from the previous v-for loop example):

<div class="wrapper">
    <div class="item">This returns a <a href="#" @click.prevent="help('promise');">promise</a> containing a <a href="#" @click.prevent="help('User object');">User object</a> that has the id</div>
    <div class="item">next string</div>
 </div>

I attempted to achieve this with the following method but it did not bind the @click event:

methods: {
    linkify(str) {
       return str.replace(/user object/, '<a href="#" @click="help">User object</a>');
    }
}

Any suggestions?

Answer №1

Illustrated below is a component showcasing how it takes a string for the complete message and another string for the text to be replaced with a link. It then proceeds to render a span containing that message, with the link text enclosed within an <a> tag:

Vue.component('linkify', {
  template: '#linkify-template',
  props: {
    value: { type: String },
    linkText: { type: String }
  },
  computed: {
    before() {
      return this.value.split(this.linkText)[0];
    },
    after() {
      return this.value.split(this.linkText)[1];
    }
  }
});

new Vue({
  el: '#app',
  data() {
    return {
      message: 'This returns a promise containing a User Object that has the id',
    }
  },
  methods: {
    foo() {
      console.log('clicked')
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<script type="text/x-template" id="linkify-template">
  <span>
    {{ before }}
    <a href="#" @click.prevent="$emit('click')">
      <code>{{ linkText }}</code>
    </a>
    {{ after }}
  </span>
</script>

<div id="app">
  <linkify link-text="User Object" :value="message" @click="foo"></linkify>
</div>

Answer №2

Finally solved the issue. If anyone knows a more efficient method, please share!

Vue.component('linkify', {
    props: ['value', 'words'],
    template: `<span :is="html"></span>`,
    data() {
        return {
            html: Vue.compile('<span>' + this.value.replace(new RegExp('(' + this.words.join('|') + ')', 'g'), `<a href="#" @click.prevent="$parent.$emit('click', '$1')"><code>$1</code></a>`) + '</span>'),
        }
    }
});

Now I just need to implement this in the main app:

<div class="wrapper">
    <div class="item" v-for="str in strings">
        <linkify :value="str" :words="['user object', 'promise']" @click="help"></linkify>
    </div>
</div>

Unfortunately, this code only functions with the full version of Vue due to its dependency on the compile function.

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

Even after applying trim() function, PHP's return statement still adds spaces unnecessarily

My function is supposed to return a boolean, but for some reason, it is adding spaces at the beginning of the string. Even after using trim(), the spaces persist. What could be causing this unexpected behavior? PHP function checkFile($v){ $result = is_ ...

mandating the selection of checkboxes

Currently, I am exploring the possibility of automatically selecting a checkbox when an option is chosen from a dropdown menu. Below is a code snippet that demonstrates what I am aiming to tweak: $('.stackoverflow').on('change', func ...

The checkbox is not showing the check mark accurately

I am currently working on a React form where I am trying to retrieve the status of a checkbox element from local storage using the useEffect hook. const [checkbox, setCheckbox] = useState(false); useEffect(() => { setCheckbox(localStorage.getItem(&ap ...

VueJS displays an error message stating: "Component '<IncomeList>' is not recognized - have you properly registered the component?"

As a junior student, I attempted to create a simple exercise using the income-tracker tutorial at https://www.youtube.com/watch?v=AjV7k7t78Ik, but encountered an error that I'm struggling to resolve. [Vue warn]: Unknown custom element: <IncomeList ...

Develop a flexible axios client

I have a basic axios client setup like this: import axios from "axios"; const httpClient = axios.create({ baseURL: "https://localhost:7254/test", }); httpClient.interceptors.request.use( (config) => config, (error) => Prom ...

What could be causing issues with my jQuery POST call?

I am attempting to establish authentication with a remote service using jQuery. Initially, I confirmed that I can accomplish this outside of the browser: curl -X POST -H "Content-Type: application/json" -H "Accept: appliction/json" -d '{"username":" ...

Invoke a specific URL during an HTML5 upload

So I've got this code that allows for file upload via drag and drop using HTML5 in the browser. $(function(){ var dropbox = $('#dropbox'), message = $('.message', dropbox); dropbox.filedrop({ // Customizing upload settin ...

The route is displaying the variable as 'undefined' when I attempt to access it

I had set up CRUD for two different models (venues & artists) - venues works fine, but when I try to access 'artists/index', it gives me an error saying 'Artists is not defined'. After examining the code, I believe I need to do two ...

Import MDX metadata in Next.js on the fly

I am currently utilizing Next.js to create a static blog site. Following the guidelines in Next.js documentation, I set up @next/mdx and successfully imported MDX statically using import MDXArticle from "@/app/(article)/2023/test-article/page.mdx&quo ...

Discovering the values within a separate JSON object

I have a collection of json objects that include information about different languages and user details. Languages User Details The user details contain a field for languages, which can have multiple values. Below is a sample json: $scope.languages = ...

Tips for preventing the need to open numerous chrome windows when running multiple URLs with Selenium WebDriverJS

Is there a way to prevent multiple instances of the browser from opening when attempting to parse multiple URLs? I would like to have just one browser open and running all the URLs within it. Any advice or suggestions would be greatly appreciated! I' ...

Does the built-in waiting mechanism in Protractor automatically handle promises?

While browsing through Stack Overflow, I stumbled upon this response in a discussion about Protractor tests and asynchronous solutions: 'AFAIK expect waits internally for the related promises.' I have tried looking through the official Protract ...

Resetting the Angular provider configuration whenever the service is injected into a different location

Trying to wrap my head around a rather complex issue here. I have a service set up as a provider in order to configure it. Initially, this service has an empty array of APIs which can be dynamically added to by various configuration blocks. When adding API ...

Tips for implementing a shape divider in vuetify.js

Currently, I am incorporating the vuetify library into my project and attempting to include a shape divider similar to the one displayed in the image below. Unfortunately, I have been unsuccessful in achieving this desired effect. https://i.stack.imgur.c ...

Unable to access property 'map' of undefined - having trouble mapping data retrieved from Axios request

When working with React, I have encountered an issue while trying to fetch data from an API I created. The console correctly displays the response, which is a list of user names. However, the mapping process is not functioning as expected. Any insights or ...

Allow for the ability to choose a specific option for every individual line that is echoed in

I have researched several similar questions, but none of them address exactly what I am attempting to achieve. My goal is to use AJAX to fetch a PHP page that will display the contents of a folder on my server. Currently, the files are being listed line by ...

How can you stop data URI from being cached as an image source?

I am facing an issue where I have an img-tag with a data-image base64 URI as the source. Browsers tend to cache this source, which is causing problems for me. If it were a normal URL, I could easily prevent caching by adding a random query-parameter value. ...

Stop Antd Modal from automatically scrolling to the top

At the moment, I'm utilizing Ant Design (v4.22.8) and Next.js (v12.3.4) in my project. One issue I've encountered is with a Modal component that activates when a button is clicked. Instead of overlaying the current content on the screen, the moda ...

Tips for sharing data between two components

In my project, I have a customized Shared Component which consists of an input search bar with a "continue" button. This Shared Component is being utilized within two other components - the buy component and sell component. The challenge I am encountering ...

Deactivate PyV8's automatic garbage collection functionality

I am currently experiencing an issue that appears to be stemming from the interaction between Python and PyV8's garbage collection processes. To temporarily address this problem, I have disabled Python's garbage collection and implemented a worka ...