Vue.js Declarative rendering not working after webpacking - npm

Below is my index.html file
<!doctype html>
<html><head>
<body>
<h1>ES</h1>
<div id="app">
{{ message }}
</div>
<script src="dist/main.js" type="text/javascript"></script></head>
</body>
</html>
I am trying to use basic vue.js declarative rendering. My index.js input for webpack with zero configuration is below
import Vue from 'vue';
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
The value of message is not shown in the page . Is this something to do with my webpack configuration. Do I need to use Babel transpiler to get this to work?

See Explanation of Different Builds in the doc.
The default file for these bundlers (pkg.module) is the Runtime only
ES Module build (vue.runtime.esm.js).
Vue build with runtime only doesn't include HTML template compiler, which you need in your case. (Runtime only build is 30% smaller in size)
As the doc mentioned, to import full build of Vue, you may use
import Vue from 'vue/dist/vue.esm.js';
Btw, I highly recommend you to use vue-cli instead of configuring the Vue project yourself.

Related

How to make Vue 3 application without CLI / Webpack / Node

I am trying to make Vue 3 application but without CLI and Webpack.
There is no official documentation yet. On CDN are many versions (vue.cjs.js, vue.cjs.prod.js, vue.esm-browser.js, vue.esm-bundler.js, vue.global.js, vue.runtime.global.js...).
Which one to pick? And how to mount application, old way does not work. There are many online examples how works new Composition API but none how to start project without CLI / Webpack.
Link to Vue 3 CDN:
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>
In body:
<div id="app">
</div>
<script type="module">
import app from './app.js'
const {createApp} = Vue;
createApp(app).mount('#app');
</script>
In app.js is simple component:
export default {
name: 'Test',
setup() {
const title = "Hello";
return {
title
};
},
template: `
<div>
<h1>{{title}}</h1>
</div>
`,
};
Instead of one component, app.js can be a container for other components.
I made simple Vue 3 QuickStart template so anyone can see how this works.
Template is in SPA-like style and contains 4 sample pages, 4 components, routing and store. It uses only Vue.js from CDN, everything else is hand made ;)
Note: This is not library, it's just demo code so anyone can see how to mount Vue 3 application and use Composition API in simple scenario.
Online demo: http://vue3quickstart.rf.gd/
GitHub: https://github.com/SaleCar/Vue3-QuickStart
Found in docs: https://vuejs.org/guide/quick-start.html#without-build-tools
Without Build Tools
To get started with Vue without a build step, simply copy the following code into an HTML file and open it in your browser:
<script src="https://unpkg.com/vue#3"></script>
<div id="app">{{ message }}</div>
<script>
Vue.createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
The above example uses the global build of Vue where all APIs are exposed under the global Vue variable.
While the global build works, we will be primarily using ES modules syntax throughout the rest of the documentation for consistency. In order to use Vue over native ES modules, use the following HTML instead:
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue#3/dist/vue.esm-browser.js"
}
}
</script>
<div id="app">{{ message }}</div>
<script type="module">
import { createApp } from 'vue'
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
Notice how we can import directly from 'vue' in our code - this is made possible by the <script type="importmap"> block, leveraging a native browser feature called Import Maps. Import maps are currently only available in Chromium-based browsers, so we recommend using Chrome or Edge during the learning process. If your preferred browser does not support import maps yet, you can polyfill it with es-module-shims.
You can add entries for other dependencies to the import map - just make sure they point to the ES modules version of the library you intend to use.
Not for production
The import-maps-based setup is meant for learning only - if you intend to use Vue without build tools in production, make sure to check out the Production Deployment Guide.
In addition, as Evan You recommended, Vite(https://madewithvuejs.com/vite) is a good alternative to #vue/cli and webpack. It's still CLI like but more lightweight I think. Fast and supports SFC.

Setting up a simple example of page routing using vue-router on vue-cli

I am trying to get the simplest of page routing working using vue-cli.
I have been trying to follow the Vue-router documentation (https://router.vuejs.org/guide/#html) as well as various other guides I have come across on google and have not been successful getting anything working on vue-cli.
I was able to get the example shown here: https://www.tutorialspoint.com/vuejs/vuejs_routing working, which does not use vue-cli. From there I tried to 'copy' that example into vue-cli to see if I can get it to work.
My main.js file looks like this:
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
Vue.config.productionTip = false
const Route1 = { template: '<div>router 1</div>' }
const Route2 = { template: '<div>router 2</div>' }
const routes = [
{ path: '/route1', component: Route1 },
{ path: '/route2', component: Route2 }
];
const router = new VueRouter({
routes
});
new Vue({
el: '#app',
router,
render: h => h(App)
});
And my App.vue file looks like this:
<template>
<div id="app">
<h1>Routing Example</h1>
<p>
<router-link to = "/route1">Router Link 1</router-link>
<router-link to = "/route2">Router Link 2</router-link>
</p>
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</script>
It does not work. I have tried both direct access to the dist/index.html on the file system and viewing the app on localhost, using npm run serve. I see the page but the <router-link> tags render only as <router-link>, not as anchor (<a>) tags. It is impossible to click on them and thus no routing is happening.
The page in my browser has the following source:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="favicon.ico">
<title>ucic</title>
<link href="js/app.a486cc75.js" rel="preload" as="script">
<link href="js/chunk-vendors.a6df83c5.js" rel="preload" as="script">
</head>
<body>
<noscript><strong>We're sorry but ucic doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
<div id="app">
<h1>Routing Example</h1>
<p>
<router-link to="/route1">Router Link 1</router-link>
<router-link to="/route2">Router Link 2</router-link>
</p>
<router-view></router-view>
</div>
<script src="js/chunk-vendors.a6df83c5.js"></script>
<script src="js/app.a486cc75.js"></script>
</body>
</html>
There are no console errors and no errors trying to download javascript files.
Can anyone point me in the right direction? What am I doing wrong?
Update:
As Pukwa has mentioned, I did not correctly mount the application. After doing so I no longer receive a white screen, but as mentioned above, the <router-link> tag is not rendering as an anchor but literally as a <router-link> tag. The javascript is obviously doing something, or else even that wouldn't show up on the page.
I've updated my question rather than ask a new one as my original problem has not been solved (vue-router is still not working) and this is only one of many iterations to try and get this to work (I have, on previous iterations, had the application correctly mounted and seen the error described above).
I guess you did not mount your application inside of main.js
new Vue({
el: '#app',
router,
render: h => h(App)
});
I had to apply three fixes to make this code work:
mounting the application as identified by Puwka in their answer
Adding Vue.use(VueRouter); in main.js (I got help from answers to this question: [Vue warn]: Unknown custom element: <router-view> - did you register the component correctly?)
Adding "runtimeCompiler": true to vue.config.js (I got help from answers to this question: Vue replaces HTML with comment when compiling with webpack and this: https://cli.vuejs.org/config/#runtimecompiler)
Additionally, I was not able to see logs in the console because it seems vue or npm turns off logging? (I have to use // eslint-disable-next-line no-console before I can use a console.log statement).
A comment to this question Vue router does not render/mount root path component helped me to resolve that problem. Somehow, after logging out this.$router.currentRoute.path in a mounted function I was able to see the errors in the developer console.

Expressing Vue dependencies w/Browserify & CommonJS

I am experimenting with Vue and would like to develop a node app with my usual setup which uses budo(browserify + watchify).
./index.html:
<div id="app">
{{ message }}
</div>
<!-- ===================== JavaScript Files Below This Line =============== -->
<script src="index.js"></script>
and ./src/js/main.js
const Vue = require('vue');
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
module.exports = app;
with ./index.js
// js includes
require('./src/js/main');
I cant see the message on the page. I see index.js in the console with main.js injected into it. When I use the Vue CDN with the vue code in index.html that works ok. I was hoping someone could shed some light on how one uses CommonJS modules to import vue code into their app when bundling w/browserify. Thanks in advance...
As explained here Vue.js not rendering you need to add this to your
package.json file:
"browser": {
"vue": "vue/dist/vue.common.js"
}

Header and footer component in Vue.js

I am learning Vue.js, I am not using cli for Vue.js installation, I just downloaded Vue.js file and trying to learn it.
My issue is to externalize components like header.vue and footer.vue and add them to main component.
I used Vue.component('MyHeader', require('./components/Header.vue')); to load component but I was getting error like "Uncaught ReferenceError: require is not defined".
To resolve this error I downloaded require.js file from here but I am still unable to load component files.
Folder Structure
index.html
<!DOCTYPE html>
<html>
<head>
<title>this is example of header and footer</title>
</head>
<body>
<div id='root'>
<testcomponent></testcomponent>
<MyHeader></MyHeader>
<div>I am Content</div>
<MyFooter></MyFooter>
</div>
<!-- we need this two files for vue js -->
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript" src="require.js"></script>
<!-- End of we need this two files for vue js -->
<script type="text/javascript" src="indexController.js"></script>
</body>
</html>
indexController.js
//rout file for vue js
Vue.component("testcomponent",{
template:'<p>I am Test Component</p>'
});
Vue.component('MyHeader', require('./components/Header.vue'));
Vue.component('MyFooter', require('./components/Footer.vue'));
//import MyHeader from './components/Header.vue'
//import MyFooter from './components/Footer.vue'
var app = new Vue({
el: "#root",
components: {
MyHeader,
MyFooter
},
data: {
},
methods:{
}
});
Header.vue
<template>
<h1>I am Header</h1>
</template>
Footer.vue
<template>
<h1>I am Footer</h1>
</template>
Single file component (.vue)
You need vue-loader to convert .vue files to normal js format.
If you will read the documentation at https://v2.vuejs.org/v2/guide/single-file-components.html, you basically need to use webpack or browserify to use .vue files extensions.
As it says in the comments, you need a build tool to use .vue files. But you can get all the goodness of components, except scoped css, by using plain .js files.
Put your templates in .js template strings, then call your components the old way, with <script src="urlOfFile.js">, or call them with requirejs, but they need to be plain .js files, not .vue.
CommonJS using require (not to be confused with require.js which is using AMD):
Instead of Header.vue create Header.js which you then can require just like you do:
module.exports = {
template: `<template>
<h1>I am Header</h1>
</template>`
}
ES6 export / import
If you want to use ES6 import instead of require, this would be the content of Header.js:
export default {
template: `<template>
<h1>I am Header</h1>
</template>`
}
To work with .vue component files and structuring, you need vue-webpack-loader and a build stack involving something like webpack or browserify.
See
https://v2.vuejs.org/v2/guide/single-file-components.html#For-Users-New-to-Module-Build-Systems-in-JavaScript
If you are just starting with Vue and all the JS magic I would look into the vue cli install approach link. It should install webpack and all the things needed for single page components then you can work backward to deconstruct the pieces of that setup.
You can also look at the examples in the vue GitHub repos. link
That example is using vuex along with single file components but it is solid.

VueMdl components not registered correctly

I'm using Vue 2.0 + VueRouter and trying to integrate VueMdl (https://posva.net/vue-mdl/#/usage) components into my project.
The site is running as a static resource served by Spring Boot using an embedded Apache Tomcat, so consider that the frontend isn't running in a NodeJs environment.
The problem is I can't figure out why the VueMdl components aren't registered correctly. The require() function doesn't work since it's specific to NodeJs and in the browser developer console, if I type VueMdl or console.log(VueMdl) ... I can see that the object is defined as well.
Thank you in advance,
app.js
const router = new VueRouter({
routes: routes
})
// load main Vue.js app
var app = new Vue({
el: '#app',
router: router,
components: VueMdl.components,
directives: VueMdl.directives
})
index.html
<html>
<head>
[....]
</head>
<body>
[....]
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.min.js"></script>
<script src="//rawgit.com/posva/vue-mdl/master/dist/vue-mdl.min.js"></script>
<script src="app.js"></script>
</body>
</html>
error text
[Vue warn]: Unknown custom element: <mdl-textfield> - did you register the
component correctly? For recursive components, make sure to provide the "name" option.
(found in <Anonymous> - use the "name" option for better debugging messages.)
I think you need to import it :
var VueMdl = require('vue-mdl');