Hey I am really new to VUE and for this project I have a button on one page which should trigger or call the function of another page. Everyone will be like why don't you have the button and function on same page as I am trying to learn basic part of how to call function of different page and then implement on my project. I am trying to make it easier and clear while I am asking question.
When I call the method function of chairPage.vue from homePage.vue, it throws an error saying world not defined on homePage.vue. Can anyone please explain why I am getting this error and what's the best way to solve this.
I have two pages one is homePage.vue and another one is chair.Vue. I have a button on homePage.vue which should call the method function of chairPage.vue.
Home Page
<template>
<div id="homepage">
<b-button variant="info" #click="buttonClicked()">Click</b-button>
<chairComponent ref="world"/>
</div>
</template>
<script>
import chairComponent from '#/components/chair.vue';
export default {
props: [],
methods:{
buttonClicked(){
this.$refs.world.hello();
}
}
}
</script>
Chair Page
<template>
<div id="chairComponent">
<p v-if="displayText == '1'"> HELLO WORLD </p>
</div>
</template>
<script>
export default {
props: ['world'],
data(){
return{
displayText:'',
}
},
methods:{
hello(){
console.log('inside child component hello function');
this.displayText = '1';
}
}
}
</script>
You can pass props to your child component, and there watch on props and call function:
Vue.component('Chair', {
template: `
<div id="chairComponent">
<p v-if="displayText == '1'"> HELLO WORLD </p>
</div>
`,
props: ['world'],
data(){
return{
displayText:'',
}
},
methods:{
hello(){
console.log('inside child component hello function');
this.displayText = '1';
}
},
watch: {
world() {
if (this.world) this.hello()
}
}
})
new Vue({
el: '#demo',
data() {
return {
val: null
}
},
methods:{
buttonClicked(){
this.val = true
setTimeout(() => {this.val = false},0)
}
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css" />
<script src="//unpkg.com/vue#latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="demo">
<div id="homepage">
<b-button variant="info" #click="buttonClicked">Click</b-button>
<chair :world="val" />
</div>
</div>
It works perfectly fine in the below snippet
Vue.component('Chair', {
template: `
<div id="chairComponent">
</div>
`,
data(){
return{
displayText:'',
}
},
methods:{
hello(){
console.log('inside child component hello function');
}
},
})
new Vue({
el: '#demo',
methods:{
buttonClicked(){
this.$refs.world.hello();
}
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css" />
<script src="//unpkg.com/vue#latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="demo">
<div id="homepage">
<b-button variant="info" #click="buttonClicked">Click</b-button>
<chair ref="world" />
</div>
</div>
I guess adding the components section in the homepage.vue might make it work
<template>
<div id="homepage">
<b-button variant="info" #click="buttonClicked()">Click</b-button>
<chairComponent ref="world"/>
</div>
</template>
<script>
import chairComponent from '#/components/chair.vue';
export default {
props: [],
// New changes added below
components: {
chairComponent
},
methods:{
buttonClicked(){
this.$refs.world.hello();
}
}
}
</script>
You can $emit from children to parent
https://v2.vuejs.org/v2/guide/components-custom-events.html
Child
hello () {
...//yours code
this.$emit('customEvent', someValue)
}
Parent
<template>
<child
#cutomEvent="function"
/>
<template>
Related
It is my first day learning VUE, and I'm following a tutorial by freeCodeCamp.org on YTB.
When it comes to the concept of component, the lecturer showed how to create a login form project by using components.
I followed exactly what she typed, but the code just didn't run. I'm confused why that happened.
Here is the ytb address: https://www.youtube.com/watch?v=FXpIoQ_rT_c&t=2224s , and the component section started from 00:29:20.
Here are the codes. Can anyone tell the reason plz? thx ahead!
<!DOCTYPE html>
<html>
<head>
<title>vueComponents</title>
<style type="text/css">
[v-cloak]{
display: none;
}
input {
margin: 10px;
display: block;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<login-form />
</div>
<script src="https://unpkg.com/vue#next"></script>
<script>
let app=Vue.createApp({
data():{
return{
greeting : 'hello VUE',
}
}
})
app.component ('login-form',{
template: ‘
<form #submit="handleSubmit">
<h1> {{ title }} </h1>
<input type="email" />
<input type="password" />
<button>Log In</button>
</form>
’,
data(){
return{
title:'Login Form'
}
},
methods:{
handleSubmit(){
console.log('submitted')
}
}
})
app.mount('#app')
</script>
</body>
</html>
Looks like there is an issue with quotes in the template.
Working Demo :
let app = Vue.createApp({
data() {
return {
greeting : 'hello VUE',
}
}
})
app.component ('login-form',{
template: `<form #submit="handleSubmit">
<h1> {{ title }} </h1>
<input type="email" />
<input type="password" />
<button>Log In</button>
</form>`,
data() {
return {
title:'Login Form'
}
},
methods:{
handleSubmit(){
console.log('submitted')
}
}
})
app.mount('#app')
<script src="https://unpkg.com/vue#next"></script>
<div id="app" v-cloak>
<login-form />
</div>
Ran into a case to trigger a click once a page or view is loaded, and a popup is triggered in vue.js to edit data table row. There is no such a good VUE way that I can find, although the following link mentioned a way as the follows:
https://forum.vuejs.org/t/how-to-trigger-a-click-event-through-code-in-vuejs-on-page-load/92582
mounted: function () {
setTimeout(function(){
const elem = document.getElementById('myBtn');
elem.click();
}, 100);
},
I did in a similar way as the follows. The try catch to contain error although it's ugly, since at some point the data doesn't exist.
edit: function (idx, row) {
... nore code here ...
try {
document.getElementById(row.id).click(); // row.id is dynamic or variable
} catch (error) {
// pass
}
},
However my team mate, a vue.js lover, said it's not a damn VUE way. Now what it the right way to do such a thing?
The following Demo is possible for the expected work:
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
li_address: [{name: 'CA'}, {name: 'NY'}, {name: 'AL'}],
name: 'NY'
},
methods: {
},
mounted() {
console.log(['this.name', this.name]);
// this.$refs[this.name].click(); // failed
document.getElementById(this.name).click(); // worked. the click is triggered upon this.name
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/css/uikit.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/js/uikit.min.js"></script>
<div id="app" class="container">
<div class="uk-grid" uk-grid>
<div v-for="r in li_address">
<label>{{r.name}}
<input :id="r.name" :ref="r.name" type="radio" class="uk-radio" :value="r"
name="address_group">
</label>
</div>
</div>
</div>
Add a ref to your element called myBtn like :
<div ref="myBtn" >some content</div>
then run the click :
this.$refs.myBtn.click()
example :
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
methods: {
logOk() {
console.log("OK OK")
}
},
mounted() {
this.$refs.okBtn.click()
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app" class="container">
<button ref="okBtn" #click="logOk"> OK</button>
</div>
Just select your element and trigger Click Event on Mounted life cycle of Vue app
mounted() {
this.$nextTick(() => {
document.getElementById('myBtn').click()
});
}
$nextTick according to VueJs documentation :
Defer the callback to be executed after the next DOM update cycle. Use
it immediately after you’ve changed some data to wait for the DOM
update.
In your example code, there is no need for any DOM manipulation. The main strength of a declarative reactive framework like Vue is for changes to the model to be automatically propagated to the view. This will select the appropriate radio button just by setting v-model appropriately.
new Vue({
el: '#app',
data() {
return {
li_address: [{name: 'CA'}, {name: 'NY'}, {name: 'AL'}],
name: 'NY'
}
}
})
<div id="app" class="container">
<div class="uk-grid" uk-grid>
<div v-for="r in li_address">
<label :for="r.name">{{r.name}}
<input type="radio" v-model="name" :id="r.name" :value="r.name">
</label>
</div>
<h4>NAME: {{ name }}</h4>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/css/uikit.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.27.5/js/uikit.min.js"></script>
I'm reading through the documentation here for switch style checkboxes: https://bootstrap-vue.org/docs/components/form-checkbox
When I use the example HTML/JS in my own application, I can get the html to render but it doesn't show the actual switch toggle, like so:
https://jsfiddle.net/Lz5tcpqb/2/
<template>
<div>
<b-form-checkbox v-model="checked" name="check-button" switch>
Switch Checkbox <b>(Checked: {{ checked }})</b>
</b-form-checkbox>
</div>
</template>
<script>
export default {
data() {
return {
checked: false
}
}
}
</script>
Is there something I'm missing here?
It's kind of working, you might need to import css or use latest stable version of bootstrap-vue and Vue.js
new Vue({
el: '#app',
data() {
return {
checked: false,
};
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/bootstrap#4.5.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue#2.16.0/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://unpkg.com/bootstrap-vue#2.16.0/dist/bootstrap-vue.js"></script>
<div id="app">
<b-form-checkbox v-model="checked" name="check-button" switch>
Switch Checkbox <b>(Checked: {{ checked }})</b>
</b-form-checkbox>
</div>
I'm trying to pass value from Laravel to Vue. But the props I get is always undefined (from console.log). I checked it's not the camel case issue. I really can't find where is the issue. Can anyone help, please?
PS. I'm a laravel and Vue beginner. Thank you very much
blade.php file:
#extends('layouts.subject')
#section('content')
<script src="{{ asset('js/subject/subjectapp.js') }}" defer></script>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-body">
<sample message="HELLO"></sample>
</div>
</div>
</div>
</div>
</div>
#endsection
subjectapp.js file:
require('../bootstrap');
window.Vue = require('vue');
import 'babel-polyfill'
import Vuetify from 'vuetify';
import Sample from '../components/subject/Sample.vue';
Vue.use(Vuetify);
const sample = new Vue({
el: 'sample',
vuetify: new Vuetify(),
components: {
Sample
},
render: h => h(Sample),
});
Sample.vue file
<template>
<v-app>
<div class="row">
<div class="col border m-2">
MESSAGE
{{message}}
</div>
</div>
</v-app>
</template>
<script>
export default {
props: ['message'],
created() {
console.log(this.message);
},
}
</script>
Edit:
extra info of my app:
data CANNOT be passed from blade.php to a vue component(A.vue) nested inside.
Data CAN be passed from a Vue component(A.vue) nested in the blade.php, to a vue component(B.vue) nested in that component(A.vue).
You can add this to the end of your blade.php file
<script>
window.prop1 = somePropValue;
window.prop2 = somePropValue;
</script>
and access it on your vue file by calling window.prop1
This solution works for me. Here are my files:
<html>
<head>
<script src="{{ asset('js/app.js') }}" defer></script>
</head>
<body>
<div id="app">
<main class="py-sm-4">
<chat-component #if(isset($create_message)) user="{{ $create_message }}" #endif></chat-component>
</main>
</div>
</body>
<script>
window.Laravel = {!! json_encode([
'auth' => auth() -> check() ? auth() -> user() -> id : null,
])!!};
window.LaravelUrl = "{{ url('') }}"
window.user_id = "{{Auth::id()}}"
</script>
</html>
app.js file:
require('./bootstrap');
window.Vue = require('vue');
import WebRTC from 'vue-webrtc'; //video call plugin, not relevant to the answer
Vue.use(WebRTC); //video call plugin, not relevant to the answer
Vue.component('chat-component', require('./components/ChatComponent.vue'));
const app = new Vue({
el: '#app',
});
Vue example usages:
axios.post(window.LaravelUrl + `/send/${this.friend.session.id}`)
//
axios.post(window.LaravelUrl + "/send_calling_info", {
session_id: this.friend.session.id,
receiver_id: this.friend.id,
caller_id: window.user_id
})
//
return this.session.blocked_by == window.Laravel.auth;
and some other usages inside axios.post()
So this is the most simplified version of the program that I am trying to create.
Basically I want to change the display from Component 1 to Component 2 with the click event of of button. Whenever I click the button I want to change from component 1 to component 2 and vice versa.
To create a this program I have used a JavaScript event .onclick, but somehow I don't know why this is not working. My console log is not even showing any error message.please help Thank you
I have also tried using a v-on event but that is not working.
<html>
<head>
<title></title>
<style media="screen">
#inp{
height:100px;border:1px solid black;
}
</style>
<script type="text/javascript" src='vue.js'></script>
</head>
<body>
<div id='main_area'>
<button id='button1' type="button" name="button">Click Here</button>
<div id='inp'>
</div>
</div>
<template id="first_comp">
<div class="FC1">
<h1>This is component 1</h1>
</div>
</template>
<template id="second_comp">
<div class="SC1">
<h1>This is component 2</h1>
</div>
</template>
<script type="text/javascript">
var elem=document.getElementById('inp');
var swic=true;
elem.innerHTML='<comp1></comp1>';
var btn=document.getElementById('button1');
btn.onclick=function(){
if (swic==true) {
swic=false;
elem.innerHTML='<comp2></comp2>'
}
else {
swic=true;
elem.innerHTML='<comp1></comp1>';
}
}
Vue.component('comp1',{
template:'#first_comp',
data:function(){
return{
}
},
})
Vue.component('comp2',{
template:'#second_comp',
data:function(){
return{
}
},
})
var vvm= new Vue({
el:'#main_area',
data:{
},
})
</script>
</body>
</html>
The console log is not showing any error message