Vue.js links are not clickable, and Home component does not load by default - vue.js

Ok, I am JUST getting started with vue.js. I've added a TypeScript vue.js project into an exiting Visual Studio 2017 solution. Out of the box that worked pretty well.
But now, I'm trying to do something that should be pretty simple... create some pages and navigate between them. I've found 3 or 4 tutorials but none of them match enough what I already have to make them adaptable, and I'm having a hard time finding what I need in vue.js's documentation.
Here's a screenshot of what my project looks like right now....
And here's the App.vue file:
And this is the router/index.js file:
With all of this, here's what is rendered in the browser:
This ALMOST correct except for two things:
1) The links for Home and Time Sheet are not rendered as clickable html links. This is what they look like in dev tools:
2) I thought that the Home component would be loaded by default, but it's not.
So, two questions:
1) How fo I make the links clickable?
2) Why doesn't Home load by default?
EDIT:
Here's the main.ts file:

You would need to set up vue-router on your main.js file as well. here is an example:
import router from './router'
new Vue({
render: h => h(App),
router
}).$mount('#app')

Related

Vuepress dynamic routes and render as page?

I use vuepress as a mixed solution of static generated pages and dynamic pages in the SPA approach. The dynamic data source is a large database server, hence it can not use the additionalPages feature introduced in vurepress 1.x. That means dynamic routes was added using enhanceApp.js as below. Dynamic pages are rendered with extended layouts to share same page structure (header, footer).
// Foo is a layout component extends from Layout.vue
import Foo from './layouts/Foo.vue'
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData // site metadata
}) => {
router.addRoutes([
{ path: '/foo/:id', component: Foo },
]);
}
It works, however the layouts/Foo.vue is a component. It missing frontmatter, markdown syntax like normal markdown page does. The question is how to load a markdown page and pass to routes as component?
I'm still new to Vuepress, but I come across this comment in the source code that might be able to help you.
When Vue SFCs are source files, make them as layout components directly
I haven't finished reading all source code, so I'm not very sure I understand it correctly. But I guess when Vuepress find a vue component, it will not render it like a markdown file. It assumes you have your own style inside the .vue file. So I think that may be why you are missing what normal markdown page has.
However, if you need to mix a dynamic data source with static pages, you can try to use Vue in markdown to get what you want to achieve.

Why router link have diferent behavior in mobil view?

When I use router links in desktop view works fine but in mobile view the links lack the "/" to work, any idea to make it work for mobile (I mean when max-width change) (bootstraps makes all the jobs). I think a parameter or something to keep it working if bootstraps changes to a copy the menu adapted to mobile screen. In that swap of styles bootstrap stripes the "/" to the links with router vue link to. Any advice, suggerence or sample link will appretiated.
You should read this.
Vue Router Child, Trailing slash
Also to prevent this you can use strict in vue-router as follows
const route1 = { template: '<div>Route 1 (strict)</div>' }
const route2 = { template: '<div>Route 2 (no strict)</div>' }
Check the fiddle link
http://jsfiddle.net/L7hscd8h/9377/

Vue component name must be lowercase?

I am trying to use a component in my view file. The following doesn't work
When I try to mount the component in my view with <CampaignCreate></CampaignCreate>
const app = new Vue({
el: '#rewards-app',
components: {
CampaignCreate,
}
});
If I change it to:
const app = new Vue({
el: '#rewards-app',
components: {
'campaign-create': CampaignCreate,
}
});
I can mount the component in my view file as <campaign-create></campaign-create> without a problem. I am trying to understand the reason behind this. I am currently on vuejs 2.x
In short, it's because HTML is case-insensitive. There was a big discussion in VueJS tracker opened 2 years ago by Evan You himself with the following reasoning:
So as we all know, HTML is case insensitive. myProp="123" gets parsed
as myprop="123" and this has led to the caveat in Vue.js where you
have to use my-prop="123" to refer to a prop declared in JavaScript as
myProp. This bites beginners quite often.
The issue was eventually closed with decision to stay on the same track. Here's a telling quote:
Essentially, the problem exists because js and html are different
technologies and use different naming systems. And using same
case(kebab or camel) in both technologies will shift weirdness from
one place to another but the underlying problem will persist So I
believe, best we can do is draw a line. and the current line i,e.
kebab case in html context and camelCase (and PascalCase) in js
context is very good.

Is it possible to make a distributable Vue widget with Single File Components?

This might be a bit of an odd question, but I'll try to explain.
I'm looking to build a vue based video player widget for a client's Drupal website. The idea is to create something he can just drop in, like a JQuery plugin. However, I'd really like to leverage Vue's Single File Components (with Webpack) so I can keep everything all bundled together.
My first thought would be to use the Vue CLI, npm build and then reach into the dist/ folder and pull out the following to drop in:
<link href=/static/css/app.cf6f127cf50f4c0b2424d30fdc56c3a4.css rel=stylesheet>
<div id="my-widget"></div>
<script type=text/javascript src=/static/js/manifest.e12c1c4a9566f686d69f.js></script>
<script type=text/javascript src=/static/js/vendor.47037dd92c40b3f38949.js></script>
<script type=text/javascript src=/static/js/app.3f1bab5cc5b1be1127b2.js></script>
Although this feels off, is there a better way to achieve this? Keep in mind his website is NOT a Vue app, but I want this widget to be built LIKE a Vue app.
I don't know if I understand 100 percent, as far as I know, it is possible. It doesn't matter how you bundle your app. It is a matter of architecture. You can use vue.js partly, like widget.
First when you set Vue instance, just set element with your target element.
new Vue({
el: '#my-widget'
});
If you want your client to set element himself, make some functions to create vue widget. (considering multiple vue instance or state sharing blah blah...)
// you can provide simple function like this (I'm sure it needs to be more.)
const Widget = {
createWidget(el) {
new Vue({
el: el
});
}
};
// on client side
Widget.createWidget('#his-widget');
On bundling, if you want your widget to be bundled together with client's Drupal website. Let him import your widget like other libraries. You can build your widget with npm run build in vue-cli and then give it to him so that he can include it.
Thanks to #yuriy636 for answering my question. The CLI 3.0 allows to build as a library or a web component. docs
Also I found the following article which goes into more depth
https://vuejsdevelopers.com/2018/05/21/vue-js-web-component/

multiple pages app and vuejs

I am trying to use vuejs in a multiple pages app, say I have two pages:
/home and /account, I created two js files, home.js and account.js, home.js is included in home.html and account.js is included in account.html, this works quite well until I started to use webpack 4, webpack combines files into a single main.js, how to work with a single main.js in my use case? thanks
You should be able to have more than 1 Vue instance, for example, for home.js:
new Vue({
el: '#home'
...
and for account.js:
new Vue({
el: '#account'
...
and then just wrap the content of home.html with an id="home" and wrap the content of account.html with id="account"
You can take a look at this template as an example or starting point. The idea is the same no matter the backend technology.
https://github.com/danijelh/aspnetcore-vue-typescript-template
You can create modules for pages which you want to enhance with Vue and import its bundle. There's also a medium article for more details :)