Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
218 views
in Technique[技术] by (71.8m points)

javascript - Create anchor tags dynamically in Vue.JS

I have a JS-object and I need to be able to create html elements out of it and render it in Vue.JS. My solution until now was to get the object, create the HTML-elements as strings out of it and then just add it to the template. However, although this shows the elements correctly, the anchor tags are not clickable.

<template>
  <div>
    <template v-if="elementData">
      <ul>
        <li v-for="(value, key) in elementData" :key="key">
          <div v-html='value'></div>
        </li>
      </ul>
    </template>
  </div>
</template>

<script>
const about = [
  [
    'This is normal text ',
    {
      text: 'im a link',
      link: 'https://www.stack-overflow.com',
    },
    ', is not bad ',
  ],
  [
    'More text and text',
  ],
];

export default {
  data() {
    return {
      elementData: [],
    };
  },
  mounted() {
    this.setData();
  },
  methods: {
    setData() {
      this.elementData = about.map((paragraph) => {
        let pElement = '<p>';
        paragraph.forEach((part) => {
          if (typeof part === 'object') {
            const link = `<a target="_" :href="${ part.link }">${ part.text }</a>`;
            pElement = pElement.concat(link);
          } else pElement = pElement.concat(part);
        });
        pElement.concat('</p>');
        return pElement;
      });
    },
  },
};
</script>

The problem probably comes from me not creating the actual html-elements (like when using document.createElement('div') with vanilla JS). However, I don't know how to do this Vue.JS.

question from:https://stackoverflow.com/questions/65904531/create-anchor-tags-dynamically-in-vue-js

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of manipulating the DOM manually, you can use Vue's conditional rendering to achieve the same goal. Take a look at this solution below:

<template>
  <div>
    <template v-if="elementData">
      <ul>

        <li v-for="(paragraph, key) in elementData" :key="`paragraph-${key}`">
          <span v-for="(part, partKey) in paragraph" :key="`part-${partKey}`">
            
            <!-- Render an anchor tag if the part is a link -->
            <template v-if="isLink(part)"
              ><a :href="part.link">{{ part.text }}</a></template
            >
            <!-- Else, just put output the part -->
            <template v-else>{{ part }}</template>
          </span>
        </li>

      </ul>
    </template>
  </div>
</template>

<script>
const about = [
  [
    "This is normal text ",
    {
      text: "im a link",
      link: "https://www.stackoverflow.com",
    },
    ", is not bad ",
  ],
  ["More text and text"],
];

export default {
  ...
  data() {
    return {
      elementData: [],
    };
  },
  mounted() {
    this.setData();
  },
  methods: {
    isLink(e) {
      // You can change this condition if you like
      return e && typeof e === "object" && e.link && e.text; 
    },
    setData() {
      this.elementData = about;
    },
  },
};
</script>

Notice how we just created elements based on conditions. We render an anchor tag if the part is an object, and has the link and text attribute. Else, we just display the string.

enter image description here

See live demo


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...