How to import extrenal library on mounted hook in Nuxt Js? - javascript

I use conversation form package in my nuxt js project. I found custom component from github where used this package.
Component code:
<template>
<form id="my-form-element" cf-form></form>
</template>
<script>
import * as cf from 'conversational-form'
export default {
mounted: function() {
this.setupForm()
},
methods: {
setupForm: function() {
const formFields = [
{
tag: 'input',
type: 'text',
name: 'firstname',
'cf-questions': 'What is your firstname?'
},
{
tag: 'input',
type: 'text',
name: 'lastname',
'cf-questions': 'What is your lastname?'
}
]
this.cf = cf.startTheConversation({
options: {
submitCallback: this.submitCallback
},
tags: formFields
})
this.$el.appendChild(this.cf.formEl)
},
submitCallback: function() {
const formDataSerialized = this.cf.getFormData(true)
console.log('Formdata, obj:', formDataSerialized)
this.cf.addRobotChatResponse(
'You are done. Check the dev console for form data output.'
)
}
}
}
</script>
Now when I use this component get error message:
window is not defined
As solution of this error recomended this answer from stackowerflow
And after seen this answer I've change component code.
Changes:
1.Removedimport * as cf from 'conversational-form'
2.Replaced mounted() hook content to:
var cf = require('conversational-form')
this.setupForm()
After changes error fixed but package not work correctly. When call this library inside methods as this.cf nuxt js can't found cf var. How I can fix this problem?
Also you can see live demo of this package in vue js here

This is a rare situation that you may need to use the <client-only> tag. If you're using a version older than 2.9.0, then it is <no-ssr>. Docs found here.
Example:
<template>
<client-only>
<form id="my-form-element" cf-form></form>
</client-only>
</template>
<script>
import * as cf from 'conversational-form'
export default { ... }
</script>
This instructs Nuxt to only render the component client side, where window is defined.

Related

Dynamically add css theme when the App.vue has been mounted?

I'm trying to add a CSS theme file globally inside the root component App.vue in a Vue3 project. I have to process it as a component props (I can't change this behavior since the css file can change dynamically and I need to handle this change every time it is mounted again), so the link will be available once the whole app is mounted.
I've been trying to achieve this inside App.vue appending to the header a <link> tag but I'm getting the MIME type ('text/plain') is not a supported stylesheet MIME type, and strict MIME checking is enabled. error even if I specified the text/css type:
export default defineComponent({
name: "Application",
props: {
themeUrl: {
type: String,
required: false,
},
},
data() {
return {};
},
created() {
if (this.themeUrl) {
console.log(this.themeUrl);
let file = document.createElement("link");
file.rel = "stylesheet";
file.type = "text/css";
file.href = this.themeUrl;
document.head.appendChild(file);
}
},
});
</script>
Is there a way to achieve this? I think I can get this theme url even before the app mounting phase but I don't know if and how to tell Vue to use it globally anyway.
If you have a direct link to the css file then this should be sufficient, make sure to remove the tag when unmounted if you need to swap the theme.
It looks that your file.type = "text/css"; is the cause of the issue.
mounted () {
const file = document.createElement('link')
file.rel = 'stylesheet'
file.href = 'https://gist.githubusercontent.com/eirikbakke/1059266/raw/d81dba46c76169c2b253de0baed790677883c221/gistfile1.css'
document.head.appendChild(file)
}
You could also fetch the file content and load it into an existing tag:
Fetch the theme file in a lifecycle hook (mounted())
Read its content
Apply the style with the corresponding querySelector
With this tag in the head :
<style id="customStyle"></style>
And a similar behavior in your component :
export default defineComponent({
name: "Application",
props: {
themeUrl: {
type: String,
required: false,
},
},
data() {
return {};
},
mounted() {
if (this.themeUrl) {
console.log(this.themeUrl);
fetch(this.themeUrl)
.then(response => {
response.text().then(content => {
document.getElementById('customStyle').innerHTML = content
})
})
}
},
});
</script>
https://stackoverflow.com/a/68003923/4390988

nuxt.js get default head in vue.js component

I am trying to get the head object that is configured by nuxt.config.js in a vue layout. In order to show the same title in an app bar as the page title.
I know that you can alter the page title with the head function in a vue component. But is it also possible to retrieve this information somehow?
<script>
export default {
data () {
return {
title: head.titleTemplate // possible?
}
},
head () {
// here it is possible to change it but how about getting it?
}
}
</script>
Another approach could be to get some data out of an page in the nuxt.config.js. But I think this is not how the hierarchy is structured.
Thanks for you help I am just starting to use javascript to code a website :)
(If I understand you correctly) You can use the changed callback to keep track of the latest meta info used (and thus the title).
Example:
head() {
return {
changed: (info) => {
this.title = info.title;
console.log(info, info.title);
},
};
},
data() {
return {
title: '',
};
},
In nuxt.config.js before export I have setted variable with a string of the title.
Then added it to the head section and create a new env section:
https://nuxtjs.org/api/configuration-env/
const title = `Site title`
export default {
head: {
title
},
env: {
title
}
}
This how I'm getting the title in any Vue component:
export default {
computed: {
title () {
return process.env.title
}
},
}
This helps you to keep your original title in process.env.title, even if you will want to change head.title dynamically.
Did anyone found a better solution maybe? :)

VueJS : Adding to existing HTML and handling imports

So I built a Single Page Application in VueJS which works nicely but the SEO sucks as expected, so I decided to make a normal HTML site with some pages having VueJS code (Remote hosting so no node else I would go SSR).
I followed this guide which works fin
I have a search.js which contains my VueJS instance and methods etc
Vue.component('todo-component', {
template: '#todo-component',
data: function () {
return {
items: [
{
id: 'item-1',
title: 'Checkout vue',
completed: false
}, {
id: 'item-2',
title: 'Use this stuff!!',
completed: false
}
],
newItem: ''
};
},
methods: {
addItem: function () {
if (this.newItem) {
var item = {
id: Math.random(0, 10000),
title: this.newItem,
completed: false
};
this.items.push(item);
this.newItem = '';
}
}
}
});
var app = new Vue({
el: '#vue-app'
});
However, I need to import stuff like axios and other components
if I add an import statement to the script above, it comes up with
import axios from "axios";
Uncaught SyntaxError: Unexpected identifier
Where should my imports go?
Since you are directly writing code running in the browser, you can simply include the axios cdn in your html code before search.js is loaded:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
As for components import, you can read more about component registration here. Generally if your components are registered globally via Vue.component('my-component', {}) syntax, you should be able to directly use it within your code.
You're missing axios library so add it as follow :
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
i'm also providing you of how to use it when you work with browser :
new Vue({
el: '#app',
data: {
dataReceived: '',
},
methods: {
getData() {
axios.get('https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD')
.then((response) => {
this.dataReceived = response.data;
console.log(this.dataReceived);
return this.dataReceived;
})
}
}
})
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/vue#2.5.17/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<button #click="getData" type="button">getData</button>
<p>dataReceived: {{ dataReceived }}</p>
</div>
</body>

Vue.js import images

So I am making an app with a control panel and i want to be able to change a few images inside the app dynamically and my problem is, it just won't work
This is the div I am trying to change
<div class="bg-image bg-parallax overlay" :style="`background-image:url(${bg1url})`"></div>
this is the script part of the Home.vue file
<script>
import axios from 'axios';
export default {
name: 'Home', // this is the name of the component
data () {
return{
page_data: {},
bg1url: null,
};
},
created() {
axios.get("http://localhost:5001/api/v1/pages")
.then((result) => {this.page_data = result.data.page_data});
this.bg1url = require('#/assets/img/' + this.page_data.background1);
alert(page_data.background1);
},
};
</script>
I have tried most of the suggestions on stack overflow but nothing seems to work.
I use the default webpack configurations and generated structure
Note: the parts with axios fetching from the backend work correctly. The only problem is adding the image to the style.
I think could be because you are setting the value for bg1url outsite of promise (calback function of axios), and so this make the code sync and not async
so please try to update, use this instead
created() {
axios.get("http://localhost:5001/api/v1/pages").then(result => {
this.page_data = result.data.page_data
this.bg1url = require('#/assets/img/' + this.page_data.background1);
});
},

Vue - access data in component outside of Vue - Single file component

How to access and change data of compontent out side the component and Vue instance but inside single-file-component?
Component in sigle file like:
<script>
export default {
data() {
return {
lock: true,
connection: '',
login: true,
message: {
time: '',
nick: '',
.......................
The file is chat.vue
Main Vue app:
var app = new Vue({
el: '.app',
components: {
Chat
}
});
And I need to access and example data from something like
Socket.onopen = function(e)
{
Chat.connection = 'Zostałeś połączony pomyślnie!';
Chat.lock = false;
};
Outside of component but in this component file
tried something like
Chat.message.nick = 'xxxx'; but doesn't work
this.message.nick = 'xxx'; doesn't work too + I got error: named exports are not supported in *.vue files.
var chat = export default.... doesn't work too, blowup
And many things... I don't know...
the only thing I worked out is to use ref="Chat" on component in HTML. But it is not what I want, it allows me to reference my component's data but in not in this component vue single file but in my main js file
I need to reference data and change it in this compontent vue single file

Categories

Resources