I'm trying to create a table view with laravel framework using jetstream inertia js vue package, and came across revogrid npm package, so i installed it using the vue 3 version.
Installation went fine, but when i imported the component, it gives me Could not find a declaration module for '#revolist/vue3-datagrid' and after npm run dev no changes happened.
my container.vue :
<template>
<app-layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Customer
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-xl sm:rounded-lg">
<v-grid
theme="compact"
:source="rows"
:columns="columns"
></v-grid>
</div>
</div>
</div>
</app-layout>
</template>
<script>
import AppLayout from '#/Layouts/AppLayout'
export default {
data: function () {
return {
columns: [{ prop: "name" }, { prop: "details" }],
rows: [{
name: "1",
details: "Item 1",
}]
}
},
components: {
AppLayout,
VGrid
},
methods: {
fetchCustomer: function () {
axios.get('/api/customers')
.then(response => this.rows = response.data)
.catch(error => console.log(error))
}
},
created: function () {
this.fetchCustomer()
}
}
</script>
error :
error message
result is empty page, while expected result is a sample table
Related
I am trying to disactivate the last crumb in InertiaJS (Laravel + Vue3) but I think I have an error or something missing somewhere. The error I am getting is the "isLast" is not defined.
isLast: This method simply takes in an index of the crumb array and checks if that crumb is the last one in the list.
selected: This is a simple method that emits an event whenever a crumb is selected. The event is then caught by Example.vue…
Here is the code:
BreadCrumb.vue
<template>
<div>
<ol class="inline-flex items-center space-x-1 md:space-x-3">
<li
v-for="(crumb, ci) in crumbs"
:key="ci"
>
<div class="inline-flex items-center">
<icon name="arrow"/>
<Link :href="`/${crumb}`" as="button" type="button" :class="{ disabled: isLast(ci) }" #click="selected(crumb)" class="capitalize" >
{{ crumb }}
</Link>
</div>
</li>
</ol>
</div>
</template>
<script>
import { Link } from '#inertiajs/inertia-vue3'
import Icon from '#/Shared/Icon'
export default {
components: {
Icon,
Link,
},
props: {
crumbs: {
type: Array,
required: true,
},
},
methods: {
isLast(index) {
return index === this.crumbs.length - 1;
},
},
}
</script>
Example.vue
<template>
<div class="md:p-12 md:pt-1">
<breadcrumb class="flex pl-4 mb-12" :crumbs="crumbs" #selected="selected"></breadcrumb>
</div>
</template>
<script>
import Breadcrumb from '#/Shared/Breadcrumb'
export default {
components: {
Breadcrumb,
},
return {
crumbs: ['home','users', 'create'],
}
methods: {
selected(crumb) {
console.log(crumb);
},
},
}
</script>
I would recommend binding the disabled-attribute
<Link ... :disabled="isLast(ci)" >
👆
so I'm using spatie media library and I can upload images to storage and database. And I'm trying to display multiple images in a vue component. This is my Controller.
public function showHotelPhoto($id)
{
$hotel = Hotel::first()->getFirstMedia('images')->getUrl();
return Inertia::render('AdminHotelPhoto', [
'data' => $hotel,
]);
}
And this my vue component, and I already success to fetch the image URL but only one image URL. And in my cases, I need to display all media from the database.
<template>
<breeze-authenticated-layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Foto Hotel
</h2>
</template>
{{ data }}
<img v-bind:src="image">
{{ test }}
</breeze-authenticated-layout>
</template>
<script>
import BreezeAuthenticatedLayout from '#/Layouts/Authenticated'
export default {
components: {
BreezeAuthenticatedLayout,
},
props: ['data', 'test'],
data () {
return {
image: this.data
}
},
}
</script>
It looks like you are close, try changing your component so you are properly referencing the image with the url, assuming that your data prop contains a url referencing it via this.data in the :src attribute:
<template>
<breeze-authenticated-layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Foto Hotel
</h2>
</template>
<div>
<img :src="this.data" />
</div>
</breeze-authenticated-layout>
</template>
<script>
import BreezeAuthenticatedLayout from '#/Layouts/Authenticated'
export default {
components: {
BreezeAuthenticatedLayout,
},
props: ['data', 'test'],
data () {
return {
image: this.data
}
},
}
</script>
I have this problem but i try some solutions in web but and i can't resolve it: Unknown custom element:
- did you register the component correctly? For recursive components, make sure to provide the "name" option.
The problem appears to be in those fils :
Please I need help as soon as possible
routes.js:
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../components/Home.vue";
import PostDetails from "../components/PostDetails.vue";
Vue.use(VueRouter);
const routes = [{
path: "/",
component: Home,
name: "Home"
},
{
path: "/post/:slug",
component: PostDetails,
name: "postDetails"
}
];
const router = new VueRouter({
routes: routes,
hashbang: false,
mode: "history"
});
export default router;
app.js:
import Vue from "vue";
import VueRouter from "vue-router";
require('./bootstrap');
window.Vue = require('vue');
Vue.component(key.split('/').pop().split('.')[0], files(key).default))
Vue.component('app-home', require('./AppHome.vue'));
import router from "./routes/routes.js";
const app = new Vue({
el: '#app',
vuetify,
render: h => h(App),
router: router,
});
AppHome.vue:
<template>
<div>
<router-view></router-view>
</div>
</template>
<script>
export default {
};
</script>
Home.vue:
<template>
<div class="container">
<div class="row my-4">
<div class="col-md-8">
<div class="card">
<div class="card-header">Articles</div>
<div
class="card-body"
:key="index"
v-for="(post, index) in posts.data"
>
<div class="media">
<img
:src="post.photo"
class="rounded img-fluid mr-2 shadow-sm"
alt=""
srcset=""
/>
<div class="media-body text-justify">
<router-link :to="post.path">
<h3>{{ index }}:{{ post.title }}</h3>
</router-link>
<p>
<span class="textdefaut">
{{ post.user.name }}
</span>
<span class="text-danger">
{{ post.added }}
</span>
</p>
<p class="lead text-justify">
{{ post.body.substr(0, 200) }}...
</p>
<hr />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
posts: {},
};
},
created() {
this.getPosts();
},
methods: {
getPosts() {
axios
.get("/api/posts")
.then((response) => {
console.log(response.data);
this.posts = response.data;
})
.catch((err) => console.log(err));
},
},
};
</script>
Post Details:
<template>
<div>
Posts details , This shows that the route is really working!!
<router-link to="/Home"><a>Back to the root</a></router-link>
</div>
</telpmate>
<script>
export default {
data () {
return {
message: 'Hoera!!!!'
};
}
};
</script>
If all of your Vuejs components (including AppHome.vue) are in /resources/js/components directory, you must change:
Vue.component('app-home', require('./AppHome.vue'));
by
Vue.component('app-home', require('./components/AppHome.vue'));
...in your app.js
Try to append .default option:
Vue.component('app-home', require('./components/AppHome.vue').default);
In #vue/cli 4.1.1 app I use v-money and vee-validate and I see that required rule does not work for
v-money , as it always has “0” value. So I make custom validation as it is written here
http://vee-validate.logaretm.com/v2/guide/custom-rules.html#using-the-custom-rule
Inserting this exam[ple in test page I got warnings in console :
WARNING Compiled with 2 warnings 7:45:56 AM
warning in ./src/views/Test.vue?vue&type=script&lang=js&
"export 'Validator' was not found in 'vee-validate'
warning in ./src/views/Test.vue?vue&type=script&lang=js&
"export 'Validator' was not found in 'vee-validate'
App running at:
- Local: http://localhost:8080/
- Network: unavailable
and in browser I see error :
vue-router.esm.js?8c4f:2113 TypeError: Cannot read property 'extend' of undefined
at eval (Test.vue?f246:87)
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/views/Test.vue?vue&type=script&lang=js& (4.js:11)
at __webpack_require__ (app.js:790)
at fn (app.js:151)
My test component :
<template>
<div class="frontend_item_container">
<ValidationObserver
ref="pageObserverForm"
v-slot="{handleSubmit}"
>
<b-form #submit.prevent="handleSubmit(onSubmit)">
<b-card-header>
<h3 class="row_content_left_aligned p-2" v-show="is_page_loaded">
<i :class="'info_link '+getHeaderIcon('page')"></i>{{ getHeaderTitle }}
</h3>
<div v-show="!is_page_loaded">
<h3>
<b-spinner variant="success" label="Page loading"></b-spinner> Page loading...
</h3>
</div>
</b-card-header>
<b-card-body v-show="is_page_loaded">
<b-row class="editor_row">
<b-col md="4">
<label for="editable_ad_price" class="pt-2 ">
Price<span class="required"> * </span>:
</label>
</b-col>
<b-col md="8">
price::{{ price}}
<ValidationProvider
name="editable_ad_price"
rules="required|truthy"
v-slot="{ errors }"
>
<money
v-model="price"
v-bind="moneyConfig"
name="editable_ad_price"
id="editable_ad_price"
class="form-control text-right"
placeholder="Enter price"
>
</money>
<p class="validation_error">{{ clearErrorMessage(errors[0]) }}</p>
</ValidationProvider>
</b-col>
</b-row>
</b-card-body>
<b-card-footer class="buttons_container" v-show="is_page_loaded">
<b-button size="md" #click.prevent="$router.push('/admin/pages')" class="m-3">
<i :class="'a_link '+getHeaderIcon('cancel')"></i>Cancel
</b-button>
<b-button type="submit" size="md" variant="success" class="m-3">
<i :class="'action_link '+getHeaderIcon('save')"></i>{{ submit_label }}
</b-button>
</b-card-footer>
</b-form>
</ValidationObserver>
</div>
</template>
<script>
import appMixin from '#/appMixin';
import Vue from 'vue'
import money from 'v-money'
Vue.use(money, {precision: 4})
import {settingsLocalizeMessages} from '#/app.settings.js'
import {ValidationObserver, ValidationProvider, extend} from 'vee-validate'
import * as rules from 'vee-validate/dist/rules';
Object.keys(rules).forEach(rule => {
extend(rule, rules[rule]);
});
import { Validator } from 'vee-validate';
Validator.extend('truthy', {
getMessage: field => 'The ' + field + ' value is not truthy.',
validate: value => !! value
});
let instance = new Validator({ trueField: 'truthy' });
instance.extend('falsy', (value) => ! value);
instance.attach({
name: 'falseField',
rules: 'falsy'
});
import {localize} from 'vee-validate';
localize({
en: settingsLocalizeMessages['en']
});
export default {
data() {
return {
apiUrl: process.env.VUE_APP_API_URL,
price: 12,
moneyConfig: {
decimal: ',',
thousands: '.',
prefix: '$',
suffix: '',
precision: 2,
masked: false
},
is_page_loaded: false,
}
}, // data() {
name: 'testPage',
mixins: [appMixin],
components: {
ValidationObserver, ValidationProvider
},
mounted() {
}, // mounted() {
created() {
}, // created() {
beforeDestroy() {
},
methods: {
}, // methods: {
computed: {
getHeaderTitle: function () {
return 'Test'
},
}, //computed: {
}
</script>
Why error and how to fix it ?
"bootstrap-vue": "^2.3.0",
"v-money": "^0.8.1",
"vee-validate": "^3.2.1",
"vue": "^2.6.11",
Thanks!
You are using the old documentation for vee-validate. In version 3 you have to do:
import { extend } from 'vee-validate';
Also check out the 3.x docs here: https://logaretm.github.io/vee-validate/guide/basics.html#adding-rules
I want to add one component inside other when user clicks a button. but how can we render the component in the virtual dom.
I tried using v-html but its not working.
Whats the best way to solve this issue?
export default {
data(){
return{
elements : {
hotel : '<hotel-form></hotel-form>'
},
}
},
methods:{
addHotel(){
console.log('add');
}
}
}
<template>
<div class="container" style="margin-top:300px;">
<div class="row" id="mainform">
<div v-for="item in elements">
<div v-html="item"></div>
</div>
</div>
<button #click="addHotel()">add hotel</button>
</div>
</template>
I would bind an array (hotels) to a <hotel-form> component tag via v-for. This way, no hotel-form components will be initially rendered, and then you can push an object (with any data to want bound to the hotel-form component) to the hotels array and the DOM will automatically render a new corresponding hotel-form component.
Here's a simple example:
Vue.component('hotel-form', {
template: '#hotel-form',
props: { id: Number, name: String },
});
new Vue({
el: '#app',
data() {
return { hotels: [], count: 0 }
},
methods: {
addHotel() {
this.hotels.push({ name: 'foo', id: this.count++ })
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="app">
<div id="mainform">
<hotel-form v-for="hotel in hotels" :key="hotel.id" v-bind="hotel">
</hotel-form>
</div>
<button #click="addHotel">add hotel</button>
</div>
<template id="hotel-form">
<div>
<h4>Hotel Form #{{ id }}</h4>
<div>{{ name }}</div>
</div>
</template>