Vue js - Getting Uncaught ReferenceError: jQuery is not defined - javascript

I am new to Vue.js and trying to create a custom component that uses jQuery formBuilder plugin. When I include the component file inside another component, I am getting an error:
Uncaught ReferenceError: jQuery is not defined in /resources/js/form-builder.min.js
I created a custom component with name formBuilder.vue. Here is the component code:
<template>
<div class="content">
<formBuilder/>
</div>
</template>
<script>
// import './jquery.min.js';
// import './jquery-ui.min.js';
// import './form-builder.min.js';
export default {
created() {
},
data() {
return {
}
},
mounted() {
jQuery(this.$el).formBuilder();
},
methods: {
}
}
</script>
In app.js file, which is placed in resource/js/app.js, I am calling this vue to be recursively used by other components:
window.Vue = require('vue');
require('./bootstrap');
require('admin-lte');
require('./datatable');
import router from './router';
import Datepicker from 'vuejs-datepicker';
import CKEditor from 'ckeditor4-vue';
import FullCalendar from 'vue-full-calendar';
import 'fullcalendar/dist/fullcalendar.css'
import Vue from 'vue';
import jQuery from 'jquery'
import './form-builder.min.js';
Vue.use(VueRouter)
Vue.use(FullCalendar);
Vue.use(CKEditor)
Vue.component("vue-datepicker", Datepicker);
Vue.component('FormBuilder', require('./components/tools/formBuilder.vue').default);
const app = new Vue({
el: '#app',
router
});
This is the component file where i am using formbuilder component
<template>
<div class="content-wrapper">
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0 text-dark">Questionnaire</h1>
</div>
<div class="col-sm-6"></div>
</div>
</div>
</div>
<div class="content">
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<FormBuilder/> <!--- used formbuilder component --->
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
created() {
},
data() {
return {
}
},
methods: {
}
}
</script>
I have attached the error as well.
Can you guys help me find where I am doing wrong?
Thanks in Advance.

Importing an object into Vue's app JS doesn't automatically produce that object for use by other components.
There are at least two ways to do this (though I recommend avoiding all this and just importing jQuery in the components that need it):
Option 1: Vue.prototype
In your app JS, add jQuery to the Vue prototype after you import it, which will make it accessible to every component using the syntax this.jQuery:
Vue.prototype.jQuery = jQuery
Option 2: window object
Alternatively, you could add it to the window object after importing and use it like window.jQuery:
window.jQuery = jQuery
Option 3: Individual imports
It's probably more readable/maintainable to simply import it in components that use it:
import jQuery from 'jquery'
and then you can use it with the syntax in your example.

That worked for me (Vue 3)
for some reason i had to stop the cli and restart
window.$ = window.jQuery = require('jquery');
Eslint may return "Unexpected top level property" "$". You will need to insert an exception in your package.json
"env": {
...
"jquery": true,
},
It is important to know that jquery will only be available in .vue files. Therefore, your extensions and libraries may report an error. In these cases you will have 2 options:
Transform libraries into a .vue template
Make a local import on top of them.
import jQuery from 'jquery'

Related

How to Mount Correctly an In-DOM Root Component Template

I have obviously a misconception of how the vue3 "In-DOM Root Component Template"-mechanism is working. Any hints appreciated!
I modified an example vite project to use "In-DOM Root Component Template".
index.html
<body>
<div id="app">
<div>
<a href="https://vitejs.dev" target="_blank">
<img src="/vite.svg" class="logo" alt="Vite logo" />
</a>
</div>
<hello-world msg="Vite + Vue"></hello-world>
</div>
<script type="module" src="/src/main.js"></script>
</body>
main.js
import { createApp } from 'vue'
import './style.css'
import HelloWorld from './components/HelloWorld.vue'
const app = createApp({})
app.component('HelloWorld',HelloWorld)
app.mount('#app')
HelloWorld is the default example component, installed by vite install.
Result: The rendered output is empty, the div#app-innerHtml is not used as Template as expected.
I had an js error here const app = createApp()
Error: Cannot read properties of undefined (reading 'render').
Vue Options should not be undefined. Please replace it with:
const app = createApp({})
You register you component in PascalCase as HelloWorld and use it the same way in HTML. But you should use kebab-case <hello-world>.
There is an explanation in the Vue Docs Using a Component about this:
If you are authoring your templates directly in a DOM (e.g. as the
content of a native element), the template will be subject
to the browser's native HTML parsing behavior. In such cases, you will
need to use kebab-case and explicit closing tags for components
Please pay attention to the explicit closing tags also.
The app works When you fix both problems. Here is the working playground
https://stackblitz.com/edit/vue-n2v2y4?file=public/index.html

TinyMCE not loaded in vue component

I'm trying to integrate tinymce in my vue app. I don't want to use the cloud version and I've installed it inside my app suing this commend npm i tinymce.
After the setup into my component I've imported the needed files in this way and I created a textarea into the template
<template>
<Navbar></Navbar>
<div class="container" id="editorWrapper">
<div class="row mt-5 pt-5 m-0">
<!-- -->
<div class="col-sm-12 col-md-12 col-lg-12 p-0" id="">
<h1>Write post</h1>
</div>
<!-- -->
<div class="col-sm-12 col-md-12 col-lg-12 p-0" id="programEditorWrapper">
<textarea ref="programEditor" id="programEditor"></textarea>
</div>
</div>
</div>
</template>
<script>
import tinymce from 'tinymce'
import 'tinymce/themes/silver'
import 'tinymce/skins/ui/oxide/skin.css'
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/code'
import 'tinymce/plugins/emoticons'
import 'tinymce/plugins/emoticons/js/emojis'
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/table'
import contentUiCss from 'tinymce/skins/ui/oxide/content.css'
import contentCss from 'tinymce/skins/content/default/content.css'
export default {
name: 'ProgramsEditor',
components: {
Navbar
},
data() {
return {
editor: null
}
},
created() {
},
mounted() {
this.initEditor()
},
methods: {
initEditor() {
this.editor = tinymce.init({
selector: '#programEditor',
plugins: 'advlist code emoticons link lists table',
toolbar: 'bold italic | bullist numlist | link emoticons',
skin: false,
content_css: false,
content_style: contentUiCss.toString() + '\n' + contentCss.toString()
})
},
}
}
</script>
Unfortunately I'm not able to see the editor and I get two errors
How I can fix this problem and let the editor work?
Based on the error message and the code snippet provided, you've missed importing some critical files that TinyMCE uses, as such its trying to load the external JS files which don't appear to exist or are being served as HTML files (potentially a 404 page).
I'd suggest reviewing the TinyMCE bundling docs further, which hold the answer here: https://www.tiny.cloud/docs/tinymce/6/introduction-to-bundling-tinymce/. So in this case, to solve the 2 errors you're getting that should be able to be resolved by importing the model and default icon pack alongside the theme:
import tinymce from 'tinymce'
import 'tinymce/icons/default';
import 'tinymce/themes/silver';
import 'tinymce/models/dom';
Basically, TinyMCE at the very minimum needs the core, theme, skin, default icon pack and model to be able to operate (Note: the model is new in TinyMCE 6 and wasn't needed before that). If any of those are missed then it will fail to initialize.
Additionally, you could use the official Vue integration guide.
After installation.
Simple input the core packages:
You need both the core tinymce package and tinymce-vue installed.
import "tinymce/tinymce";
import "tinymce/themes/silver";
import "tinymce/icons/default";
import "tinymce/skins/ui/oxide/skin.css";
import <Your component name here> from "#tinymce/tinymce-vue";
And use it as a normal Vue component.

How to you use vue js for certain Laravel Routes and blade for other routes?

I have tried searching up for this but can't seem to find an answer for this. It seems to point to if you are going to use blade then all your views must be in blade whereas if you are going to continue using vue js for your front end then every view must be in Vue.
So my question is can I use vue js for certain routes and blade for certain routes?
For an example , let's say if I have '/login' route and I would like to use Vue js for this route's front end and for '/about' route, I would like to use Laravel's blade for it's front end. Is this possible?
If yes, how to do it ?
Thank you.
Yes, create Vue components and call them from within the blade template:-
ExampleComponent.vue:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
example.blade.php:
#extends('layouts.app')
#section('content')
<example-component></example-component>
#endsection
Thanks #chris for the answer, however I would like to extend this answer .
Let's say if you want to register a for a new component which is in resources/js/components/AboutComponent.vue
Step 1 : Register route in web.php
Route::get('contact', 'TestController#contact')->middleware('auth');
Step 2 : Create controller and point to blade
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function contact()
{
return view('testing.contact');
}
}
//Step 3 : Create vue component in resources/js/components/ContactComponent.vue
<template>
<div class="col-md-12">
<p>Brought to you by Evan You</p>
</div>
</template>
<script>
export default {
data() {
return {
}
} ,
mounted() {
console.log('Contact Component mounted.')
}
}
</script>
//Step 4 Register Vue Component in resources/js/app.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
/**
* The following block of code may be used to automatically register your
* Vue components. It will recursively scan this directory for the Vue
* components and automatically register them with their "basename".
*
* Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
*/
// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('contact-component', require('./components/ContactComponent.vue').default);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app',
});
// Step 5 Use this component in contact.blade.php which is located in resources/views/testing/contact.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<h2>From the vue component</h2>
{{-- This is the vue component that we registered in app.js --}}
<contact-component></contact-component>
</div>
<div class="container">
<div class="col-md-12">
<h2>From the blade component</h2>
<p>Brought to you by Taylor Otwell</p>
</div>
</div>
#endsection
//Step 6 Don't forget to run npm run watch
Result:

Using a component containing other components within a router-view in Vue.js

I am trying to build a layout using single-file components in Vue.js, with dynamic population and URLs using Vue-router. (I'm using the webpack template via vue-cli as well.)
It works as expected for my app.vue file-- containing the nav, sidebar, page head, and <router-view>-- and the <router-view> content appeared as expected when the correct <router-link> is clicked... until I tried to add subcomponents to the add-load component being called to the <router-view>. Now, nothing appears at all, despite not throwing any errors.
Admittedly, I am not basing my structure on any examples, as I couldn't really find any doing it the way I was hoping to. I wanted to use nested components by calling them like custom elements-- I think this makes the code much easier to read and maintain. I'm not entirely sure how to structure it otherwise, to be honest. Using multiple <router-view>s as siblings to each other seems counterintuitive to me.
I've tried a variety of combinations of how and where to import and call the components, and nothing has worked. The only way I can get any content to load is if I only call a single component for path: '/add-load'. Is it just impossible to use multiple components outside of your base app.vue? I find that hard to believe. Here's what I started with.
From my index.js:
import AddLoad from '#/components/AddLoad'
import AddLoad from '#/components/ProgressSteps'
import Stops from '#/components/Stops'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
components: {
Sidebar,
TopNav,
MobNav,
PageHead
}
},
{
path: '/add-load',
components: {
AddLoad,
ProgressSteps}
}
]
})
From my App.vue file (the multiple component behavior that I'd like to mimic is shown here):
<template>
<div id="app">
<div class="wrapper">
<Sidebar/>
<div class="container-fluid">
<TopNav/>
<MobNav/>
<div class="container-fluid">
<PageHead/>
<router-view></router-view>
</div>
</div>
</div>
</div>
</template>
<script>
import Sidebar from '#/components/Sidebar'
import TopNav from '#/components/TopNav'
import MobNav from '#/components/MobNav'
import PageHead from '#/components/PageHead'
export default {
name: 'App',
components: {
Sidebar,
TopNav,
MobNav,
PageHead
}
}
</script>
From my AddLoad.vue file:
<template>
<div class="add-load">
<div class="content-container container-slim">
<progress-steps/>
<router-link to="#stops">Stops</router-link>
<router-view></router-view>
</div>
</div>
</template>
<script>
import ProgressSteps from '#/components/ProgressSteps'
export default {
name: 'AddLoad',
component: ProgressSteps
}
</script>
Here is a link to a codesandbox, so you can see the full functionality. https://codesandbox.io/s/7k520xk0yq

How to import a component in Vuejs 2

I'm really confused about importing a VueJs component.
I'm using Vuejs 2.2.4, and I need to import a Vuejs component. Here is my app.js:
Vue.component('Test', require('./Test.vue'));
const app = new Vue({
el: '#vue-app',
});
Assume app.js is located in MyProject/js/app.js
And here is my component SimpleCompnent.vue :
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Simple Component</div>
<div class="panel-body">
I'm an Simple component!
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Simple Component mounted.')
}
}
</script>
Assume SimpleCompnent.vue is located in MyProject/js/SimpleCompnent.vue
Seems like Vue can't load the component! It throws this error in the browser console:
Uncaught ReferenceError: require is not defined
Indeed, require cannot be used in a browser context without proper support, so you have couple of options:
Create (or fix) support for require.js in your app (see how here). As a first step, make sure you have a script tag that fetches require.js and has a data-main attribute that points to your app's entrypoint.
Use a CommonJS implementation for the client, like webpack or browserify, so requires can be written naturally in client-side code.
Use another module system implementation, e.g. on top of system.js or ES2015.
Either way, if you chose an implementation that uses imports (i.e. an ES2015 module system), you may want to use a transpiler that down-compiles your code to a language level the browser supports (avoiding those nasty Unexpected token import errors).
Try:
import Test from './Test.vue'
You can see an example of it here.

Categories

Resources