Import a javascript file in Vue compoment - javascript

I'm building a project using Laravel and vue js and I needed to import a js package name ( photojshop ) ", which enable to edit an image filter or color " in my vue component.
I tried this way :
<template>
<img src=".." id="myImg" >
</templete>
<script>
import $ from 'jquery'
export default {enter code here
data: () => ({
......data of your component
}),
mounted() {
let recaptchaScript = document.createElement('script')
recaptchaScript.setAttribute('src', 'my local js file')
document.head.appendChild(recaptchaScript)
},
methods: {
EditImage(){
$('myImg').photoJshop({ .... }) (error)
}
}
}
</script>
but when I call the function $('..').photoJshop({}) an error occur function is not defined (photoJshop)

My problem is solved i just needed to write my code in
this.$nextTick(function () {
....
})
so that

Related

How to dynamically import CKEditor in Vue.js 3 only on client-side?

I am trying to include CKEditor 5 in my Vue.js 3 app but am struggling with including it only on client-side. I am using server-side rendering which cannot handle window that CKEditor uses, so it must only load only if the browser requests it, and not Node.js.
In the setup() method I can test for IsBrowser like this:
const IsBrowser = typeof window !== 'undefined';
How can I perform import and initialise a component only if IsBrowser is true?
I have to do the following code to make CKEditor-5 work:
<CKEditor v-if="IsBrowser" id="PostContent" class="ck-content" contenteditable="true" :editor="CKEditorInline" ></CKEditor>
<script>
import CKEditor from '#ckeditor/ckeditor5-vue/dist/ckeditor'
import CKEditorInline from '#ckeditor/ckeditor5-editor-inline/src/inlineeditor';
export default {
name: "ComponentCreate",
components: {
CKEditor: CKEditor.component
},
data() {
return {
CKEditorInline: CKEditorInline,
</script>
TLDR
Working solution (explanation is below):
<CKEditor v-if="IsBrowser && CKEditorInline"
id="PostContent"
class="ck-content"
contenteditable="true"
:editor="CKEditorInline"
></CKEditor>
<script>
import { ref, defineAsyncComponent } from 'vue';
export default {
name: "ComponentCreate",
components: {
CKEditor: defineAsyncComponent(() => {
return import('#ckeditor/ckeditor5-vue/dist/ckeditor')
.then(module => module.component)
})
},
setup() {
const IsBrowser = typeof window !== 'undefined';
let CKEditorInline = ref(null);
if (IsBrowser) {
import('#ckeditor/ckeditor5-editor-inline/src/inlineeditor')
.then(e => CKEditorInline.value = e.default)
}
return { IsBrowser, CKEditorInline }
},
};
</script>
There are two challenges here:
Conditionally load the <CKEditor> component
Conditionally load the CKEditorInline module's export
Conditionally Load <CKEditor> component
Use defineAsyncComponent to lazy load and register the component. It only loads and registers if the template actually renders it. So only when the v-if is true.
components: {
CKEditor: defineAsyncComponent(() => {
return import('#ckeditor/ckeditor5-vue/dist/ckeditor')
.then(module => module.component)
})
},
Extra challenge, not the module but the component property is needed in your case
Conditionally load CKEditorInline module export
For this dynamic module, we want the default export
let CKEditorInline = ref(null);
if (IsBrowser) {
import('#ckeditor/ckeditor5-editor-inline/src/inlineeditor')
.then(e => CKEditorInline.value = e.default)
}
Change the v-if condition
<CKEditor v-if="IsBrowser && CKEditorInline" :editor="CKEditorInline"></CKEditor>

Run a Script in React JS/TSX file

I have a ReactJs file, Component.js and I want to execute a Script which looks like this:
<script type='text/javascript'>
window.onAmazonLoginReady = function() {
amazon.Login.setClientId('CLIENT-ID');
};
window.onAmazonPaymentsReady = function() {
//Will also add this button implementation method
showButton();
};
</script>
I want to include this Script in Component.js file, but couldn't think of any way. I had included this in index.js/index.html but I want the above script to be executed when the Component.js file loads.
This is my component.js file:
import React, { useContext, Component } from 'react';
import { Link } from 'react-router-dom';
const Component = () => {
return (
<div> Hello from Component </div>
);
};
export default Component;
You can just add the script inside the useEffect of the Component.js file like this :
useEffect(() => {
const setLoginClientId = () => {
amazon.Login.setClientId('CLIENT-ID');
};
// If this "onAmazonLoginReady" is a javascript event then you should add like this
// window.addEventListener("onAmazonLoginReady",setLoginClientId);
window.onAmazonLoginReady = setLoginClientId;
// Removed the unncessary function inside function,
// you can directly call showButton now
window.onAmazonPaymentsReady = showButton;
//Calling Set Client Id once, if you want
setLoginClientId();
},[]);
This will only run one time just after the Component loads.

Vue js import components dynamically

I have the following parent component which has to render a list of dynamic children components:
<template>
<div>
<div v-for="(componentName, index) in supportedComponents" :key="index">
<component v-bind:is="componentName"></component>
</div>
</div>
</template>
<script>
const Component1 = () => import("/components/Component1.vue");
const Component2 = () => import("/components/Component2.vue");
export default {
name: "parentComponent",
components: {
Component1,
Component2
},
props: {
supportedComponents: {
type: Array,
required: true
}
}
};
</script>
The supportedComponents property is a list of component names which I want to render in the parent conponent.
In order to use the children components in the parent I have to import them and register them.
But the only way to do this is to hard code the import paths of the components:
const Component1 = () => import("/components/Component1.vue");
const Component2 = () => import("/components/Component2.vue");
And then register them like this:
components: {
Component1,
Component2
}
I want to keep my parentComponent as generic as possible. This means I have to find a way to avoid hard coded components paths on import statements and registering. I want to inject into the parentComponent what children components it should import and render.
Is this possible in Vue? If yes, then how?
You can load the components inside the created lifecycle and register them according to your array property:
<template>
<div>
<div v-for="(componentName, index) in supportedComponents" :key="index">
<component :is="componentName"></component>
</div>
</div>
</template>
<script>
export default {
name: "parentComponent",
components: {},
props: {
supportedComponents: {
type: Array,
required: true
}
},
created () {
for(let c=0; c<this.supportedComponents.length; c++) {
let componentName = this.supportedComponents[c];
this.$options.components[componentName] = () => import('./' + componentName + '.vue');
}
}
};
</script>
Works pretty well
Here's a working code, just make sure you have some string inside your dynamic import otherwise you'll get "module not found"
<component :is="current" />
export default {  data () {
    return {
      componentToDisplay: null
    }
  },
  computed: {
    current () {
      if (this.componentToDisplay) {
        return () => import('#/components/notices/' + this.componentToDisplay)
      }
      return () => import('#/components/notices/LoadingNotice.vue')
    }
  },
  mounted () {
    this.componentToDisplay = 'Notice' + this.$route.query.id + '.vue'
  }
}
Resolving dynamic webpack import() at runtime
You can dynamically set the path of your import() function to load different components depending on component state.
<template>
<component :is="myComponent" />
</template>
<script>
export default {
props: {
component: String,
},
data() {
return {
myComponent: '',
};
},
computed: {
loader() {
return () => import(`../components/${this.component}`);
},
},
created() {
this.loader().then(res => {
// components can be defined as a function that returns a promise;
this.myComponent = () => this.loader();
},
},
}
</script>
Note: JavaScript is compiled by your browser right before it runs. This has nothing to do with how webpack imports are resolved.
I think we need some plugin that can have code and every time it should load automatically. This solution is working for me.
import { App, defineAsyncComponent } from 'vue'
const componentList = ['Button', 'Card']
export const registerComponents = async (app: App): void => {
// import.meta.globEager('../components/Base/*.vue')
componentList.forEach(async (component) => {
const asyncComponent = defineAsyncComponent(
() => import(`../components/Base/${component}.vue`)
)
app.component(component, asyncComponent)
})
}
you can also try glob that also work pretty well but I have checked it for this solution but check this out worth reading
Dynamic import
[Update]
I tried same with import.meta.globEage and it works only issue its little bit lazy loaded you may feel it loading slow but isn't noticeable much.
import { App, defineAsyncComponent } from 'vue'
export const registerComponents = async (app: App): void => {
Object.keys(import.meta.globEager('../components/Base/*.vue')).forEach(
async (component) => {
const asyncComponent = defineAsyncComponent(
() => import(/* #vite-ignore */ component)
)
app.component(
(component && component.split('/').pop()?.split('.')[0]) || '',asyncComponent
)
})
}

close bootstrap modal in react-redux programmatically using jquery

trust we all doing great...I am currently building a react application also making use of redux, I am having an issue trying to close modal in bootstarp programmatically, I am using bootstrap 4, and jquery 3.3.1... I have tried this:
onSubmit(event) {
event.preventDefault();
this.props.editBusinessAction(this.props.id, this.state)
.then((message) => {
$('#modal').modal(hide)
toastrOption();
toastr.success(message);
})
.catch((message) => {
toastrOption();
toastr.error(message);
console.log(message);
});
}
Try putting hide in quotes like this:
onSubmit(event) {
event.preventDefault();
this.props.editBusinessAction(this.props.id, this.state)
.then((message) => {
$('#modal').modal('hide')
toastrOption();
toastr.success(message);
})
.catch((message) => {
toastrOption();
toastr.error(message);
console.log(message);
});
}
$('#modal').modal('hide') this works only when you import jquery and bootstrap in your entry component.
install jquery and bootstrap and import jquery in your starting component eg: App.js like below
npm install -s jquery#2.2.3 bootstrap#3.3.6
App.js
import 'jquery';
import 'bootstrap/dist/js/bootstrap';
import 'bootstrap/dist/css/bootstrap.css';
export default class extends Component {
render(){
return (
<div>App component</App>
)
}
}

Vue-loader dynamic list of components

I am quite new to Vue.js and got stuck at a problem that shouldn't be too hard to solve: I have a single file component (.vue) that is supposed to view/manage a dynamic list of another single file component via JS.
My approach is this:
<script>
import Event from './DayView/Event'
export default {
components: {
Event
},
props: ['day']
}
const $ = window.$ = require('jquery')
$(document).ready(function () {
$('#day-view').append(new Event())
})
</script>
This results in the following error:
Uncaught TypeError: __WEBPACK_IMPORTED_MODULE_0__DayView_Event___default.a is not a constructor
Thanks in advance.
I found a solution for my problem (which isn't neccessarily mounting new objects). As DayView is supposed to view a list of Events, using a list of objects combined with v-for did the trick for me:
<template>
<div id="day-view">
[...]
<event v-for="event in events" :event="event"></event>
</div>
</template>
<script>
import Event from './DayView/Event'
let events = []
export default {
components: {
Event
},
data () {
return {
events: events
}
}
}
const $ = window.$ = require('jquery')
$(document).ready(function () {
events.push({start: '540', end: '630'})
})
</script>
See https://v2.vuejs.org/v2/api/
<template><div><event /></div></template>
<script>
import Event from './DayView/Event'
export default {
components: {
Event
},
props: ['day']
}
</script>

Categories

Resources