I am new in Vue Js. I am developing a project in Laravel 7.* with Vue js.
My Vue Project Structure
app.js File contains:
require('./bootstrap');
window.Vue = require('vue');
Vue.config.debug = true;
Vue.config.devtools = true;
Vue.config.productionTip = false;
Vue.config.silent = false;
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import VueAxios from 'vue-axios';
import axios from 'axios';
import App from './App.vue';
Vue.use(VueAxios, axios);
import HomeComponent from './components/home/HomeComponent.vue';
import CreateComponent from './components/post/CreateComponent.vue';
import IndexComponent from './components/post/IndexComponent.vue';
import EditComponent from './components/post/EditComponent.vue';
import Notification from './components/Notification.vue';
const routes = [
{
name: 'home',
path: '/',
component: HomeComponent
},
{
name: 'create',
path: '/create',
component: CreateComponent
},
{
name: 'posts',
path: '/posts',
component: IndexComponent
},
{
name: 'edit',
path: '/edit/:id',
component: EditComponent
},
{
name: 'notify',
path: '/notifications',
component: Notification
}
];
const router = new VueRouter({ mode: 'history', routes: routes});
const app = new Vue(Vue.util.extend({ router }, App)).$mount('#app');
App.Vue File contains:
<template>
<div class="container-fluid">
<div class="row">
<div class="col-12 p-0">
<nav class="navbar navbar-expand-sm bg-info navbar-dark">
<div class="container">
<ul class="navbar-nav">
<li class="nav-item">
<router-link to="/" class="nav-link">Home</router-link>
</li>
<li class="nav-item">
<router-link to="/create" class="nav-link">Create Post</router-link>
</li>
<li class="nav-item">
<router-link to="/posts" class="nav-link">Posts</router-link>
</li>
<li class="nav-item">
<router-link to="/notifications" class="nav-link">Notifications</router-link>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<br/>
<!-- <transition name="fade">-->
<router-view></router-view>
<!-- </transition>-->
</div>
</div>
</div>
</div>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-active {
opacity: 0
}
</style>
<script type="text/babel">
export default {}
</script>
Webpack.mix file contains
const mix = require('laravel-mix');
let productionSourceMaps = false;
if ( ! mix.inProduction()) {
mix.webpackConfig({
devtool: 'eval-source-map'
});
}
mix.sourceMaps(false, type = 'eval-source-map')
.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
bootstrap.js file contains:
window._ = require('lodash');
try {
window.Popper = require('popper.js').default;
window.$ = window.jQuery = require('jquery');
require('bootstrap');
} catch (e) {}
window.axios = require('axios');
window.axios.defaults.baseURL = 'http://dshop.test';
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
HomeComponent.vue contains
<template>
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card card-default">
<div class="card-header">Home Component</div>
<div class="card-body">
I'm the Home Component component.
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>
Now when I want to debug in Chrome the components don't showing the original components
Please help me! What configurations I have missed I can't find it.
Regards
You cant see Vue component at this way. Install Vue dev tool plugin following this link:
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
Then you will be able to see this in your chrome browser:
https://www.dropbox.com/s/fo0jpb4y1w0cv8k/Screenshot%202020-04-17%2010.26.52.png?dl=0
Please note that in order to be able to see Vue dev tab in your chrome dev tools, you must have assets built as dev.
npm run dev or yarn watch etc.. If you run npm run production or yarn production, you will not have Vue tab since is not in development mode.
maybe try this extension when trying to debug Vue as it will show component structures, props and much more: https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
Related
I want to use svg image in my vue. However i keep getting invalid component definition in my website. I also created a configuration file vue.config.js. However , the same error keep coming out although i followed the documentation correctly. Can anyone help me with this?
Navigation.vue
<template>
<header>
<nav class="container">
<div class="branding">
<router-link class="header" :to="{ name:'Home'}">Blog</router-link>
</div>
<div class="nav-links">
<ul>
<router-link class="link" to="#">Home</router-link>
<router-link class="link" to="#">Blogs</router-link>
<router-link class="link" to="#">Create Post</router-link>
<router-link class="link" to="#">Login/Register</router-link>
</ul>
</div>
</nav>
<MenuIcon/>
<transition name="mobile-nav">
<ul>
<router-link class="link" to="#">Home</router-link>
<router-link class="link" to="#">Blogs</router-link>
<router-link class="link" to="#">Create Post</router-link>
<router-link class="link" to="#">Login/Register</router-link>
</ul>
</transition>
</header>
</template>
<script>
import MenuIcon from '../assets/Icons/bars-regular.svg'
export default {
name: 'navigation',
components:{
MenuIcon,
}
};
</script>
vue.config.js
module.exports = {
chainWebpack: (config) => {
const svgRule = config.module.rule('svg');
svgRule.uses.clear();
svgRule
.use('babel-loader')
.loader('babel-loader')
.end()
.use('vue-svg-loader')
.loader('vue-svg-loader');
},
};
you need to paste the SVG's code inside a Vue file which ends with .vue
example:
../assets/Icons/bars-regular.vue
I solved the problem by adding this code in vue.config.js
module.exports = {
chainWebpack: config => {
config.module.rules.delete("svg");
},
configureWebpack: {
module: {
rules: [
{
test: /\.svg$/,
loader: 'vue-svg-loader',
},
],
}
}
};
I have a vue app and I'm trying to implement the 'Vue HTML to Paper'.
I have followed all the instructions on https://randomcodetips.com/vue-html-to-paper/ but when i click my 'Print' button I get the following error.
Main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import { routes } from './routes';
import { store } from './store/store';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import VueHtmlToPaper from 'vue-html-to-paper';
const router = new VueRouter({
// Loads page always at the top
scrollBehavior() {
$('.tooltip, .popover').tooltip('hide');
return { x: 0, y: 0 };
},
routes,
});
const options = {
name: '_blank',
specs: [
'fullscreen=yes',
'titlebar=yes',
'scrollbars=yes'
],
styles: [
'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css',
'https://unpkg.com/kidlat-css/css/kidlat.css'
]
}
Vue.use(VueRouter, VueHtmlToPaper, options);
...
Component
<template>
<div>
<loader v-if="loading" />
<div v-else class="form-group row d-flex justify-content-center">
<div class="col-10">
<div id="printMe" class="card">
<div class="card-header">
<div class="row d-flex align-items-center">
<div class="col">
Order details for: <span class="text-info">{{ 'PACK' + productOrder.id }}</span>
</div>
<div class="col d-flex justify-content-end">
<button class="btn btn-info" #click="print">Print</button>
......
<script>
export default {
data() {
return {
...
output: null
....
methods: {
print () {
// Pass the element id here
this.$htmlToPaper('printMe');
},
...
You can't register multiple plugins in one Vue.use.
Try replacing the line
Vue.use(VueRouter, VueHtmlToPaper, options);
With
Vue.use(VueRouter);
Vue.use(VueHtmlToPaper, options)
The connection in between components gets disrupted. Which shouldnt happen since I am using bootstrap-vue inbuilt router link (using to=" " instead of href="").
The app works perfectly fine when running without dist.
App.vue
<template>
<div class="container">
<app-header></app-header>
<div class="row">
<div class="col-xs-12">
<transition name="slide" mode="out-in">
<router-view></router-view>
</transition>
</div>
</div>
</div>
</template>
<script>
import Header from "./components/Header.vue";
export default {
components: {
appHeader: Header
},
created() {
this.$store.dispatch("initStocks");
}
};
</script>
Header.vue
<template>
<div>
<b-navbar toggleable="lg" type="dark" variant="info">
<b-navbar-brand to="/">Stock Broker</b-navbar-brand>
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav>
<b-nav-item to="/portfolio">Portfolio</b-nav-item>
<b-nav-item to="/stocks">Stocks</b-nav-item>
<b-nav-item #click="endDay">End Day</b-nav-item>
<b-navbar-nav right>
<b-nav-item right>Funds: {{ funds }}</b-nav-item>
</b-navbar-nav>
</b-navbar-nav>
</b-collapse>
</b-navbar>
</div>
</template>
<script>
import { mapActions } from "vuex";
export default {
data() {
return {
isDropdownOpen: false
};
},
computed: {
funds() {
return this.$store.getters.funds;
}
},
methods: {
...mapActions({
randomizeStocks: "randomizeStocks",
fetchData: "loadData"
}),
endDay() {
this.randomizeStocks();
},
saveData() {
const data = {
funds: this.$store.getters.funds,
stockPortfolio: this.$store.getters.stockPortfolio,
stocks: this.$store.getters.stocks
};
this.$http.put("data.json", data);
},
loadData() {
this.fetchData();
}
}
};
</script>
vue.config.js
module.exports = {
pluginOptions: {
prerenderSpa: {
registry: undefined,
renderRoutes: ["/", "/portfolio", "/stocks"],
useRenderEvent: true,
headless: true,
onlyProduction: true
}
}
};
router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/stocks',
name: 'Stocks',
component: () => import(/ '../views/Stocks.vue')
},
{
path: '/portfolio',
name: 'Portfolio',
component: () => import('../views/Portfolio.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
I figured it a minute after making this post haha.
The issue was that in App.vue I had my main div with a class of "container" instead of id of "app".
Corrected below:
<template>
<div id="app"> //correction here
<app-header></app-header>
<div class="row">
<div class="col-xs-12">
<transition name="slide" mode="out-in">
<router-view></router-view>
</transition>
</div>
</div>
</div>
</template>
I'm working on admin panel in vuejs and using vuex for state management.
store/module/home/home.js:
import instance from "../../../services/Http";
const state = {
usersCount: 0,
customersCount: 0,
chefsCount: 0,
driversCount: 0,
Users: [],
};
const getters = {
Userscount: state => state.usersCount,
Customerscount: state => state.customersCount,
Chefscount: state => state.chefsCount,
Driverscount: state => state.driversCount,
users: state => state.Users,
};
const actions = {
getStats({commit})
{
instance.get('admin/stats').then(res => commit('setStats', res.data));
},
getUsers({commit})
{
instance.get('admin/users').then(res => commit('setUsers', res.data));
}
};
const mutations = {
setStats:(state, data) => {
state.usersCount = data.usersCount;
state.customersCount = data.customersCount;
state.chefsCount = data.chefsCount;
state.driversCount = data.driversCount;
},
setUsers:(state, data) => { state.Users = data.users}
};
export default {
state,
getters,
actions,
mutations
}
and then i'm calling getStats and getUsers actions in two different components in created method of respective components.
The issue is that getStats and setStats is executed but it does not set the data, but getUsers and setUsers is working as expected.
src/components/layouts/Widgets.vue:
<template>
<!-- Widgets -->
<div class="row">
<div class="col-lg-3 col-md-6">
<div class="card">
<div class="card-body">
<div class="stat-widget-five">
<div class="stat-icon dib flat-color-1">
<!-- <i class="pe-7s-cash"></i>-->
<i class="pe-7s-users"></i>
</div>
<div class="stat-content">
<div class="text-left dib">
<div class="stat-text"><span class="count">{{ Userscount }}</span></div>
<div class="stat-heading">Total Users</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6">
<div class="card">
<div class="card-body">
<div class="stat-widget-five">
<div class="stat-icon dib flat-color-2">
<!-- <i class="pe-7s-cart"></i>-->
<i class="pe-7s-users"></i>
</div>
<div class="stat-content">
<div class="text-left dib">
<div class="stat-text"><span class="count">{{ Chefscount }}</span></div>
<div class="stat-heading">Total Chefs</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6">
<div class="card">
<div class="card-body">
<div class="stat-widget-five">
<div class="stat-icon dib flat-color-8">
<!-- <i class="pe-7s-browser"></i>-->
<i class="pe-7s-users"></i>
</div>
<div class="stat-content">
<div class="text-left dib">
<div class="stat-text"><span class="count">{{ Customerscount }}</span></div>
<div class="stat-heading">Total Customers</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6">
<div class="card">
<div class="card-body">
<div class="stat-widget-five">
<div class="stat-icon dib flat-color-4">
<i class="pe-7s-users"></i>
</div>
<div class="stat-content">
<div class="text-left dib">
<div class="stat-text"><span class="count">{{ Driverscount }}</span></div>
<div class="stat-heading">Total Drivers</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /Widgets -->
</template>
<script>
import {mapActions,mapGetters} from 'vuex';
export default {
name: "Widgets",
created() {
this.getStats();
},
computed: mapGetters(['Userscount','Customerscount','Chefscount','Driverscount']),
methods:{
...mapActions(['getStats'])
},
}
</script>
i'have also attached images showing of vue js dev tools for vuex that data is stored in state but it is not being displayed.
edit-1:
setStats-after console.log
{usersCount: 12, customersCount: 4, chefsCount: 7, driversCount: 0, postsCount: 22}chefsCount: 7customersCount: 4driversCount: 0postsCount: 22usersCount: 12__proto__: Object
Edit-2:
vuex binding widgets components
Edit-3:
Store/index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import auth from "./modules/auth/auth";
import home from "./modules/home/home";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
auth,
home
}
});
sr/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false;
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!store.getters.isLoggedIn)
{
next({
name: 'login',
})
}
else
{
next();
}
}
else if(to.matched.some(record => record.meta.Visitor)) {
if (store.getters.isLoggedIn)
{
next({
name: 'home',
})
}
else
{
next();
}
}
else
{
next()
}
});
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app');
src/components/layout/Main.vue:
<template>
<div class="Main">
<SideBar/>
<div id="right-panel" class="right-panel">
<Header/>
<!-- Content -->
<div class="content">
<div class="animated fadeIn">
<Widgets/>
<div class="clearfix"></div>
<Users/>
<div class="clearfix"></div>
<Footer/>
</div>
</div>
</template>
<script>
import SideBar from "./SideBar";
import Header from "./Header";
import Footer from "./Footer";
import Widgets from "./Widgets";
import Users from "../users/Users";
export default {
name: "Main",
components: {Users, Widgets, Footer, Header, SideBar}
}
</script>
<style scoped>
#weatherWidget .currentDesc {
color: #ffffff!important;
}
.traffic-chart {
min-height: 335px;
}
#flotPie1 {
height: 150px;
}
#flotPie1 td {
padding:3px;
}
#flotPie1 table {
top: 20px!important;
right: -10px!important;
}
.chart-container {
display: table;
min-width: 270px ;
text-align: left;
padding-top: 10px;
padding-bottom: 10px;
}
#flotLine5 {
height: 105px;
}
#flotBarChart {
height: 150px;
}
#cellPaiChart{
height: 160px;
}
</style>
Any help will be appreciated.
Thanks.
you forgot to add "..." before the 'mapGetters', "...mapGetters"
I think your problem would be solved by implementing the strict-mode in Vuex, by the way, it's turned off by default.
take a look here: https://vuex.vuejs.org/guide/strict.html
Have you tried using mapState instead of mapGetters? As your values are just being updated, but your getters aren't computed values, they just map to your state.
Instead of:
<script>
import {mapActions,mapGetters} from 'vuex';
export default {
name: "Widgets",
created() {
this.getStats();
},
computed: mapGetters(['Userscount','Customerscount','Chefscount','Driverscount']),
methods:{
...mapActions(['getStats'])
},
}
</script>
Maybe try:
<script>
import {mapActions,mapGetters} from 'vuex';
export default {
name: "Widgets",
created() {
this.getStats();
},
computed: mapState({
Userscount: state => state.home.Userscount,
Customerscount: state => state.home.Customerscount,
Chefscount: state => state.home.Chefscount,
Driverscount: state => state.home.Drivers.count
}),
methods:{
...mapActions(['getStats'])
},
}
</script>
I am creating vue js application. I have login screen and after login, left sidebar for options like dashboard, users, settings.. and header for signout and notification feature.
My architecture is : I have 1 common file(main layout) in which header and sidebar are added. Now on 1st time open after login, dashboard is called in which main layout is imported.
I want to call this sidebar and header only once.. but the problem is whenever I click on sidebar, it opens respective screen in right side in container but sidebar and header also calls as I have imported main file to each component.
Due to this my firebase listener attached in header calls multiple times. I want to load header only once after login so that I can use firebase listener correctly.
My architecture is below:
main layout file:
<template>
<div id="appOne">
<div class="col-sm-3 col-lg-2 hamburger" style="padding-left: 0;">
<Sidebar></Sidebar>
</div>
<div class="col-sm-9 col-lg-10 fixed">
<Header class="header"></Header>
<div class="dynTemplate" id="dynTemplate"></div>
</div>
</div>
</template>
Dashboard vue file:
<template>
<div>
<Mainlayout></Mainlayout>
<div>
<span><h1 align="center"> Welcome </h1> </span>
</div>
</div>
</template>
<script>
import Mainlayout from './shared/Mainlayout.vue';
export default {
el: '#appOne',
components: {
Mainlayout,
}
}
</script>
What is correct way to use header, sidebar and other component which will call on click on sidebar options.
Try this snippet. The mounted() and created() in header will be called only once.
Or if you need more dynamic view components, try named view
const Login = {
template: `
<div>
<div>Login Page</div>
<router-link to="/foo">click here</router-link>
</div>
`
}
const Sider = {
template: '<div>This is sider</div>'
}
const Header = {
template: '<div>This is header</div>',
mounted() {
console.log("header mounted")
},
created() {
console.log("header created")
},
}
const MainLayout = {
template: `
<div>
<mysider></mysider>
<div>
<myheader></myheader>
<router-view></router-view>
</div>
</div>
`,
components: {
mysider: Sider,
myheader: Header
}
}
const Foo = {
template: `
<div>
<div>This is Foo</div>
<router-link to="/bar">go to Bar</router-link>
</div>`
}
const Bar = {
template: `
<div>
<div>This is Bar</div>
<router-link to="/foo">go to Foo</router-link>
</div>`
}
const router = new VueRouter({
routes: [{
path: '/',
component: Login
},
{
path: '/main',
component: MainLayout,
children: [
{
path: '/foo',
component: Foo
},
{
path: '/bar',
component: Bar
},
]
}
]
})
const app = new Vue({
router
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">
<router-view></router-view>
</div>