I created Vue Component inside Laravel Project
TableComponent.vue
<template>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
</tr>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
i want to display it in
welcome.blade.php
<div id="id">
<table>
<thead>
<table-component></table-component>
</thead>
</table>
</div>
Thank you!
After experimenting and looking out my code. I solved it by adding in welcome.blade.php. Maybe because I added , I need to add .
THANKS!
Related
I have a table that lists out all my products and their prices and I have the prices as input
and what I would like to do is, when I click on save then I need to be able to save all those prices that I changed at
one time.
I'm not sure how to go about doing that.
Here is my code
<template>
<div>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr v-for="product in products">
<td>{{product.name}}</td>
<td>
<input #change="onChange(product)" v-model="product.prices">
</td>
</tr>
</tbody>
</table>
<div>
<div class="btn btn-success" #click="updatePrices()">
Save Prices
</div>
</div>
</template>
<script>
export default {
props: ['products'],
data() {
return {
product: {
price: null
}
}
},
methods: {
updatePrices(){
console.log(this.products.price);
}
},
mounted(){
}
}
</script>
Your question is about two parts of data passing.
From Vue Component to Vue Parent.
From Vue Client to Server.
And also, you may be confused with component data and props
You can check my answer
//component
Vue.component('price-table', {
props:[
'parentProducts',
],
data: function() {
return {
products:[]
};
},
methods: {
updatePrice(){
console.log('update prices from component to parent');
console.log(this.products);
this.$emit('update-prices', this.products);
}
},
mounted:function(){
console.log('pass products from parent to component');
this.products = this.parentProducts;
}
});
//parent
var vm = new Vue({
el: '#app',
data: () => ({
products:[
{
name:'Apple',
price:'10'
},
{
name:'Banana',
price:'12'
},
{
name:'Coconut',
price:'20'
},
]
}),
methods:{
savePricesToServer(products){
console.log('save prices to server');
console.log(products);
//do ajax here
}
}
});
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>Price Table</h2>
<price-table
inline-template
:parent-products="products"
v-on:update-prices="savePricesToServer"
>
<div>
<table border='1' width="100%">
<tr>
<th>Product</th>
<th>Price</th>
</tr>
<tr v-for="(product, productIndex) in products" :key="productIndex">
<td>{{ product.name}}</td>
<td>
<input type="number" v-model="product.price">
</td>
</tr>
</table>
<button #click="updatePrice">Update Price</button>
</div>
</price-table>
</div>
</body>
</html>
It is showing how to use custom event to pass data from component back to parent https://v2.vuejs.org/v2/guide/components-custom-events.html
The onclick event is complaining that the java script function is not defined.
<body>
<div layout:fragment="content" th:remove="tag">
<div class="container">
<h6 class="mb-3">Restaurant Order Details</h6>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th scope="col">Order Id</th>
<th scope="col">Order Details</th>
<th scope="col">Date</th>
<th scope="col">Amount</th>
</tr>
</thead>
<tbody>
<tr th:each="order : ${orders}" style="cursor: pointer"
th:attr="onclick=|getOrderItems('${order.orderId}')|">
<td scope="row" th:text="${order.orderId}"></td>
<td th:text="${order.orderDetais}"></td>
<td th:text="${order.orderDate}"></td>
<td th:text="${order.amount}"></td>
</tr>
<tr>
<td colspan="3">Total</td>
<td th:text="${grandTotal}"></td>
</tr>
</tbody>
</table>
<div class="mb-4"></div>
</div>
</div>
<script>
function getOrderItems(orderId) {
alert("order details here");
}
</script>
</body>
When I click on the table row I get
Uncaught ReferenceError: getOrderItems is not defined
at HTMLTableRowElement.onclick
When I replace getOrderItems with a simple alert instead, the alert is fired. How do I fix this?
I know this is probably not the answer you looking for, it's just a suggestion:
In JavaScript, you can actually use the thymeleaf variables like this:
var myVar = [[${order.orderId}]];
The issue here was I declared my <script> outside the <div layout:fragment="content" th:remove="tag"> tag. Since this is a fragment, thymeleaf only rendered everything within this scope. Putting the script tag inside this solved the issue.
You are not passing thymeleaf variable to javascript. You can issue <script> outside your (just above </body>) and still pass variable to JS.
<script th:inline="javascript">
/*<![CDATA[*/
var orders = [[${orders}]];
function getOrderItems(orders) {
alert("order details here ");
}
/*]]>*/
</script>
Then you can call JS method on your html onclick event.
<tr th:each="order : ${orders}" style="cursor: pointer"
th:attr="onclick=|getOrderItems(orders)}')|">
<td scope="row" th:text="${order.orderId}"></td>
<td th:text="${order.orderDetais}"></td>
<td th:text="${order.orderDate}"></td>
<td th:text="${order.amount}"></td>
</tr>
However, I still see a challenge if you wish to pass every single order to javascript. I haven't used <script> inside the th:each loop.
I'm trying using vue.js component, but the table template not showing in index.blade.php, I've searched for it in google but it not help me
Index.blade.php
<div id="app">
<h1>#{{6+9}}</h1>
<employee-component></employee-component>
</div>
<script src="{{asset('js/app.js')}}"></script>
resource/assets/js/app.js
Vue.component('employee-component', require('./components/Employee.vue'));
const app = new Vue({
el: '#app',
});
Employee.vue
<template>
<table class="table table-bordered">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
</template>
Result
15
Solved
Has been solved with using
Npm Run dev
Npm Run watch-pool
Npm Run watch
app.js
var Users = {
template: `
<tr v-for="list in UsersData">
<th>{{ list.idx }}</th>
<td>{{ list.id }}</td>
</tr>
`,
data: function () {
return {
UsersData //get data from query
}
}
}
var mainview = new Vue({
el: "#mainview",
components: {
'users': Users
},
method: {}
})
layout.blade.php
<body>
<div class="container">
<aside>...</aside>
<main id="mainview">
#section('content')
#show
</mainview>
</div>
</body>
index.blade.php
#extends('layout')
#section('content')
<table>
<thead>
<tr>
<th>IDX</th>
<th>ID</th>
</tr>
</thead>
<tbody>
<users></users>
</tbody>
</table>
#endsection
ERROR LOG from chrome console
[Vue warn]: Cannot use v-for on stateful component root element because it renders multiple elements:
<tr v-for="list in UsersData">
<th>{{ list.idx }}</th>
<td>{{ list.id }}</td>
</tr>
vue.js:525 [Vue warn]: Multiple root nodes returned from render function. Render function should return a single root node.
(found in component )
How should I fix code?
Your template has to have one root element. It's just one rule you cannot break. Since you're making a table, it would make sense to make tbody the root element.
var Users = {
template: `
<tbody>
<tr v-for="list in UsersData">
<th>{{ list.idx }}</th>
<td>{{ list.id }}</td>
</tr>
</tbody>
`,
data: function () {
return {
UsersData //get data from query
}
}
}
index.blade.php
#extends('layout')
#section('content')
<table>
<thead>
<tr>
<th>IDX</th>
<th>ID</th>
</tr>
</thead>
<users></users>
</table>
#endsection
For the lazy: Vue interprets the root element having a v-for loop on it as producing multiple root level elements (a nono in modern JS frameworks).
Just wrap your template in a superfluous blank <div>. 👌
I struggled with this, until I realized you can just add a section tag over everything in template and then this error goes away.
Example
//gives error
<template>
<div classname="allFutures" v-for="(items, index) in arr">
<Future title="Shee" />
</div>
</template>
// do this instead
<template>
<section id="main" class="main-alt">
<div classname="allFutures" v-for="(items, index) in arr">
<Future title="Shee" />
</div>
</section>
</template>
I'm having hard time on this.
My specific error is on this code: If I'll try to remove it everything works but I need to display the data columns. I don't understand why it cause an error.
<select>
<option v-for="column in columns">{{ column }}</option>
</select>
My app.js
import Vue from 'vue'
import DataViewer from './components/DataViewer.vue'
const app = new Vue({
el: '#app',
components: {
DataViewer
},
data: {
}
});
My DataViwer.vue
<template>
<div class="dv">
{{ title }}
</div>
<select>
<option v-for="column in columns">{{ column }}</option>
</select>
</template>
<script type="text/javascript">
import Vue from 'vue'
import axios from 'axios'
export default {
props: ['source', 'title'],
data(){
return {
model: {},
columns: {}
}
},
created(){
this.fetchIndexData()
},
methods: {
fetchIndexData(){
var vm = this
axios.get(this.source)
.then(function(response){
Vue.set(vm.$data, 'model', response.data.model)
Vue.set(vm.$data, 'columns', response.data.columns)
console.log(vm.$data.columns);
})
.catch(function(response){
console.log(response)
})
}
}
}
</script>
My ajax results:
I had the same warn and I found this decision: http://github.com.proxy.parle.co/ElemeFE/element/issues/4137
<el-tag v-for="tag in tags">
=>
<el-tag v-for="(tag, index) in tags" :key="index">
I faced that error because of a syntax mistake in for loop
the problem was the typo issue in src attribute in img tag!
<img class="m-widget__img" src="{{article.img_thumbnail}}" alt="">
which is totally wrong! it have to be like:
<img class="m-widget__img" :src="article.img_thumbnail" alt="">
as you know in these cases we have to bind the parameter to use in that attribute,
so first of all search for similar mistakes...
hope be helpful
To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key
<option v-for="column in columns">{{ column }}</option>
change it to
<option v-for="column in columns" :key="column">{{ column }}</option>
I have the same warn and figure it out that it happen when writing something else outside the loop:
This is OK
<template>
<table class="responsive-table">
<thead>
<tr>
<th class="no-print" style="width:1%;">
<label>
<input type="checkbox" v-model="selectAll"><span></span>
</label>
</th>
<th style="width:85%">Fecha</th>
<th style="width:14%">Acciones</th>
</tr>
</thead>
<tbody>
<tr v-for="list in messages" :key="list.id">
<td class="no-print" style="width:1%;">
<label><input type="checkbox" name="print_messages[]" v-model="selected" :value="list.id"><span></span></label>
</th>
<td class="view-link">{{list.formatted_date}}</td>
<td></td>
</tr>
</tbody>
</table>
This is NOT OK and through the error "(Emitted value instead of an instance of Error)"
<template>
<h1>I AM TRYING TO ADD A TITLE IN HERE</h1>
<table class="responsive-table">
<thead>
<tr>
<th class="no-print" style="width:1%;">
<label>
<input type="checkbox" v-model="selectAll"><span></span>
</label>
</th>
<th style="width:85%">Fecha</th>
<th style="width:14%">Acciones</th>
</tr>
</thead>
<tbody>
<tr v-for="list in messages" :key="list.id">
<td class="no-print" style="width:1%;">
<label><input type="checkbox" name="print_messages[]" v-model="selected" :value="list.id"><span></span></label>
</th>
<td class="view-link">{{list.formatted_date}}</td>
<td></td>
</tr>
</tbody>
</table>
** CHECK THE FIRST LINE AFTER OPENING "template" tag
Any clue on this?
Oh, BTW, I am learning VUEJS brute force style... so be nice ;p
In my case the problem was writing this:
<div :v-if="a>b"/>
<div v-else/>
Instead of this:
<div v-if="a>b"/>
<div v-else/>
Afaik you usually get this error when you have made a syntactic error in your template. It has usually nothing to do with the javascript and logic of your application.