How to add external script to vue component? - javascript

I need your help very much...
I have a Vue component and endpoint which gives me a script with a small menu and that script includes some actions.
So, after my script is loaded its actions don't work on a page and I don't know why.
Below the example code:
<template>
<div id="menu"></div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
mounted () {
// here I get a script which contains menu bar with actions
// css and styles
this.$http.get("https://endpointwithscript.com/menu").then(response => {
if (response.status === 200) {
//in that case script doesn't work. Eg click
var div = document.getElementById("menu")
div.innerHTML += response.body;
document.appendChild(div);
}
})
}
}
</script>
If I insert my downloaded script that way :
mounted () {
this.$http.get("https://endpointwithscript.com/menu").then(response => {
if (response.status === 200) {
document.write(response.body);
}
})
}
then script works but another html elements are overridden by that script and not displayed.
How to download script, insert it on a page and keep all functionality ?
Thank you!

You can try adding your external script into Mounted()
mounted() {
let yourScript= document.createElement('script')
yourScript.setAttribute('src', 'https://endpointwithscript.com/menu')
document.head.appendChild(yourScript)
},

<div class="menu"></div>
var div = document.getElementById("menu")
You are grabbing the element by ID, but gave it a class instead. Change the div to be <div id="menu"></div>

You could use v-html to include HTML-Code into a specific tag.
It seems the only way to implement a working script is by defining a new script element.
This worked for me here
https://jsfiddle.net/nh475cq2/
new Vue({
el: "#app",
mounted () {
this.$http.get("https://gist.githubusercontent.com/blurrryy/8f7e9b6a74d1455b23989a7d5b094f3f/raw/921937ea99ff233dfc78add22e18868b32cd11c0/Test").then(res => {
if(res.status === 200) {
let scr = document.createElement('script');
scr.innerHTML = res.body;
document.body.appendChild(scr);
}
})
}
})

Related

Vue3 Display PDF Document

I can grab images and display them in a browser using them as a bytearray without any problem. In Normal C# I was also able to do this with PDFs very easily by inserting this bytearray as an but now in Vue3 I am having troubles doing this same thing I've done in the past. What is a simple way to display a PDF document In browser with Vuejs?
This is how I've done in in the past,
I am open to suggestions and a better way to do this.
This will be hosted and be shown on a big screen TV so the department can view the document and it will flash to other ones as well.
<div v-if="byteArrayPDF" class="content">
<object data="byteArrayPDF" type="application/pdf" style="height:700px;width:1100px;"></object>
</div>
</div>
</template>
<script lang="js">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
loading: false,
byteArrayPDF: null
};
},
created() {
this.fetchByteArray();
},
methods: {
fetchByteArray() {
this.byteArrayPDF = true;
this.loading = null;
fetch('https://localhost:5001/api/Doc/Virtual-Visual-Service-2020.pdf')
.then(response => response.json())
.then(bytespdf => {
this.byteArrayPDF = "data:application/pdf;base64," + bytespdf;
this.loading = false;
return;
})
.catch(console.log("Error PDF View"));
}
From what you said in your question, I think you want to load a pdf file in for example a "vue component". If that is right, you can use a code like the code below:
<template>
<div v-if="byteArrayPDF">
<iframe :src="srcData" width="100%" height="500px">
</iframe>
</div>
<div v-else>
loading...
</div>
</template>
<script>
export default {
name: "CompoPdf",
data() {
return {
srcData: null,
byteArrayPDF: false,
}
},
created() {
this.fetchByteArray();
},
methods: {
fetchByteArray: async function () {
// to see the "loading..." effect, I intentionally add a "setTimeout" code. that loads the pdf after "3s". You can remove it in your real app.
await new Promise(resolve => setTimeout(resolve, 3000));
fetch('https://www.antennahouse.com/hubfs/xsl-fo-sample/pdf/basic-link-1.pdf')
.then(response => {
console.log(response);
// for this case "response.url" is what we need, but if you fetch data for example from a database ... you may need "response.json()" or other codes;
this.srcData = response.url;
this.byteArrayPDF = true;
})
}
}
}
</script>
<style scoped>
</style>
I also suggest that you read more about fetch API and CORS if you are not familiar with that topics, to better manage your request to the url you want.

React JS external script Load

I'm a beginner in React/Node.js and i got a problem on my custom shopify app dev.
i have to import, load and save an external js file on my current shoppify shop from the back.
In my react project, i could import the script via an init on button click as :
const onClick = () => {
if (typeof window !== "undefined") {
addScript({
src: `https://sdk.com/loader.js`,
id: "script",
async: "true",
onLoad: () => {
console.log("script initialized!");
},
});
}
};
But when i refresh, close and reopen, i have to re-import the script.
My question is, how can i adjust my code to save the script on my DOM.
Thank you.
You can try something like this
const onClick = () => {
const exists = document.getElementById("myScript");
if (!exists) {
const script = document.createElement("script");
script.src = "https://sdk.com/loader.js";
script.id = "myScript";
document.body.appendChild(script);
script.onload = () => {
console.log("Script loaded")
}
}
}

Calling VueJS Components after login from an external script

I have a VueJS Program where I want to provide a login. Thus this login is used one multiple platforms, it is loaded via an external server (See: mounted). It is loaded, puts elements into the mainlogin-div creating a login view and when the user clicks Login it performs a http login request to another server. When the login is successful, the external script calls done(result) or error(result) whether the login was a success or not.
But now of course how can I go back to calling Vue-stuff from there? I cant just do like this.$router.push("/coolPath") or call a defined method like loggedIn to make a toast or what not... How is this implemented?
<template>
<div id="main">
<div id="mainlogin"></div>
<script type="application/javascript">
function done(result){
console.log(result);
loggedIn(result, true)
}
function error(result) {
console.log(result)
loggedIn(result, false)
}
</script>
</div>
</template>
<script>
const Toast = require("#/toast/toast")
export default {
name: "Login",
components: {},
data() {
return {
isAuthenticated: false
}
},
beforeMount() {
let loginScript = document.createElement('script')
loginScript .setAttribute('src', 'http://**.***.***.***/index_krass.js')
document.body.appendChild(loginScript )
},
methods: {
loggedIn: function (result, success){
Toast.toast(result.message, success)
}
}
}
</script>
<style>
...
</style>
Error is always "this." is not defined or loggedIn(...) is not defined...
Maybe its some race condition where VueJS needs to be loaded first or the other way around?
Instead of the <script> block in the template, just set the global functions up on window as arrow functions to capture the Vue instance context:
export default {
beforeMount() {
window.done = result => this.loggedIn(result, true)
window.error = result => this.loggedIn(result, false)
let loginScript = document.createElement("script")
loginScript.setAttribute("src", ".../index_krass.js")
document.body.appendChild(loginScript)
},
destroyed() {
window.done = window.error = undefined
},
}
demo

VueJS / v-html shows empty page (Bokeh-html)

I am new to VueJS and I am trying to display a local html-file inside of the Vue Application.
I fetch the html file with axios like following:
<template>
<div>
<h1>bla</h1>
<div v-html="input"></div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
input: null,
}
},
created() {
this.loadFile()
},
methods: {
loadFile() {
axios({
method: "get",
url: "../../test.html"
})
.then(result => {
this.input = result.data;
console.log("Data: " + result.data)
})
.catch(error => {
console.error("error getting file: " + error);
});
},
}
}
</script>
We generate the html-Files with Bokeh (interactive Charts). If I open the html Files in the Browser they are shown correctly. These files contain
<script type="text/javascript">
and <script type="application/json">.
I tried this with a simple "Hello World"-html Example and this works fine and gets displayed in Vue. But when I read the actual file, I just get an empty page. The console.log(result.data) shows me the correct and complete html Code but I don't get any errors, so I can't figure out the problem.
Does anyone know, what I have to adjust to make this work?
Thanks !
The reason is the statement this.input = result.data tries to parse result.data as json but it is not.
Send the json from the server and use it in your code properly.
Are you doing this inside of a .vue file or is all of this in a .html file. If in html you need to remember to set the el property on your Vue model to ensure it knows where to render. If this is a .vue there has to be a defined template for the same reason.
Here is a fiddle with an example. Yes the site has issues rendering with correct layout, but it renders. This is an example for <script> tags in your html file or just a raw .js file. Looks like you were making a Vue component (.vue) but the premise is still the same as long as you define the template where the Vue code is to be rendered.
Edit:
What does your vue file look like? This is what I'm expecting.
<template id="foo">
<div v-html="input"></div>
</template>
<script>
export default {
template:'#foo',
data: {
input: null
},
created() {
this.loadFile();
},
methods: {
loadFile() {
let _this = this;
axios({
method: "get",
url: 'https://jsfiddle.net/',
})
.then(result => {
console.log(result);
_this.input = result.data;
console.log("Data: " + result.data)
})
.catch(error => {
console.error("error getting file: " + error);
});
},
}
};
</script>

Vuejs - Render raw html links to <router-link>

I;m new to VueJS and I'm making some weird experiments. I build a backend service using python/flask and this backend provide me a string of html code with many tags inside, I want to render this inside my Vue app, I have a method for calling the backend that looks like this:
async execute (method, resource, data) {
return client({
method,
url: resource,
data: data
}).then(async req => {
return req.data.html
})
},
callBack (id) {
console.log(id)
return this.execute('post', '/content/', {body: { 'id': id }})
}
And in the .vue file I have:
export default {
data () {
return {
loading: false,
launch: [],
html: 'none',
page: this.$route.params.article
}
},
beforeMount () {
console.log('beforeee')
this.html = api.callBack(this.page)
},
methods: {
async launch () {
this.launch = ''
this.html = await api.callBack(this.page)
}
}
}
so when I call the launch function it populates this.html, and this html variable lives in a v-html.Everything seems to work i get the html and render it in de container but the links are broken, the links should point at the same app something like #/test/linkvalue, but as they are tags, and in vue you have to use they doesn't work.
There is a way to achieve this "dynamic re route" or I'm doing something too weird?
The links are plenty, since they are scraped from the web, so manually parsing is not an option.
JSFiddle
Thanks in advance for your help
Also, you shouldn't return the raw html. Just return the paths for the routes and then loop the paths and create links that way.
You can use the v-html vue directive to output raw html.
https://jsfiddle.net/eywraw8t/66262/
new Vue({
el: "#app",
data: {
rawhtml: "<h1 style='color: red;'>Hi, I am raw html.</h1>"
},
methods: {
}
})
<div id="app">
<div v-html="rawhtml"></div>
</div>

Categories

Resources