Using Global module object within Vue instance methods - javascript

I'm trying to create a global object I can use in Vue but having trouble accessing the methods. I want to use these methods in different components. Also, what's the best approach. I heard about using Mixins but I was thinking about trying a basic javascript object. I hope I'm asking this question the right way.
src/myobject.js
exports.myObj = () => {
function testMethod() {
console.log('working');
}
}
src/main.js
import Vue from 'vue'
import App from './App'
import { store } from './store/store'
import { myObj } from './myobject'
Vue.config.productionTip = false
myObj.testMethod() // NOT WORKING - TypeError: __WEBPACK_IMPORTED_MODULE_3_
/* eslint-disable no-new */
new Vue({
el: '#app',
store: store,
components: { App },
template: '<App/>'
})
src/components/App.vue
<template>
<div id="app">
<img src="./assets/logo.png">
</div>
</template>
<script>
export default {
name: 'App',
mounted: function () {
myObj.testMethod() // NOT WORKING
},
components: {
}
}
</script>
<style>
body {
margin: 0;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
</style>

To create a simple ES module that exports both named functions and a default object, you can define it like this:
export function testMethod() {
console.log('working');
}
export function otherMethod() {
console.log('other method');
}
// optionally export a default object
export default {
testMethod,
otherMethod
}
Then, it will be possible to import it:
import { testMethod } from './myobject';
// or import the default export
import myObj from './myobject';
myObj.testMethod();
Now, to use it in your Vue components, there are multiple ways which I already explained in another answer. Using Vue mixins is one way (beware of global mixins) and writing a plugin is another way.
In your case, it could be a simple mixin:
// my-mixin.js
import { testMethod } from './myobject';
export default {
mounted() {
testMethod();
}
}
Hook functions with the same name are merged into an array so that all of them will be called.
<script>
// components/App.vue
import MyMixin from '../my-mixin'
export default {
name: 'App',
mixins: [MyMixin],
mounted() {
console.log('both this function and the mixin one will be called');
},
components: {
}
}
</script>
The reason your code doesn't work is because you're exporting a function which does nothing. testMethod isn't exposed, it's just declared within the exported function as a local function.

Related

How do I create a function library which I can used across all my Vuejs components?

I currently writing a financial application using Vue.js and Vuetify. I have a few component files and javascript files like
Dashboard.vue
Cashflow.vue
NetWorth.vue
stores.js <- Vue Vuex
I have some functions which I need to use across all the Vue.js and javascript files. Would it be possible for me to perhaps write a function library which can be used across all
the component and js files.
function moneyFormat(num)
function IRRCalc(Cashflow)
function TimeValueMoneyCalc(I,N,PV,FV,PMT)
function PerpetualAnnuityCalc(I,PV)
function CarLoanInstallment(V,N)
function HouseLoanInstallment(V,N)
I know in C it is very simple just #include<financial.h> was wondering is there something similar in javascript.
Thanks.
There are 3 ways to do this:
1/You can create a helper.js file and import it to .vue files
// helper.js
export default {
function moneyFormat(num) { // some logic}
}
// Dashboard.vue
<script>
import helper from "helper.js" //the path may change depends on where you put the js file
methods: {
useHelper(value) {
helper.moneyFormat(value)
}
}
</script>
2/Another way is bind the function to Vue prototype
in main.js
Vue.prototype.$moneyFormat= function moneyFormat(num) {}
then in Dashboard.vue just call this.$moneyFormat(num). No need to import anything
3/ Use mixins. You can search online on how to use this https://v2.vuejs.org/v2/guide/mixins.html
You can create a single JS file that holds all the helper/util methods, and then export them individually:
export function moneyFormat(num) { ... }
export function IRRCalc(Cashflow) { ... }
export function TimeValueMoneyCalc(I,N,PV,FV,PMT) { ... }
export function PerpetualAnnuityCalc(I,PV) { ... }
export function CarLoanInstallment(V,N) { ... }
export function HouseLoanInstallment(V,N) { ... }
Then, you can simply import individual methods as of when needed, i.e.:
import { CarLoanInstallment, HouseLoanInstallment } from '/path/to/helper/file';
This can be quite usefuly for tree-shaking when you're bundling with webpack, for example, so that you don't bundle unnecessary functions that are never used in your project.
You can use Mixin
In your main.js, add Vue.mixin:
import Vue from "vue";
import App from "./App.vue";
Vue.mixin({
methods: {
helloWorld() {
alert("Hello world");
}
}
});
new Vue({
render: h => h(App)
}).$mount("#app");
and then you can call helloWorld() method from your component script with this.helloWorld() or just helloWorld() from the template.
You also can use filters if the method is to apply common text formatting
In your main.js, add Vue.filter:
import Vue from "vue";
import App from "./App.vue";
Vue.filter("capitalize", function(value) {
if (!value) return "";
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
});
new Vue({
render: h => h(App)
}).$mount("#app");
and then you can do {{ "some text" | capitalize }} to apply capitalize filter on "some text"
Example here: https://codesandbox.io/s/heuristic-dirac-esb45?file=/src/main.js:0-226

Emiting VueJS event from a JavaScript class

I'm building a simple subscription model in my Vuejs application where I'm having few difficulties in maintaining the local storage. I created a class which is responsible for storage of token/key which is required in the application.
export default class session {
constructor(STORAGE, INACTIVITY_SESSION) {
this.STORAGE = STORAGE;
this.INACTIVITY_SESSION = INACTIVITY_SESSION;
this.key = 'session-key';
}
start() {
//
}
setAll(all) {
}
getAll() {
}
renew(sessionId){
}
destroy(){
//Some code for removal of keys.
eventBus.$emit('destroyed');
}
resetTimer() {
}
}
I want that whenever destroy function is called it should call an event, and this event can be captured in my application and perform action as desired. But somehow the event is emitting. I'm having import event file:
import {eventBus} from './_events.js';
and my _event.js file has:
import Vue from 'vue';
/**
* Event bag to be used globally
*/
export const eventBus = new Vue();
This event bag is working inside any .vue file or vue-templates but not working in this session class. Moreover I'm importing class in vue application as:
import session from 'NitsModels/_session';
window.Vue = require('vue');
const sessions = new session(process.env.MIX_STORAGE_PERSIST, process.env.MIX_INACTIVITY_SESSION);
sessions.start();
//Some code for routing, vuex-store and definition of rendering component....
const layoutTwo = new Vue({
el: '#layout-three',
router: router,
store,
render:h=>h(adminLayout)
});
And I'm listening to this event inside my template component:
<template>
<div style="height: 100%;">
<div v-if="logged" style="height: 100%;">
<layout-three></layout-three>
</div>
<div v-else style="height: 100%;">
<router-view></router-view>
</div>
</div>
</template>
<script>
import {eventBus} from 'NitsModels/_events.js';
export default {
name: "admin",
data() {
return {
logged: false,
}
},
created() {
eventBus.$on('destroyed', () => {
this.$router.push({path: '/'});
this.logged = false
});
},
watch: {
'$route' (to, from) {
// react to route changes...
if(to.meta.requiresAuth && !from.meta.requiresAuth)
this.logged = true
if(!to.meta.requiresAuth && from.meta.requiresAuth)
this.logged = false
}
}
}
</script>
<style lang="scss">
</style>
Any suggestions are welcomed. Thanks.

Vue: Child string prop wont render

Hi I'm new to vue and am trying to understand its one-way data bind model component registration and passing props.
In my index.js I have my parent component in which I want to render a single child right now
import Vue from 'vue'
import StyledTitle from './components/StyledTitle'
new Vue({
el: '#app',
components: {
StyledTitle,
},
})
Child Component is StyledTitle.js
import Vue from 'vue'
import styled from 'vue-styled-components'
const StyledTitle = styled.h1`
font-size: 1.5em;
text-align: center;
color: #ff4947;
&:hover,
&:focus {
color: #f07079;
}
`
Vue.component('styled-title', {
props: ['text'],
components: {
'styled-title': StyledTitle,
},
template: `<StyledTitle>{{ text }}</StyledTitle>`,
})
export default StyledTitle
Finally my HTML is which I expect to render a red Hi
<div id="app">
<styled-title text="Hi"></styled-title>
</div>
The HI is not showing up though and the props value is undefined. Coming to this from react so wondering why this isnt working, thanks!
Ps screenshot of my vue devtools
The issue is that your StyledTitle.js file exports a normal styled <h1> component which uses a default slot for its content instead of your custom component that accepts a text prop.
If you're still keen on using a prop-based component, you need to export that instead of the one from vue-styled-components. You should avoid global component registration in this case too.
For example
// StyledTitle.js
import styled from 'vue-styled-components'
// create a styled title locally
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: #ff4947;
&:hover,
&:focus {
color: #f07079;
}
`
// now export your custom wrapper component
export default {
name: 'StyledTitle',
props: ['text'],
components: {
Title, // locally register your styled Title as "Title"
},
template: `<Title>{{ text }}</Title>`,
})
Given your component doesn't maintain any state, you could make it purely functional. Using a render function will also help, especially if your Vue runtime doesn't include the template compiler (which is the default for most Vue CLI apps)
export default {
name: 'StyledTitle',
functional: true,
props: { text: String },
render: (h, { props }) => h(Title, props.text)
}

Call function from imported helper class in Vue.js component data

I am trying to call a JavaScript function from an imported helper class in my Vue.js component. I import my helper class in my component and try to use mounted() to call it and pass a paramter to the helper class.
I tried out some solutions from here, but didn't help:
Vue.js: Import class with function and call it in child component
https://forum.vuejs.org/t/how-to-use-helper-functions-for-imported-modules-in-vuejs-vue-template/6266
This is what I tried so far, any ideas?
I have a helper class myHelper.js:
export default myHelper {
myHelperFunction(param) {
return param;
}
}
I have a Vue component MyComponent.vue:
<template>
<v-text-field :rules="[myRule]"></v-text-field>
</template>
<script>
import myHelper from './myHelper.js';
export default {
name: 'MyComponent',
data() {
return {
myCls: new myHelper(),
myRule: this.callHelperFunction,
};
},
components: {
myHelper,
},
mounted() {
this.myCls.myHelperFunction();
},
methods: {
callHelperFunction(param) {
this.myCls.myHelperFunction(param);
}
},
};
</script>
You are not really exporting the class. It is a plain object. To export a class instead of an object do this:
// Notice the use of class keyword
export default class MyHelper {
myHelperFunction(param) {
return param;
}
}
Also, you do not need:
components: {
myHelper,
},
Rest of the code stays the same.

How to access function inside methods of mixin from component lifecycle method in Vue.js

Here is an example :
mixin.js
export default {
methods : {
aFunction() { // Some functionality here }
}
}
component.vue
import mixin from './mixin'
export default {
mixins : [ mixin ]
created() {
// Call aFunction defined in the mixin here
}
}
I want to access the aFunction defined inside methods of mixin from the created() lifecycle method inside the component.
The mixin methods are merged with the current instance of the component, so it would just be:
created(){
this.aFunction()
}
Here is an example.
console.clear()
const mixin = {
methods:{
aFunction(){
console.log("called aFunction")
}
}
}
new Vue({
mixins:[mixin],
created(){
this.aFunction()
}
})
<script src="https://unpkg.com/vue#2.4.2"></script>

Categories