Vue component/data not rendering - vue.js

I have a python project (using flask) where I am trying to use Vue with. The problem is that nothing vue related renders if I go peek the html definition.
I've installed vue via npm, also installed webpack and laravel-mix. They seem to be well configured.
I have the instance
import Vue from 'vue';
import alert from './components/Alert.vue';
new Vue({
el: '#app',
delimiters: ['[[', ']]'],
data: {
test: 'is it working?'
},
components: {
alert
}
});
The component
<template>
<div class="alert" v-text="message"></div>
</template>
<script>
export default {
name: 'alert',
data() {
return {
message: 'I am an alert.'
};
}
};
</script>
<style>
.alert {
background: red;
}
</style>
And I am just trying to render the message
<div class="mdl-card__title mdl-color--primary mdl-color-text--white relative">
<h2 class="mdl-card__title-text">Login</h2>
</div>
<div id="app">
[[ test ]]
</div>
but when I try peeking in the html I see nothing.
Component not showing bellow the Login h2 tag
Package.json
{
"name": "I've hidden it",
"version": "1.0.0",
"description": "<h1>I've hidden it</h1>",
"main": "webpack.mix.js",
"directories": {
"test": "tests"
},
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"repository": {
"type": "git",
"url": "i've hidden it"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"laravel-mix": "6.0.6",
"postcss": "8.1",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14"
},
"dependencies": {
"vue": "^2.6.14"
}
}

On running npm mix, laravel-mix will compile the file you've provided to mix.js function and save it to the second parameter of the function, which is public/js directory in your project. The .vue() tells laravel-mix that it is a vue app entry point.
Once its compiled, you need to import the compiled scripts into your html.
<script src="public/js/main.js"/>
Now your Vue app should work fine.

Related

Why does vue.js not work inside html files?

I wanted to add Vue.js to my Spring Boot application. Even though everything seem to build fine, I cannot make vue component work.
Here is my simple component, MenuBar.vue:
<template>
<div>
Menu
</div>
</template>
<script>
export default {
name: "MenuBar"
}
</script>
And here is HTML which should be using it:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Dashboard</title>
</head>
<body>
<div id="vueApp">
<menu-bar></menu-bar>
</div>
<form th:action="#{/logout}" method="post">
<div><input type="submit" value="Log out"/></div>
</form>
</body>
</html>
Configuration files index.js:
import Vue from "vue";
import App from './App.vue'
Vue.config.devtools = true;
new Vue({
el: '#app',
template: '<App/>',
components: {App}
});
new Vue({
el: '#vueApp'
})
components.js:
import Vue from 'vue';
import MenuBar from "./components/MenuBar";
Vue.component('menu-bar', MenuBar);
And webpack config file:
// webpack.config.js
const {VueLoaderPlugin} = require('vue-loader');
const path = require('path');
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
entry: {
main: path.resolve(__dirname, './src/index.js')
},
resolve: {
extensions: ['.vue', '.js'],
alias: {
'components': path.resolve(__dirname, './src/components/')
}
},
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
],
devServer: {
hot: false,
liveReload: true,
proxy: {
"*": {
target: 'http://localhost:8080',
ignorePath: false,
changeOrigin: false,
secure: false
}
},
port: 8081,
host: "0.0.0.0"
},
output: {
publicPath: '/dist/',
path: path.resolve(__dirname, './src/main/resources/static/dist')
}
}
When I build npm and run application page contains element <menu-bar></menu-bar> but does not load its content. What could be an issue here?
The problem is that you add the component inside of <div id="vueApp"> at:
<div id="vueApp">
<menu-bar></menu-bar>
</div>
In this case, your app renders inside of this <div id="vueApp"> tag. Everything you write inside of this tag at your html file, will be overwritten.
You have another file named App.vue. You should add your MenuBar.vue component to this main component and it should show.
EDIT: Easiest attempt to get your component to work
This ist the main.js:
import { createApp } from 'vue'
import App from './App.vue'
// Create app
const app = createApp(App);
// Import component
import MenuBar from "./components/MenuBar";
// Use MenuBar
app.component('MenuBar', MenuBar);
// Mount app
app.mount('#app')
This is the App.vue:
<template>
<div>
<MenuBar></MenuBar>
Body
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
This is the MenuBar.vue:
<template>
<div>
Menu
</div>
</template>
<script>
export default {
name: "MenuBar"
}
</script>
As we have a slight different approach I will also give you the package.json, so you can just hit npm install and it should implement all the (few) packages includet in this app:
{
"name": "q68966956",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0"
},
"devDependencies": {
"#vue/cli-plugin-babel": "~4.5.0",
"#vue/cli-plugin-eslint": "~4.5.0",
"#vue/cli-service": "~4.5.0",
"#vue/compiler-sfc": "^3.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
It looks like you are in a early stage with your project, so maybe you can start with a stable base from that code. Let me know, if it helped you.

Why am I getting "Cannot find module..." Typescript error for ".vue" file on webpack-dev-server recompilation?

I've setup a small webpack project which creates a Vue app bundle which is included in a static HTML file where the app is injected. I want to have components written in Typescript so I've included ts-loader in the webapck configuration. The build process - using the "webpack" command - works ok, but I'm having some trouble when I use webpack-dev-server.
When I initially start the server, everything works fine: the bundle is created and served on my local server and the browser displays the app correcly. However, when I make a change in the source code and save, I get a Typescript error when the code is recompiled telling me that a module or declaraton is missing for the ".vue" file for my component:
TS2307: Cannot find module './components/Banner.vue' or its corresponding type declarations.
To start the server I use the following command:
webpack serve --open
Project's folder structure
=======
webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')
const path = require('path')
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: {
app: './src/app.js',
},
output: {
filename: '[name].bundle.js',
},
plugins: [
new VueLoaderPlugin(),
],
devServer: {
contentBase: path.join(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
},
{
test: /\.ts$/,
loader: 'ts-loader',
exclude: [/node_modules/],
options: { appendTsSuffixTo: [/\.vue$/] }
},
],
},
}
app.js
import Vue from 'vue'
import App from './App.vue'
const app = new Vue({
render: (h) => h(App)
})
app.$mount('#app')
App.vue
<template>
<div id="app">
<h1>{{ welcomeMessage }}</h1>
<Banner />
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import Banner from './components/Banner.vue'
export default Vue.extend({
components: {
Banner,
},
data: () => ({
welcomeMessage: 'Hello world!'
})
})
</script>
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"strict": true,
"module": "es2015",
"moduleResolution": "node"
}
}
#types/vue-shims.d.ts
declare module "*.vue" {
import Vue from 'vue'
export default Vue
}
package.json
{
"name": "2021-06-21-webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"dev": "webpack serve --open"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"ts-loader": "^8.3.0",
"typescript": "^4.3.4",
"vue-loader": "^15.9.7",
"vue-template-compiler": "^2.6.14",
"webpack": "^4.46.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
},
"dependencies": {
"vue": "^2.6.14"
}
}

Vue3 / Vite: How to package components for publishing on npm

I'm trying to export two web components in a public package on npm, using Vite with TypeScript.
Vite has a Library Mode (https://vitejs.dev/guide/build.html#library-mode) which works well. The ESM and UMD files are both being transpiled into my /dist directory. My question is how to export the web components in the entry point file.
I have an entry point file called export.js
import AwesomeHeader from './components/AwesomeHeader.vue'
import AwesomeFooter from './components/AwesomeFooter.vue'
export default { // I feel like the problem is here.
components: {
AwesomeHeader: AwesomeHeader,
AwesomeFooter: AwesomeFooter,
}
}
The idea is that I'll npm publish the project and use it like this.
npm i #sparkyspider/awesome-components #(ficticious example)
import {AwesomeHeader, AwesomeFooter} from '#sparkyspider/awesome-components' // does not find
(AwesomeHeader and AwesomeFooter are not found as exports in the node_module, even though the JavaScript files are referenced / found)
My package.json below:
{
"name": "#sparkyspider/awesome-components",
"version": "1.0.8",
"files": [
"dist"
],
"main": "./dist/awesome-components.umd.js",
"module": "./dist/awesome-components.es.js",
"exports": {
".": {
"import": "./dist/awesome-components.es.js",
"require": "./dist/awesome-components.umd.js"
}
},
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"serve": "vite preview"
},
"dependencies": {
"vue": "^3.0.5"
},
"devDependencies": {
"#vitejs/plugin-vue": "^1.2.2",
"#vue/compiler-sfc": "^3.0.5",
"typescript": "^4.1.3",
"vite": "^2.3.3",
"vue-tsc": "^0.0.24"
},
}
You are having object { component: ... } as default export, instead of exporting AwesomeHeader and AwesomeFooter, which you try to import.
export { AwesomeHeader, AwesomeFooter } in export.js will work.
More on export: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
And you can't destruct default export: https://stackoverflow.com/a/43987935/8810271

Vue App Blank page in IE-11 and Ms Edge 40

I was given a Vue app that is working perfectly in Chrome, Firefox.
But blank page in IE-11 and Ms Edge. No Erorrs in console.
I'm not a Vue developer but I'm interested in Vue. So Tried to find a solution googling it. But no of those solutions works for me. Can someone please tell me what should I do to fix this blank page issue in IE-11 & Edge?.
main.js
import 'babel-polyfill'
import Vue from 'vue'
import Request from './http/request'
const EXCLUDED_PROD = [
'52.59.217.237',
'localhost'
]
babel.config.js
module.exports = {
presets: [
['#vue/app', {
polyfills: [
'es6.promise',
'es6.symbol'
]
}]
]
}
index.html
<!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.0">
<link rel="icon" href="<%= BASE_URL %>fav.png">
<title>Starline Security</title>
</head>
<body>
<noscript>
<strong>We're sorry but Starline Security doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!--built files will be auto injected-->
</body>
</html>
package.json
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
How do you create your vue project? I create vue project according to this link and choose default. It can run well in IE and Edge without installing other packages.
I compared the files in the working project with yours and the babel.config.js and package.json are different. You could try to edit your babel.config.js and package.json according to below.
babel.config.js:
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset'
]
}
package.json:
{
"name": "hello-world",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
"devDependencies": {
"#vue/cli-plugin-babel": "^4.4.0",
"#vue/cli-plugin-eslint": "^4.4.0",
"#vue/cli-service": "^4.4.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
Besides, it seems that your main.js is not complete. Mine is like this:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')

Why is lodash not working when I import it in Vue.js

I created a fresh new install of vue.js using "vue create todo --default" command. After that I installed lodash too with this command "npm i --save lodash". I can see it in my package.json on the "dependencies" object. The problem is that when I import it on my main.js and use the lodash functions, it is showing the error "_ is not defined". So I tried importing it inside the App.vue. The error "_ is not defined" was removed but it is not working.
Here are the code inside the App.vue, main.js, and package.json
main.js
import Vue from 'vue'
import App from './App.vue'
import "bootstrap/dist/css/bootstrap.min.css";
import "jquery/dist/jquery";
import "bootstrap/dist/js/bootstrap.min";
import _ from "lodash";
Vue.prototype._ = _;
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div id="app">
<h4 class="bg-primary text-white text-center p-2">
{{name}}'s' To Do List
</h4>
<div class="container-fluid p-4">
<div class="row">
<div class="col font-weight-bold">Task</div>
<div class="col-2 font-weight-bold">Done</div>
</div>
<div class="row" v-for="t in completedtask" v-bind:key="t.action">
<div class="col">{{t.action}}</div>
<div class="col-2">
<input type="checkbox" v-model="t.done" class="form-check-input">
{{t.done}}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
name: "Welly",
tasks: [{
action: "Buy Flowers",
done: false
},
{
action: "Get Shoes",
done: false
},
{
action: "Collect Tickets",
done: true
},
{
action: "Call Joe",
done: false
}
]
};
},
computed: {
hidecompletedtask(){
return _.map(this.tasks,(val)=>{
return !val.done;
});
}
}
}
</script>
<style>
</style>
package.json
{
"name": "todo",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"bootstrap": "^4.4.1",
"core-js": "^3.4.4",
"jquery": "^3.4.1",
"lodash": "^4.17.15",
"popper.js": "^1.16.1",
"vue": "^2.6.10"
},
"devDependencies": {
"#vue/cli-plugin-babel": "^4.1.0",
"#vue/cli-plugin-eslint": "^4.1.0",
"#vue/cli-service": "^4.1.0",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
You'll still need to access the prototype via the this context, like this._.map().
computed: {
hidecompletedtask() {
return this._.map(this.tasks, (val) => {
return !val.done;
});
}
}
Reference: Adding Instance Properties.
Alternatively, you could extend the global window object. Put the following line in your main.js (or some booting file).
window._ = require('lodash');
Somewhere else where you need the library:
computed: {
hidecompletedtask() {
// The underscore (_) character now refers to the `window._ object`
// so you can drop the `this`.
return _.map(this.tasks, (val) => {
return !val.done;
});
}
}
You can also use vue-lodash package -- Follow these steps:
npm install --save vue-lodash
in main.js -- import VueLodash from 'vue-lodash'
in main.js after import -- Vue.use(VueLodash)
Usage:
Vue._.random(20);
this._.random(20);
-------- OR ------------
In your main.js add this line of code:
window._ = require('lodash');
That way it will work without Vue or this:
Just do -- _.map()
You can import lodash in your main.js file by javascript window object like this:
window._ = require('lodash');
Then use it anywhere in your projet like this:
var original = [
{ label: 'private', value: 'private#johndoe.com' },
{ label: 'work', value: 'work#johndoe.com' }
];
var update = [
{ label: 'private', value: 'me#johndoe.com' },
{ label: 'school', value: 'schol#johndoe.com' }
];
var result = _.unionBy(update, original);
var sortedresult = _map(_.sortBy(result, 'label'));
console.log(sortedresult);
I just use lodash unionBy and sortBy method for example.