UnCaught Reference Error: VueRouter is not Defined - vue.js

I have never done fullstack development of any sort and was pointed to this tutorial to do WedAPI and VueJS. I also have never used JS or anything outside of Python, PERL, and C#
The tutorial is here: https://www.youtube.com/watch?v=qS833HGKPD8
I am at the time span between 31:00 and 37:55 where he begins the UI frontend part.
However I run into the error "UnCaught Reference Error: VueRouter is not Defined" when I reload the webpage and it points to my app.js file at line 8:
const router=new VueRouter({
routes
})
Here are snippets of the code so far:
home.js:
const home={template: `<h1>This is Home page</h1>`}
department.js:
const department={template: `<h1>This is Departments page</h1>`}
employee.js:
const employee={template: `<h1>This is Employee page</h1>`}
app.js:
//root component to list the routing parts
const routes=[
{path:'/home',component:home},
{path:'/employee',component:employee},
{path:'/department',component:department}
]
const router=new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
variable.js:
//save API urls
const variables={
API_URL: "http://localhost:15899/api",
PHOTO_URL: "http://localhost:15899/photos/vari"
}
index.html
<!DOCTYPE html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
</head>
<body>
<div id="app" class="container">
<h3 class="d-flex justify-content-center">
Vue JS Front End
</h3>
<h5 class="d-flex justify-content-center">
Employee Management Portal
</h5>
<nav class="navbar navbar-expand-sm bg-light navbar-dark">
<ul class="navbar-nav">
<li class="nav-item m-1">
<router-link class="btn btn-light btn-outline-primary"
to="/home">Home</router-link>
</li>
<li class="nav-item m-1">
<router-link class="btn btn-light btn-outline-primary"
to="/department">Department</router-link>
</li>
<li class="nav-item m-1">
<router-link class="btn btn-light btn-outline-primary"
to="/employee">Employee</router-link>
</li>
</ul>
</nav>
<router-view></router-view>
</div>
<script src="variables.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script src="home.js"></script>
<script src="department.js">
</script>
<script src="employee.js"></script>
<script src="app.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
</body>
</html>
On the tutorial with only this code, the instructor has no issues.
What am I doing wrong to get this message?
I looked for solutions but the directions are all over the place. I even tried
npm install --save vue-router
but got this:
npm ERR! code ENOTFOUND
npm ERR! syscall getaddrinfo
npm ERR! errno ENOTFOUND
npm ERR! network request to https://registry.npmjs.org/#vue%2fdevtools-api failed, reason: getaddrinfo ENOTFOUND proxy-chain.intel.com
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly. See: 'npm help config'
npm ERR! A complete log of this run can be found in:
I have configured my work computer's proxy but no joy.
The instructor didn't need to install vue router. It seemed he just linked it in his index.html which is what I did.
I've done everything that is stated in the tutorial.

In case anyone runs into this tutorial I fixed it like so:
So the tutorial uses the HTML method instead of package install method aluded above in Siti's answer. However since the tutorial was made, Vue has updated it's URLs and how to launch the Vue Router/use the Vue router in HTML mode and this can be found here:
https://router.vuejs.org/guide/
My app.js looks like this now:
//root component to list the routing parts
const routes=[
{path:'/home',component:home},
{path:'/employee',component:employee},
{path:'/department',component:department}
]
const router = VueRouter.createRouter({
// 4. Provide the history implementation to use. We are using the hash history for simplicity here.
history: VueRouter.createWebHashHistory(),
routes, // short for `routes: routes`
})
// const app = new Vue({
// router
// }).$mount('#app')
// 5. Create and mount the root instance.
const app = Vue.createApp({})
// Make sure to _use_ the router instance to make the
// whole app router-aware.
app.use(router)
app.mount('#app')
And ny HTMl document now looks like this:
<!DOCTYPE html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
</head>
<body>
<div id="app" class="container">
<h3 class="d-flex justify-content-center">
Vue JS Front End
</h3>
<h5 class="d-flex justify-content-center">
Employee Management Portal
</h5>
<nav class="navbar navbar-expand-sm bg-light navbar-dark">
<ul class="navbar-nav">
<li class="nav-item m-1">
<router-link class="btn btn-light btn-outline-primary"
to="/home">Home</router-link>
</li>
<li class="nav-item m-1">
<router-link class="btn btn-light btn-outline-primary"
to="/department">Department</router-link>
</li>
<li class="nav-item m-1">
<router-link class="btn btn-light btn-outline-primary"
to="/employee">Employee</router-link>
</li>
</ul>
</nav>
<router-view></router-view>
</div>
<script src="variables.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://unpkg.com/vue#3"></script>
<script src="https://unpkg.com/vue-router#4"></script>
<script src="home.js"></script>
<script src="department.js">
</script>
<script src="employee.js"></script>
<script src="app.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
</body>
</html>
Note the updated URL http/s links and the new method to invoke the vue router.
I am new to Vue js so I wasn't aware of this till my work buddy pointed this out.
This issue is resolved for now

First install vue-router using
npm install --save vue-router
Then only you can use it
import VueRouter from 'vue-router';
Vue.use(VueRouter)
const routes = [ {path: '/', component: SomeComponent} ]

Related

Passing value between files in Vue without node/npm

I'm trying to setup basic prototype web pages to test UX design in code. And want to recycle html files such as left navigation. Trying to use Vue to do this so that I can also learn Vue. I do not have access to the artifactory (company policy). So I cannot use things other than this http vue loader package that I found. So far, I was able to add external vue which is comp-nav. But from here, I want to pass title="Service" from index.html to comp-vue. How do I do that? Any help would be great! BTW, using Apache2 that came with mac to run.
index.html
<!DOCTYPE html>
<html lang="en">
<title>App</title>
<!-- Vue2 -->
<!-- from https://github.com/FranckFreiburger/http-vue-loader -->
<head>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
</head>
<body>
<div id="app">
<comp-nav title="Service"></comp-nav>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
components: {
'comp-nav': httpVueLoader('components/comp-nav.vue')
}
});
</script>
</body>
</html>
components/comp-nav.vue
<template>
<div id="nav">
<div class="nav-header">
<div class="header-title"><a>{{ title }}</a></div>
<div class="header-close">U</div>
</div>
<div class="nav-body">
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</div>
</div><!-- #nav -->
</template>
Based on the example from the docs, you could define a component prop in comp-nav.vue:
<template>
<div class="header-title">{{ title }}</div>
</template>
<script>
module.exports = {
props: ['title']
}
</script>

Primevue Grid and Flex layouts not rendering correctly

Non WebDev here trying to build a basic UI with primevue on vue3. Tried to run the basic demo but with some components included. Don't know if components come with their own CSS dependencies.
Bellow is my html code. I have also tried using a vue project with separate components and gottenthe same result
Basic example fails:
<html>
<head>
<meta charset="utf-8">
<title>PrimeVue Demo</title>
<link href="https://unpkg.com/primevue/resources/themes/saga-blue/theme.css" rel="stylesheet">
<link href="https://unpkg.com/primevue/resources/primevue.min.css" rel="stylesheet">
<link href="https://unpkg.com/primeicons/primeicons.css" rel="stylesheet">
<script src="https://unpkg.com/vue#next"></script>
<script src="https://unpkg.com/primevue/inputtext/inputtext.min.js"></script>
</head>
<body>
<div id="app">
<p-inputtext v-model="val"></p-inputtext>
<h6>{{val}}</h6>
</div>
<div class="p-d-flex">
<div class="p-mr-2">Item 1</div>
<div class="p-mr-2">Item 2</div>
<div>Item 3</div>
</div>
<div class="p-grid">
<div class="p-col-4">4</div>
<div class="p-col">1</div>
<div class="p-col">1</div>
<div class="p-col">1</div>
<div class="p-col">1</div>
<div class="p-col">1</div>
<div class="p-col">1</div>
<div class="p-col">1</div>
<div class="p-col">1</div>
</div>
<div class="p-grid">
<div class="p-col-2">2</div>
<div class="p-col-6">6</div>
<div class="p-col-4">4</div>
</div>
<script>
const {createApp, ref} = Vue;
const App = {
setup() {
const val = ref(null);
return {
val
};
},
components: {
'p-inputtext': primevue.inputtext
}
};
createApp(App).mount("#app");
</script>
</body>
</html>
Should render 1 row for flex items and 2 rows for numbers in grid layout. instead it renders all rows with no styling. What am I missing?:
In order to use prime vue's flex and grid layout, you need to load PrimeFlex.
https://primefaces.org/primevue/showcase/#/primeflex
The documentation only has npm setup but you may be able to include the following link.
<link href="https://cdn.jsdelivr.net/npm/primeflex#2.0.0/primeflex.min.css" rel="stylesheet">
In case you do it through npm, After installing the package, don't forget to include the CSS file, in my case, I included it in my main.js just adding this line.
import 'primeflex/primeflex.css';
https://primefaces.org/primevue/showcase/#/primeflex
The CDN method works!! However I downloaded the file and placed this
<link rel="stylesheet" href="static/primevue/primeflex.min.css" />
inside the head section of my html file.
However it did not work as per the documentation. I had to remove the p- for it to work:
<div id="app" class="grid">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>

VueJS: Call function from bootstrap/jQuery script includes in template/layout from a component

i am very new to VueJS and want to build an Admin Dashboard for an existing bootstrap template (SB Admin Pro). I know there is a BootstrapVUE but we want to use the specified template that we purchased before. So this is not an option for me/us.
My Goal:
In our vue component we make an axios call to our backend to retrieve and show some data. If the call fails we want to call in the catch block a bootstrap function for toast to show some notification to the user (like: Error while fetching data from backend...). We included the bootstrap and jquery libraries from the template in the default index.html.
The Problem:
I don't know how to call the toasts (or other) functions from the vue component. In the template the call looks like this:
$("#toastBasic").toast("show");
Our index.html looks
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="svote UG (haftungsbeschränkt)" />
<script data-search-pseudo-elements defer src="js/font-awesome-5.11.2.min.js" crossorigin="anonymous"></script>
<script src="./js/feather.min.js" crossorigin="anonymous"></script>
</head>
<body class="nav-fixed">
<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 -->
<script defer src="js/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script defer src="js/bootstrap.min.js" crossorigin="anonymous"></script>
<script defer src="js/script.js"></script>
</body>
</html>
Our vue component:
<template>
<main>
<div style="position: absolute; top: 1rem; right: 1rem;">
<!-- Toast container -->
<div style="position: absolute; bottom: 1rem; right: 1rem;">
<!-- Toast -->
<div class="toast" id="toastBasic" role="alert" aria-live="assertive" aria-atomic="true" data-delay="5000">
<div class="toast-header">
<i data-feather="bell"></i>
<strong class="mr-auto">Toast with Autohide</strong>
<small class="text-muted ml-2">just now</small>
<button class="ml-2 mb-1 close" type="button" data-dismiss="toast" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="toast-body">This is an example toast alert, it will dismiss automatically, or you can dismiss it manually.</div>
</div>
</div>
</div>
<ContentHeader title="Blank" icon="fas fa-file" subtitle="A blank page to get you started!" />
<div class="container-fluid mt-n10">
<div v-if="error" class="alert alert-danger" role="alert">
{{ error }}
</div>
<div class="row">
<Card cHeader="Eine Karte" class="col-md-12"> {{ contacts }}</Card>
</div>
</div>
</main>
</template>
<script>
import ContentHeader from '../../components/ContentHeader'
import Card from '../../components/Card'
import axios from 'axios';
export default {
name: "Contact",
components: {
ContentHeader,
Card,
},
data() {
return {
contacts: null,
error: null
}
},
mounted() {
const url = 'http://localhost:3000/v1/';
axios.get(url + 'contsact')
.then(response => {
this.contacts = response.data
console.log(response)}
)
.catch(error => {
console.log(error.response)
$("#toastBasic").toast("show");
});
}
}
</script>
In vue.config.js, specify jquery as external (this tells webpack where to provide jquery from when it's imported in any component):
configureWebpack: {
externals: {
jquery: 'window.jQuery'
}
}
Place all the <script>s you want loaded by the time Vue inits in your public/index.html page, in the <head> tag and remove their defer attribute. This includes any jquery plugin (or anything requiring/extending jquery) you might want to use in your Vue app (in your case, bootstrap.min.js).
The above will make it work when developing (in serve). You'll need to do the same for prod: Load jquery and any dependency before initing the Vue app.
Now you can safely use
import * as $ from 'jquery'
in any component.
Webpack will place in $ whatever window.jQuery is at the moment the component inits.
The above approach makes sure all required scripts are loaded before Vue inits (which is a bit extreme, but it makes sure there's no way you can call the jquery method before its dependencies are loaded).
If you don't want to wait for jquery and bootstrap.min.js to load before you init your Vue app, a trick you could use is to assign jquery from window object just before you need it:
yourAlertMethod() {
const $ = window.jQuery;
$.toast()...
}
Obviously, you no longer have to move all the scripts in <head> and to remove their defer. This second method doesn't guarantee they would have already loaded before your method is first used. But your app inits faster.
Here's a basic example.
I used the second method, codesandbox.io doesn't have support for #vue/cli v3 hence vue.config.js doesn't work as in a Vue project created with vue create. Therefore, I had to use the second method.
The full list of dependecies you need to load before you call the $(el).toast() method:
bootstrap.min.css
jquery.js
popper.js
bootstrap.min.js
(see them in public/index.html). You can copy/paste them from Bootstrap.
You can get ref of the element and pass it to jQuery
<div ref="toast" class="toast" id="toastBasic" role="alert" aria-live="assertive" aria-atomic="true" data-delay="5000">
import $ from 'jQuery';
$(this.$refs.toast).toast("show");
I don't recommend that though.

Vue CLI Insert Navbar

So I've installed the latest Vue CLI and have a project set up. I am familiar with the concepts of Vue but I need help with structure. Can somebody guide me as to how I could create a navigation bar that would be used across all pages and would contain vue-router links for pages? My first thought was to make a component Navbar.vue and somehow get that into the App.vue so that it is rendered before any <router-view></router-view>. Is this the proper way to do it? Would I instead try to put it inside index.html? I am confused as to how to do this. I am using bootstrap for css.
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>foo.ca</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
App.vue:
<template>
<div id="app">
<!--<img src="./assets/logo.png">-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
You should add into App.vue. Index.html will only render the app.
Remember that router-view will only render the component you set(in the router configs) for the route inside the <router-view></router-view> call. App is just like a layout for your app.
<template>
<div id="app">
<!--<img src="./assets/logo.png">-->
<!-- Assuming your navbar is looking like bootstrap -->
<navbar></navbar>
<!-- You can move container inside every page instead, if you wish so -->
<div class="container-fluid">
<div class="row">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>

Not able to find property

I have a very simple local setup for VueJS and am having problems running a simple example that shows how raw HTML can be output. I'm not including link to JS Fiddle because I want to make it work on local setup only, and sometimes my examples work on JS Fiddle but not on local machine.
Anyway, here's the html code:
<html>
<head>
<script src="https://unpkg.com/vue"></script>
<script src="app.js"></script>
</head>
<body>
<div id="app">
<!-- Doesn't work! -->
<p>{{ link }}</p>
<!-- This works! -->
<p v-html>{{ link }} </p>
</div>
</body>
</html>
And here's my app.js file:
window.addEventListener('load', function(){
new Vue({
el: '#app',
data: {
link: 'Google'
}
});
});
Now when I load the window, I get twice the following error:
[Vue warn]: Property or method "link" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in <Root>).
Any idea where I'm going wrong?
Can you try this one and see if it works as required. I moved the scripts after the body.
<html>
<head>
</head>
<body>
<div id="app">
<!-- Doesn't work! -->
<p>{{ link }}</p>
<!-- This works! -->
<p v-html>{{ link }} </p>
</div>
</body>
<script src="https://unpkg.com/vue"></script>
<script src="app.js"></script>
</html>