How to trigger Vue.js method from external JavaScript - javascript

I am trying to trigger a Vue.js method from a function that is in another JavaScript file. I have given the below code which I have tried.
sample.js
import vm from './vue.js';
function call( ) {
vm.$options.methods.displayData('I was called externally!')
}
call() // Here I am calling function
vue.js
var vm = new Vue({
el: '#app',
data: {
firstname : '' ,
lastname : ''
},
methods:{
displayData: function(s ) {
alert(s)
}
}
})

You don't need to access the $options object:
vm.displayData('I was called externally!')
This is simply using the instance to access its methods.
Edit for your comments below: To use the files without a bundler or es6 modules as you want, remove the import statement which is only for modules.
Here are the 3 complete files you would need for index.html, vue.js, sample.js:
index.html
<html>
<body>
<div id="app"></div>
<script src="https://unpkg.com/vue#2.6.12/dist/vue.js"></script>
<script src="vue.js"></script>
<script src="sample.js"></script>
</body>
</html>
vue.js
const vm = new Vue({
el: '#app',
data: () => ({
firstname : '',
lastname : ''
}),
methods:{
displayData: function(s) {
alert(s)
}
}
})
sample.js
function call( ) {
vm.displayData('I was called externally!')
}
call();

Related

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>

Laravel and VueJS, access Vue instance.

I want to change a data property and run a method on my Vue instance within Laravel. However due to using webpack and laravel I can't seem to access the instance how I would expect to:
So window.app doesn't appear to be the correct instance of my Vue class.
Below is the Blade View i'm loading, as you can see I append a script tag to my main layout.blade.php, simply trying to change the Vue instance data property, and run a method.
#push('scripts')
<script>
app.unsaved = true;
app.triggerEvent(null, 'models', null);
</script>
#endpush
Below is part of my app.js (resources/assets/js/app.js):
const app = new Vue({
el: '#app',
components: {
'models-select': ModelsSelect
},
data: {
showModel: false,
unsaved: false
},
mounted: function() {
let _self = this;
(function() {
document.querySelectorAll("input, textarea, select").forEach(function(e) {
e.addEventListener('change', function() {
_self.unsaved = true;
e.classList.add('is-changed');
});
});
function unloadPage(){
if (_self.unsaved) return 'You appear to have un-saved changes!';
}
window.onbeforeunload = unloadPage;
})();
},
methods: {
triggerEvent: function(event, target, property)
{
app.$refs[target].update(event, property);
}
As you can see i'd expect to manipulate the Vue instance through the global app variable I have defined within the app.js. However this doesn't appear to be the case.
I get the following error when running the triggerEvent method:
app.triggerEvent is not a function
In your app.js file, change const app = new Vue({ to window.app = new Vue({.
Then within your <script> tags, change it to this.
<script>
window.app.unsaved = true;
window.app.triggerEvent(null, 'models', null);
</script>

Can't get Firebase data to display on simple Vue app

I'm trying to get a simple Vue+Firebase app running that allows you to send strings to the firebase database and have the messages be displayed using the "v-for" directive. However, I keep getting the error
Property or method "messages" is not defined on the instance but referenced during render
even though I'm pretty sure I'm using the correct syntax based on Vue's example on their site and the Vuefire github page to link up messages to the database. I can push to the database just fine, but for some reason I can't read the data from the database. I've been unable to get this to work for about a day and at this point any help is appreciated.
Here is my code for reference:
index.html:
<head>
<script src="https://www.gstatic.com/firebasejs/5.2.0/firebase.js"></script>
<script>
// Initialize Firebase
var config = { ... };
firebase.initializeApp(config);
</script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="message" placeholder="Type a message!">
<button v-on:click="sendData">Send Data</button>
<br>
<h3 v-for="msg in messages">{{msg.value}}</h3>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
app.js:
var messageRef = firebase.database().ref('local/responses');
var app = new Vue({
el: '#app',
data: function () {
return {
message: ''
}
},
firebase: function () {
return {
messages: messageRef
}
},
methods: {
sendData: function () {
messageRef.push(this.message);
this.message = '';
}
}
});
You need to include the messages property in both the firestore return function as a database reference, as well as the data return function as an empty array for the database to bind to, as such.
var app = new Vue({
el: '#app',
data: function () {
return {
message: '',
messages: []
}
},
firebase: function () {
return {
messages: firebase.database().ref('local/responses')
}
},
methods: {
sendData: function () {
messageRef.push(this.message);
this.message = '';
}
}
});
This happens because you're trying to bind the Firestore reference to a piece of data that doesn't exist within your Vue instance, it needs that empty array for it to bind to the data property.

How to call functions declared out of a Vuejs instance?

This is a pseudocode to illustrate my question. When the script is run, it will encounter the error func1 is not defined. How can I go about this?
app.js
require ('./helper');
new Vue ({
el: "#app",
created: function () {
func1()
}
});
helper.js
module.exports = function () {
$.notify('Hi', {
position: "bottom right",
className: "success"
});
};
Thanks in advance!
You might have to save the imported function to a variable in your app.js file. It depends on what bundler you use (e.g. browserify or webpack or else). Functions declared outside of the parameter object you are passing to Vue should be accessible:
// app.js
var func1 = require('./helper');
new Vue ({
el: "#app",
created: function () {
func1();
}
});
In your helpers.js, you need a reference to jQuery. You can either include the library (jQuery and $ will be available globally on the window object) or like in the example below, install it from https://www.npmjs.com/package/jquery and bundle it with your own code.
// helper.js
var $ = require('jquery');
module.exports = function () {
$.notify('Hi', {
position: "bottom right",
className: "success"
});
};
If you want to call this function in more than one component's created method, you can create a mixin, which then will be passed to specific component.
//YourMixin.js
new Vue({
created: function () { ... }
})
//Component
let mixin = require('YourMixin')
new Vue({
mixins: [mixin],
...
})

Vue.js: access global value in template string

I have a very basic Vue.js app that looks like this:
index.html (just the <body> for succinctness)
<div id="root"></div>
main.js
var config = {
title: 'My App',
}
new Vue({
el: '#root',
template: '<div>{{ config.title }}</div>',
})
This gives me:
Property or method "config" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
(found in root instance)
I'm guessing it's because Vue is looking for it in the data store rather than window. Is there some way to signal that config is a global here, or a better way to do this entirely? I suppose I could pass the config object as a prop to my root Vue instance, but it seems like only components accept props. Thanks for any insights on this.
You can try to define your app as follows:
new Vue({
el: '#root',
template: '<div>{{ config.title }}</div>',
data: function() {
return {
config: window.config
}
}
})
In the above definition, your this.config within the root component points to window.config - the global variable.
If you are just trying to pass the App Name in as a hard-coded string you can do something like this:
var nameMyApp = new Vue({
el: '#root',
data: { input: 'My App' },
computed: {
whosapp: function () {
return this.input
}
}
})
With your html like this:
<div id="root">
<div v-html="whosapp"></div>
</div>
Which will pass the value of input to the whosapp div.
But, if you're looking for something more dynamic, this would be the way to go:
With the same html as above...
var nameMyApp = new Vue({
el: '#root',
data: { input: 'My App' },
The initial value is set to My App, which is what will display if not changed through a function call on the method.
methods: {
update: function(name) {
this.input = name;
}
},
Here is where we define a method that, when called, passes in the parameter to update this.input.
computed: {
whosapp: function () {
return this.input
}
}
})
nameMyApp.update("New Name");
And here is where we call the function, giving it the new parameter; making sure that the parameter is a string.
I hope this is what you're looking for.

Categories

Resources