Vue.js - how to output link from an object - javascript

I want to output a hyperlink from an object. Is it possible to do so?
I currently have this in my store.js, would like to use this info to output
it in a modal on my website. I got it to display it, but the a href is outputting as text.
Checked this, but none of these solutions worked for me:
Adding hyperlink in Javascript array of objects
export default {
photos: [
{
name: "fox1",
image: "fox01.jpg",
id: 1,
header: "Photoshoot with Fox Apparel",
description:
"Photoshoot with " +
'Fox' +
", a sustainably - driven e - retailer from Canada."
}
]
}

here is the solution:
https://nexladder.com/vuejs-tutorial/vuejs-v-html-directive
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div v-html="content"></div>
</div>
<script>
new Vue ({
el: '#app',
data: {
content: '<h2>Hello World</h2>'
}
})
</script>
</body>
</html>

Related

How to make Vue app in javascript and make it work in html?

Hi I'm trying to make my Vue app in javascript so it isn't in html. Is there any way how to make it work? I tried this:
In HTML:
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="assets/actions.js" type="text/javascript"></script>
in javascript:
const AppNotes = Vue.createApp({
data: {
newFormtext: "",
contents: [
{title: "First Title", contents: ["content1", "content2", "content3"]}
]
},
methods: {
addNewFormEvent() {
this.titles.push(this.formtext)
}
}
})
AppNotes.mount('#content')
but it don't work in my html and text is still like {{ content.title }}
Here is a basic template of vuejs 2 using html and javascript, without node.
You must call Vue constructor and set the el value to some tag id.
new Vue({
el: "#notes-app",
data: {
counter: 0
},
methods: {
increment() {
this.counter++;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="notes-app">
{{ counter }}
<button v-on:click="increment">increment</button>
</div>

How do I display two components with vue.js?

this is my first post on here! Just need some small help with a problem. Thanks!
I just started learning vue.js and I'm trying to get my second components template to display on the page. For some reason, vue isn't rendering my second component, only the first. I'm thinking something is wrong within the index file with <education :data='data' />. Do I need to create a different <div id='app'> and put the second component within it?
app.js:
// Fetch handler
function fetchData(url) {
return fetch(url)
.then(checkStatus)
.then(res => res.json())
.catch(error => console.log('Error retrieving data', error))
}
// Response error handler
function checkStatus(res) {
if(res.ok) {
return Promise.resolve(res);
} else {
return Promise.reject(new Error(res.statusText));
}
}
(() => {
// Define components.
Vue.component('contact-info', {
props: ['data'],
template: `
<div>
<img v-bind:src='data.photo'>
<h1>{{ data.name }}</h1>
<p>{{ data.email }}</p><p>{{ data.phone }}</p>
<p v-if='data'>{{ data.links[0] }}</p><p v-if='data'>{{ data.links[1] }}</p>
</div>
`
});
Vue.component('education', {
props: ['data'],
template: `
<div>
<h3>Education</h3>
<div>
<h2></h2>
<p></p>
<p></p>
<div>
<div>
`
});
// Instantiate the app.
const app = new Vue({
el: '#app',
data() {
return {
data: ''
}
},
mounted() {
fetchData('https://wip.journeygroup.com/intern-api/joshbryant.json')
.then(jsonData => (this.data = jsonData))
}
});
})();
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Resume • Josh Bryant</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Work+Sans:wght#400;600;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./css/main.css">
</head>
<body>
<div id="app">
<contact-info :data='data' />
<education :data='data' />
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
<script src="./app/main.js"></script>
</body>
</html>
Your post shows app.js though the HTML looks for main.js, but I'll assume that's just a posting error since you've gotten some of it working.
The reason it doesn't work is because custom HTML components require a closing tag and cannot be self-closing. If you were using Vue CLI this would work anyway because the compiler would fix it, but not in a CDN implementation of Vue. The first component will work but everything that follows will be invalid HTML since the first component isn't closed properly.
This will work:
<div id="app">
<contact-info :data="data"></contact-info>
<education :data="data"></education>
</div>
A couple of other suggestions
As #tao mentioned in comments, it's confusing to call your variable data in the root component, and similarly to call your props data. These won't cause a problem but probably best to rename them all for clarity (so as not to be confused with the component's data option.)
There's an invalid bullet character in the HTML <title> tag which you can replace with &bullet;
It's best to use double quotes for your HTML attributes (the props use single quotes in your code)

How to get DOM of a vue component without rendering it?

Suppose I have a simple Vue component like this:
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
I don't want to render the component. I just want to pass the title somehow into blog-post component inside my script code, and get the DOM accordingly. For example, if I pass the title value Hello, then I expected the full DOM as <h3>Hello</h3>. I'll assign the DOM into a variable for using later.
One solution is to create a new Vue instance with only the target component, $mount it, and then get the outerHTML of its $el (root element):
Vue 2
<script src="https://unpkg.com/vue#2.6.12/dist/vue.min.js"></script>
<script>
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
const app = new Vue({
template: `<blog-post title="Hello world" />`
}).$mount()
console.log(app.$el.outerHTML)
</script>
Vue 3
In Vue 3, create an app instance, and call its mount() on a newly created <div>. The return value of mount() is the root component, which contains $el:
<script src="https://unpkg.com/vue#3.2.39/dist/vue.global.prod.js"></script>
<script>
const app = Vue.createApp({
template: `<blog-post title="Hello world" />`
})
app.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
const comp = app.mount(document.createElement('div'))
console.log(comp.$el.outerHTML)
</script>
If you want to get HTML of your component, you must to use ref attribute of parent element.
Try something like that:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<button #click="logComponentBlogPost">Log Component</button>
</div>
<div v-show="false" ref="BlogPost">
<blog-post title="Hello Word"></blog-post>
</div>
</div>
<script>
let BlogPost = Vue.component('BlogPost', {
props: ['title'],
template: '<h3>{{ title }}</h3>',
});
new Vue({
el: '#app',
components: { BlogPost },
methods: {
logComponentBlogPost() {
console.log(this.$refs.BlogPost.innerHTML);
},
},
});
</script>
</body>
</html>

Why is VueJs not working showing the data?

The code below just show the title in curly braces, what is wrong with the VueJs setup?
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue#2.5.13/dist/vue.js"></script>
</head>
<body>
<div id='app'>
<p>{{ title }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
title: 'A Title'
}
});
</script>
</body>
</html>
#Web Dev It works fine but you need to do this in script tag
var app = new Vue({
el: '#app',
data: {
title: 'A Title'
}
});
And now if you load the page and you will see a title and then you can open the console and change title by typing app.title = 'My new title'

How can I bind the html <title> content in vuejs?

I'm trying a demo on vuejs. Now I want the html title to bind a vm field.
The below is what I tried:
index.html
<!DOCTYPE html>
<html id="html">
<head>
<title>{{ hello }}</title>
<script src="lib/requirejs/require.min.js" data-main="app"></script>
</head>
<body>
{{ hello }}
<input v-model="hello" title="hello" />
</body>
</html>
app.js
define([
'jquery', 'vue'
], function ($, Vue) {
var vm = new Vue({
el: 'html',
data: {
hello: 'Hello world'
}
});
});
But the title seemed not bounded, how to make it work?
There are essentially two ways to solve it.
Use an existing Package
For example, vue-meta:
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
metaInfo: {
// if no subcomponents specify a metaInfo.title, this title will be used
title: 'Default Title',
// all titles will be injected into this template
titleTemplate: '%s | My Awesome Webapp'
}
}
</script>
Create your own Component
Create a vue file containing:
<script>
export default {
name: 'vue-title',
props: ['title'],
watch: {
title: {
immediate: true,
handler() {
document.title = this.title;
}
}
},
render () {
},
}
</script>
Register the component using
import titleComponent from './title.component.vue';
Vue.component('vue-title', titleComponent);
Then you can use it in your templates, e.g.
<vue-title title="Static Title"></vue-title>
<vue-title :title="dynamic.something + ' - Static'"></vue-title>
You can do it with 1 line in the App.vue file, like this:
<script>
export default {
name: 'app',
created () {
document.title = "Look Ma!";
}
}
</script>
Or change the <title> tag content in public/index.html
<!DOCTYPE html>
<html>
<head>
<title>Look Ma!</title> <!- ------ Here ->
</head>
...
This answer is for vue 1.x
using requirejs.
define([
'https://cdn.jsdelivr.net/vue/latest/vue.js'
], function(Vue) {
var vm = new Vue({
el: 'html',
data: {
hello: 'Hello world'
}
});
});
<!DOCTYPE html>
<html id="html">
<head>
<title>{{ hello }}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.js" data-main="app"></script>
</head>
<body>
{{ hello }}
<input v-model="hello" title="hello" />
</body>
</html>
you can do it like this using the ready function to set the initial value and watch to update when the data changes.
<html>
<head>
<title>Replace Me</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<input v-model="title">
</div>
<script>
new Vue({
el: '#app',
ready: function () {
document.title = this.title
},
data: {
title: 'My Title'
},
watch: {
title: function (val, old) {
document.title = val
}
}
})
</script>
</body>
</html>
also i tried this based on your original code and it works
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<input v-model="title">
</div>
<script>
new Vue({
el: 'html',
data: {
title: 'My Title'
}
})
</script>
</body>
</html>
Just to chime in here. I have read that VueJS wants nothing to do with the meta stuff so I would do such things outside of the "VueJS" realm.
Basically make a plain vanilla js service like below. Here you could add all the functions to handle the meta data stuff such as the Open Graph data.
meta.js
export setTitle(title) {
document.title = title
}
Now we can import the service in main and then provide it to any component in the app who wants it. I could even use my meta service in other projects too which use different frameworks like React or Angular. Portability is super cool!
main.js
import meta from './meta'
new Vue({
router,
render: h => h(App),
provide: {
meta: meta
}
}).$mount('#app')
Here the component injects the meta service it wants to use.
someView.vue
export default {
name: 'someView',
inject: ['meta'],
data: function() {
returns {
title: 'Cool title'
}
},
created: function() {
this.meta.setTitle(this.title);
}
}
This way the meta service is decoupled from the app because different parent components can provide different versions of the meta service. Now you can implement various strategies to see which one is right for you or even different strategies per component.
Basically the inject walks up the component hierarchy and takes the meta service from the first parent who provides it. As long as the meta service follows a proper interface, you're golden.
Decoupling with DI is super cool 😃
Title and meta tags can be edited and updated asynchronously.
You can use state management, create a store for SEO using vuex and update each part accordingly.
Or you can update the element by yourself easily
created: function() {
ajax().then(function(data){
document.title = data.title
document.head.querySelector('meta[name=description]').content = data.description
})
}
If you are using Vuex and want <title> to be part of your application state, then:
create a pageTitle state variable in Vuex
map the state to the template using mapState()
watch it in template, probably add immediate: true to trigger the watcher right away
in watcher, document.title = pageTitle
This will allow you to manage title with Vuex and keep them in sync. I found it useful for SPAs.
By doing this you don't have to mess with your original HTML template, as most of the time Vue root template resides inside <body>.
This is for Vue 2.x.
router.beforeEach((to, from, next) => {
let mohican = to.path; if (mohican == '/') mohican = 'Home'
document.title = mohican.replace('/','');
next();
return;
});
I have an application toolbar component which is common for all pages of my SPA website and is nested in App.vue. In every page I update my common toolbar title in the created hook of the page using Vuex store:
//in every page.vue
created() {
this.$store.commit('toolBar', { pageTitle: this.pageTitle, ... })
},
To automatically update the website title (along with the toolbar title) I use this mutation in the store:
//store.js
toolBar(state,val){
document.title = val.pageTitle
state.toolBar = val
},
Similarly, I use the same mechanism to update e.g. SEO metadata
just pass
:title="data.name"

Categories