Laravel Vue.js Events not firing - javascript

Trying to use only Single File Components with Laravel. The components are mounted but events do not fire. Inside ExampleComponent I have a button #click="test" that does not fire.
It worked previously when I directly used the ExampleComponent within the blade template but after incorporating an App.vue component the events stopped.
Blade Template
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">
<!-- Styles -->
<style>
</style>
</head>
<body>
<div id="app">
</div>
<script src="{{ mix('/js/app.js') }}""></script>
<script src="/js/app.js"></script>
</body>
app.js
require('./bootstrap');
window.Vue = require('vue');
import Vue from 'vue'
import Buefy from 'buefy'
import 'buefy/dist/buefy.css'
import App from './components/App.vue'
Vue.use(Buefy)
Vue.component('navbar', require('./components/Navbar.vue'));
new Vue({
el: '#app',
template: '<App/>',
components: { App }
});
App.vue
<template>
<div id="app">
<ExampleComponent/>
</div>
</template>
<script>
import ExampleComponent from './ExampleComponent.vue'
export default {
components: {
ExampleComponent
}
}
</script>
ExampleComponent.vue
<template>
<div style="background-color: #f7faff">
<navbar></navbar>
<button #click="test">Submit</button>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
test() {
console.log("TEST")
}
},
mounted() {
console.log("Component mounted.");
}
};
</script>

Your Blade Template seems to have conflicting Javascript files that are loaded.
<script src="{{ mix('/js/app.js') }}""></script>
Should be the only script you are loading. That way, Laravel Mix can always compile the latest changes to your app.js file. See if that helps, because your .vue and .js files look wired up correctly.

I experienced a similar problem, only to find that I had made an unnecessary import in the app.js

Related

Vue component not recognised? Very basic setup. The "header" component has been registered but not used vue/no-unused-components

I'm trying to get this header component to be recognised and it just isnt. I've tried messing setting eslint to strict, and messing with my syntax to no avail. I don't get it, this should be so simple. ANy help would be appreciated.
App.vue
<template>
<div class="container">
<header />
</div>
</template>
<script>
import header from './components/header'
export default {
name: 'App',
components: {
header,
}
}
</script>
<style>
</style>
main.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
</div>
<!-- built files will be auto injected -->
</body>
</html>
header.vue
<template>
<header>
<h1>Component header</h1>
</header>
</template>
<script>
export default {
name: 'header',
};
</script>
<style>
header {
display: flex;
}
</style>
Any help would be awesome. Thankyou.
The main.jsneeds to be imported into the index.html:
<body>
<div id="app"></div>
<script type="module" src="/src/js/main.js"></script>
</body>
(using the correct path)
It is better to rename your header component to another word, because <header> is used as a standard tag name in html

Templete in App.vue doesn't show in index.html

I am using local vue.js These are my files.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="res/vue.js"></script>
<script src="res/vue-router.js"></script>
<title>Vue</title>
</head>
<body>
<div id="app" ></div>
<script type="module" src="App.js"></script>
</body>
</html>
App.js
import Vue from './res/vue.js'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div>
{{foo}}
</div>
</template>
<script>
export default {
name: 'App',
data: function(){
return{
foo:'Hello vue'
}
}
}
</script>
<style>
</style>
But my index.html shows nothing
You mount your vue instance at the div node which id is "app", but i can't find the "#app" node, so you can resolve that by insert the "#app" node .
index.html:
<body>
<div id="app"></div>
<script type="module" src="App.js"></script>
</body>
Like the Steven suggested you have to compile vue components.
If you dont want to do it that way, below is the the easiet way.
Vue.createApp({
data() {
return {
foo: 'Hello vue',
};
},
}).mount('#app');
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://unpkg.com/vue#next"></script>
<!-- <script src="res/vue-router.js"></script> -->
<title>Vue</title>
</head>
<body>
<div id="app">{{foo}}</div>
<script type="module" src="App.js"></script>
</body>
</html>
You probably need to build it with vue-cli to create a SPA(Single page Application) for your android application
Hi is your import correct? from node_modules it should be import Vue from 'vue' and not import Vue from './res/vue.js' try it

How can i have component render without App.vue

I’m trying to use vue-cli for app, but i wonder can i use component without using App.vue ?
Here component is shown in html but when i click the button, the testFunction in component is not called but in html the button "click here" is showing
index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
<body>
<h1>hi</h1>
<div id="app">
<MyComponent #my-event="testFunction"></MyComponent>
</div>
<!-- built files will be auto injected -->
</body>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.11" defer></script>
<script src="main.js" defer></script>
</html>
MyComponent.vue
<div class="child" #click="$emit('my-event')">
click here
</div>
</template>
<script>
export default {
name: 'MyComponent',
props: {
}
}
</script>
main.js
import Vue from 'vue/dist/vue.js'
import MyComponent from './components/MyComponent'
Vue.config.productionTip = false
Vue.component('MyComponent',MyComponent);
new Vue({
el: '#app',
beforeCreate() {
console.log('Vue instance beforeCreate!');
},
created() {
console.log('Vue instance created!');
},
mounted() {
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
.then(json => this.todos=json);
},
components: {
MyComponent
},
data: {
todos:null,
data:null
},
methods: {
testFunction:function(){
console.log("clicked");
}
},
render:h => h(MyComponent),
}).$mount('#app')
My Question:
here testFunction in MyComponent is not called . but i see MyComponent is $emit
and i dont use App.vue
is there way to register component, without render:h => h(myComponent)? and without $mount("#app")?
3.there is [Vue warn]: Cannot find element: #app error in console
No, that is not possible with the default configuration of vue-cli. If you want to import the component globally or only into a specific module then that is entirely possible, but what you are asking isn't possible. If you'd like to read more about local and global imports then read here.
There is a potential workaround though. You could create a second div to mount the application into, and then use the MyComponent component as the Base component for that mounting div. However, you will NOT be able to share data directly between the two Vue applications, and this behavior was used to be reserved for Modal insertion; however, nowadays the correct way to do this would be by via teleporting elements. You can read more about teleporting elements here
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import MyComponent from './components/MyComponent.vue';
createApp(App).mount('#app');
createApp(MyComponent).mount('#app2');
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<div id="app2"></div>
<!-- built files will be auto injected -->
</body>
</html>

ReactJS not rendering on Laravel

I am trying to render reactJS a component on my laravel (5.7) but it does not seem to show up. This is what my files look like:
welcome.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}" />
<title>React JS</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Varela+Round" rel="stylesheet" type="text/css">
<!-- Styles -->
<link href="{{asset('css/app.css')}}" rel="stylesheet">
</head>
<body>
<div id="root"></div>
<script src="{{asset('js/app.js')}}"></script>
</body>
</html>
Example.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from "./App.js";
ReactDOM.render(<App />, document.getElementById("root"));
App.js
import React from 'react';
class App extends React.Component() {
render(){
return (
<div>
<h1>Hello</h1>
<p>What a REAVELation</p>
</div>
);
}
}
export default App;
npm run watch is running and shows no errors.
Please what might I be doing wrong here?
Using defer fixed it for me
<script defer src="js/app.js"></script>
Use defer : The defer attribute is a boolean attribute.
<script defer type="text/javascript" src="{{ asset('js/app.js') }}"></script>
When present, it specifies that the script is executed when the page has finished parsing.
Note: The defer attribute is only for external scripts (should only be used if the src attribute is present).
Source: MDN
Syntex
You have syntactic bug when you declare class in App.js. You don't use parentheses when you declare class in JavaScript.
class App extends React.Component {
render(){
return (
<div>
<h1>Hello</h1>
<p>What a REAVELation</p>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Add this inside the <head> </head>
<script src="{{ asset('js/manifest.js') }}"></script>
<script src="{{ asset('js/vendor.js') }}"></script>
<script src="{{ asset('js/app.js') }}"></script>
One way to solve this issue is by extracting the vendor library code in a separate file. To do so, open the webpack.mix.js file and update its code as follows:
// webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.react()
.extract(['react'])
.postCss('resources/css/app.css', 'public/css', [
//
]);

How to use buefy(vue.js component library) on laravel blade template

I am trying to use buefy to my project and I can't use the vue.js on laravel 5.8 please help.
I have this on my app.js
require('./bootstrap');
window.Vue = require('vue');
import Buefy from 'buefy';
Vue.use(Buefy);
here is my blade template
#section('content')
#foreach ($permissions as $permission)
<div class="field">
<b-checkbox v-model="permissionSelected" native-value="{{$permission->id}}">
{{$permission->display_name}} <em>{{$permission->description}}</em>
</b-checkbox>
</div>
#endforeach
#endsection
#section('scripts')
<script>
var app = new Vue({
el: '#app',
permissionSelected: ['create-users']
});
</script>
#endsection
the checkbox of the buefy is not working.
With laravel it's better to use vue files and compile with NPM.
Here's the blade file. Laravel-mix will import the compile /public/js/app.js:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
...
<body>
<div id="app">
<app></app>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Your resources/js/app.js will use App.vue component:
The App.vue could be :
<template>
<div>
<h1>Hello</h1>
<template v-for='permission in permissions' :key='item.id'>
<div class="field">
<b-checkbox v-model="permissionSelected" native-value="{{permission->id}}">
{{permission->display_name}} <em>{{permission->description}}</em>
</b-checkbox>
</div>
</template>
</div>
</template>
<script>
export default {
name:'app',
data:()=>({
permissions:[],
permissionSelected:null,
....
in a terminal use this command to compile your app.js, App.vue : npm run dev

Categories

Resources