Vue: How to change tab title in Chrome - vue.js

How do I change the default "Webpack App" tab title in Vue.js?

In Your public/index.html or other HTML files used as templates by html-webpack-plugin. find title tag and change it
<title>Page Title</title>
Or you can set the page title dynamically by getting the title from document document.title and change it inside your component like the code below :
<template>
<div id="app"></div>
</template>
<script>
export default {
name: "App",
mounted() {
document.title = "page title";
},};
</script>

you have at least two options:
document.title = 'Your new name'
or in the index.html-file:
<head>
<title>Your new name</title>
</head>

You will find <title>Webpack App</title> in index.html in most probably public folder. You can change it

We needed to fix this in the webpack config which generated the index.html every time we deployed our Storybook app.
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = async ({ config }) => {
config.plugins.push(
new HtmlWebpackPlugin({ title: 'Storybook — Company Name' }),
)
return config
}

Related

How to render html partial in vue 3 router

In my apps I have a couple of pages that show some embedded forms...
The forms come from jotform, and are embedded with a js script like this
<section>
<script type="text/javascript" src="https://form.jotform.com/jsform/123124124"</script>
</section>
I cannot find a way to load this inside a component, so I'm trying to use a simple HTML partial. Is there a way to do this?
I try also with a component but it doesn't work
<script>
export default {
data: () => ({
}),
mounted() {
const scripts = [
"https://form.jotform.com/jsform/123124124124"
];
scripts.forEach(script => {
let tag = document.head.querySelector(`[src="${ script }"`);
if (!tag) {
tag = document.createElement("script");
tag.setAttribute("src", script);
tag.setAttribute("type", 'text/javascript');
console.log(document.body);
setTimeout(function() {
document.body.appendChild(tag);
}, 500)
}
});
}
}
</script>
<template>
<main class="main">
<h1 class="visuallyhidden">Funding Request</h1>
<section class="funding">
</section>
</main>
</template>
As suggested here you can try to use the iFrame version: https://www.jotform.com/help/148-getting-the-form-iframe-code/
FYI: including an embed script within a dynamic vue component is not an easy thing (as the JotForm support explaned here), so you might try to go for the iFrame version if it works for you :)

Font Awesome embed code not working in project generated with Vue CLI

I created a default Vue project with the Vue CLI, and got an embed code sent to my email for Font Awesome 5. I added that code to my project index.html in the public folder.
<head>
<script src="https://use.fontawesome.com/8e1c33adc2.js"></script>
</head>
I'm using this in a component template:
<i class="fas fa-trash"></i>
It just shows up as a box.
Do I have to do something special to get the embed code to work in my Vue component, like adding it to main.js?
I have had issues with font-awesome with vue. The solution for my problem was to use vue-fontawesome components.
For example, I used font-awesome the following way
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
import { faAngleDown } from '#fortawesome/free-solid-svg-icons'
import { faAngleUp } from '#fortawesome/free-solid-svg-icons'
export default {
name: 'Timer',
props: {
msg: String
},
components:{
FontAwesomeIcon
},
data: function(){
return {
selected_interval: null,
intervalID: null,
buttonText: "Start",
isStart: true,
isStop: false,
toggleAngle: faAngleDown,
},
methods: {
dropdown_toggle: function(event) {
event.stopPropagation()
let dropdown = document.querySelector('#pomodoro-dropdown');
dropdown.classList.toggle("is-active")
if(this.toggleAngle == faAngleDown){
this.toggleAngle = faAngleUp
}
else{
this.toggleAngle = faAngleDown
}
}
}
and used the componenent-
<font-awesome-icon :icon="toggleAngle" />
hope this helps.
I got it working by logging into Font Awesome and using the free kit code from https://fontawesome.com/kits.
All I needed was this in the head section of index.html:
<head>
<script src="https://kit.fontawesome.com/[kit code].js" crossorigin="anonymous"></script>
</head>
you have to add the css file of font-awesome.you can open developer tools and see there is no class with the <i></i>

Can we make vue.js application without .vue extension component and webpack?

Note: Can we write vue.js large application without using any compiler for code like currently i see all example use webpack now to make vue.js code compatible for browser .
I want make vue.js application without webpack and without using .vue extension. Is it possible? if it is possible, can you provide a link or give sample how to use routing in that case.
As we make component in .vue extension can be make component in .js extension and use application as we do in angular 1 where we can make whole app without any trans-compiler to convert the code.
Can be done that in html , css , js file only and no webpack sort of thing.
What i have done .
index.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vueapp01</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
main.js this file added in webpack load time
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
App.vue
<template>
<div id="app">
<img src="./assets/logo.png">
Hello route
Helloworld route
{{route}}
<router-view/>
<!-- <hello></hello> -->
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
route : "This is main page"
}
}
}
</script>
router
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
import Hello from '../components/Hello'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/hello',
name: 'Hello',
component: Hello
}
]
})
I have done something like this . Can we do this by just html , css , js file only with not webpack to compile code . Like we do in angular 1 .
Thanks
As stated in this jsFiddle: http://jsfiddle.net/posva/wtpuevc6/ , you have no obligation to use webpack or .vue files.
The code below is not from me and all credit goes to this jsFiddle creator:
Create an index.html file:
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<script src="https://npmcdn.com/vue-router/dist/vue-router.js"></script>
<script src="/js/Home.js"></script>
<script src="/js/Foo.js"></script>
<script src="/js/router.js"></script>
<script src="/js/index.js"></script>
<div id="app">
<router-link to="/">/home</router-link>
<router-link to="/foo">/foo</router-link>
<router-view></router-view>
</div>
Home.js
const Home = { template: '<div>Home</div>' }
Foo.js
const Foo = { template: '<div>Foo</div>' }
router.js
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: Home },
{ path: '/foo', component: Foo }
]
})
index.js
new Vue({
router,
el: '#app',
data: {
msg: 'Hello World'
}
})
Appreciate the framework...
Just a sidenote: .vue files are really awesome, you should definitely try them if not using them is not a requirement
I have started learning vue.js also and I am not familiar with webpack and stuff and I also wanted to still separate and use .vue files as it makes management and code cleaner.
I have found this library:
https://github.com/FranckFreiburger/http-vue-loader
and a sample project using it:
https://github.com/kafkaca/vue-without-webpack
I am using it and it seems to work fine.
You perfectly can, but with a lot of disadvantages. For example: you cannot easily use any preprocessor, like Sass or Less; or TypeScript or transpile source code with Babel.
If you don't need support for older browser, you can use ES6 modules today. Almost all browsers support it. See: ES6-Module.
But Firefox doesn't support dynamic import(). Only Firefox 66 (Nightly) support it and need to be enabled.
And if that wasn't enough, your web application will not be indexed. It's bad for SEO.
For example, Googlebot can craw and index Javascript code but still uses older Chrome 41 for rendering, and it's version don't support ES6 modules.
If that are not disadvantages for you, then you can do this:
Remove any thirty party library import like Vue, VueRouter, etc. And include those in the index.html file using script tags. All global variables are accesible in all es6 modules. For example, remove this line from main.js and all .vue files:
import Vue from 'vue';
And add this line in your index.html:
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
Rewrite all .vue files and change file extension to .js. For example, rewrite something like this:
<template>
<div id="home-page">
{{msg}}
</div>
</template>
<script>
export default {
data: function() {
return { msg: 'Put home page content here' };
}
}
</script>
<style>
#home-page {
color: blue;
}
</style>
to something like this:
let isMounted = false; /* Prevent duplicated styles in head tag */
export default {
template: `
<div id="home-page"> /* Put an "id" or "class" attribute to the root element of the component. Its important for styling. You can not use "scoped" attribute because there isn't a style tag. */
{{msg}}
</div>`,
mounted: function () {
if (!isMounted) {
let styleElem = document.createElement('style');
styleElem.textContent = `
#home-page {
color: blue;
}
`;
document.head.appendChild(styleElem);
isMounted = true;
}
},
data: function () {
return {
msg: 'Put home page content here'
};
}
}
It is all. I put an example in this link
P.S. Text editing without syntax highlighting can be frustrating. If you use Visual Studio Code you can install Template Literal Editor extension. It allows editing literal strings with syntax highlight. For styles select CSS syntax, and for templates HTML syntax. Unknown tag in HTML are highlighted differently. For solve this, change the color theme. For example, install Brackets Dark Pro color theme or any theme do you like.
Regards!
For sure you can. We did a project with Vue, and we had couple of problems during compiling .vue files.
So we switched to structure with three separate files.
But be aware that you need webpack anyway. The idea of Vue was to split huge projects into components, so using template inside .js file it's pretty normal.
So take a look at
html-loader
And
css-loader
Using these modules you can write something like this:
component.js
// For importing `css`. Read more in documentation above
import './component.css'
// For importing `html`. Read more in documentation above
const templateHtml = require('./component.html')
export default {
name: 'ComponentName',
components: { /* your components */ },
mixins: [/* your mixins */ ],
template: templateHtml,
computed: .....
}
component.css
#header {
color: red
}
component.html
<div id="header"></div>
BUT
You need to know that HTML file should be written in the same way as I you will have it in template property.
Also, take a look at this repo, maybe you will find something useful here
Vue-html-loader. It is a fork from html-loader by Vue core team.
In vuejs 3 you you can do it in an ES6 modular fashion (no webpack or other tools required):
index.html
<!DOCTYPE html>
<html>
<head>
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue#3.0.11/dist/vue.esm-browser.js",
"vue-router": "https://unpkg.com/vue-router#4.0.5/dist/vue-router.esm-browser.js",
"html" : "/utils/html.js"
}
}
</script>
<script src="/main.js" type="module"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
main.js
import { createApp, h } from 'vue';
import {createRouter, createWebHashHistory} from 'vue-router';
import App from './components/App.js';
const routes = [//each import will be loaded when route is active
{ path: '/', component: ()=>import('./components/Home.js') },
{ path: '/about', component: ()=>import('./components/About.js') },
]
const router = createRouter({
history: createWebHashHistory(),
routes,
})
const app = createApp({
render: () => h(App),
});
app.use(router);
app.mount(`#app`);
components/App.js
import html from 'html';
export default {
name: `App`,
template: html`
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
<router-view></router-view>
`};
components/Home.js
import html from 'html';
export default {
template: html`
<div>Home</div>
`};
components/About.js
import html from 'html';
export default {
template: html`
<div>About</div>
`};
utils/html.js
// html`..` will render the same as `..`
// We just want to be able to add html in front of string literals to enable
// highlighting using lit-html vscode plugin.
export default function () {
arguments[0] = { raw: arguments[0] };
return String.raw(...arguments);
}
Notes:
Currently (04/2021) importmap works only on chrome (firefox in progress). To make the code compatible with other browsers also, just import (on each .js file) the dependencies directly from the urls. In this case though vue-router.esm-browser.js still imports 'vue', so you should serve an updated version of it, replacing import { .... } from 'vue' with import { .... } from 'https://unpkg.com/vue#3.0.11/dist/vue.esm-browser.js'
To avoid waterfall loading effect, you can add <link rel="modulepreload" href="[module-name]"> entries to index.html to start preloading some or all modules asynchronously before you need them.
A Related article
Vue can be included on a single html page quite simply:
Vue 3 minimal example:
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>
<div id="app">{{ message }}</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
Vue 2 minimal example, with Vuetify
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<v-container>Hello world</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
})
</script>
</body>
</html>
vue 2 guides:
https://v2.vuejs.org/v2/guide/installation.html#CDN
https://vuetifyjs.com/en/getting-started/installation/#usage-with-cdn
vue 3 guide: https://v2.vuejs.org/v2/guide/installation.html#CDN

How to load external html file in a template in VueJs

I'm new to vue js.
I'm just creating a simple project where I just include vuejs through CDN. not using node/npm or cli.
I keep all my html markup in single html which looks messy as it grows. I tried to split html to views and want to include it by something analogous to ng-include of angularJs
I have worked in angular previously where there is ng-include to load external html files. I'm looking for something similar to that in vue. the whole point is to split my html files into more maintainable separate files.
have come across <template src="./myfile.html"/> but it doesn't work
Can somebody help me out
It's actually remarkably easy, but you need to keep something in mind. Behind the scenes, Vue converts your html template markup to code. That is, each element you see defined as HTML, gets converted to a javascript directive to create an element. The template is a convenience, so the single-file-component (vue file) is not something you'll be able to do without compiling with something like webpack. Instead, you'll need to use some other way of templating. Luckily there are other ways of defining templates that don't require pre-compiling and are useable in this scenario.
1 - string/template literals
example: template: '<div>{{myvar}}</div>'
2 - render function 🤢
example: render(create){create('div')}
Vue has several other ways of creating templates, but they just don't match the criteria.
here is the example for both:
AddItem.js - using render 😠 functions
'use strict';
Vue.component('add-item', {
methods: {
add() {
this.$emit('add', this.value);
this.value = ''
}
},
data () {
return {
value: ''
}
},
render(createElement) {
var self = this
return createElement('div', [
createElement('input', {
attrs: {
type: 'text',
placeholder: 'new Item'
},
// v-model functionality has to be implemented manually
domProps: {
value: self.value
},
on: {
input: function (event) {
self.value = event.target.value
// self.$emit('input', event.target.value)
}
}
}),
createElement('input', {
attrs: {
type: 'submit',
value: 'add'
},
on: {
click: this.add
}
}),
])
}
});
ListItem.js - using template literals (back-ticks)
'use strict';
Vue.component('list-item', {
template: `<div class="checkbox-wrapper" #click="check">
<h1>{{checked ? '☑' : '☐'}} {{ title }}</h1>
</div>`,
props: [
'title',
'checked'
],
methods: {
check() {
this.$emit('change', !this.checked);
}
}
});
and the html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.0/vue.js"></script>
<script src="ListItem.js"></script>
<script src="AddItem.js"></script>
</head>
<body>
<div id="app">
<add-item #add='list.push({title:arguments[0], checked: false})'></add-item>
<list-item v-for="(l, i) in list" :key="i" :title="l.title" :checked="l.checked" #change="l.checked=arguments[0]"></list-item>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
newTitle: '',
list: [
{ title: 'A', checked: true },
{ title: 'B', checked: true },
{ title: 'C', checked: true }
]
}
});
</script>
</body>
</html>
TL; DR;
See it in action at : https://repl.it/OEMt/9
You cant. You must use async components - read guide here
Actually you can. This is kinda easy. Depends on your needs and situation. However, this code is NOT technically correct, however it will explain to you how it might work, gives you massive freedom and makes your original vue instance smaller.
To make this work, you will need vue router (cdn is ok) and in this case axios or fetch (if you dont care about supporting older browsers).
The only downfall in my opinion is that in content files you will need to add additional call parameter $parent . This will force vue to work.
index
<div id="app">
<router-link v-for="route in this.$router.options.routes" :to="route.path" :key="route.path">{{ route.name }}</router-link>
<section style="margin-top:50px;">
<component :is="magician && { template: magician }" />
</section>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const viewer = axios.create({ baseURL: location.origin });
const routes = [
{"name":"Hello","slug":"hello","path":"/lol/index.html"},
{"name":"Page One","slug":"page_one","path":"/lol/page-one.html"},
{"name":"Page Two","slug":"page_two","path":"/lol/page-two.html"}
];
const app = new Vue({
router,
el: '#app',
data: {
magician: null,
},
watch: {
$route (to) {
this.loader(to.path);
}
},
mounted() {
this.loader(this.$router.currentRoute.path);
},
methods: {
viewer(opt) {
return viewer.get(opt);
},
loader(to) {
to == '/lol/index.html' ? to = '/lol/hello.html' : to = to;
this.viewer(to).then((response) => {
this.magician = response.data;
}).catch(error => {
alert(error.response.data.message);
})
},
huehue(i) {
alert(i);
}
}
});
</script>
hello.html content
<button v-on:click="$parent.huehue('this is great')">Button</button>
page-one.html content
<select>
<option v-for="num in 20">{{ num }}</option>
</select>
page-two.html content
// what ever you like
router explanation
To make this work perfectly, you will need to find a correct way to configure your htaccess to render everything if current page after first view is not index. Everything else should work fine.
As you can see, if it is index, it will load hello content file.
I faced the same issue and this is how I solved it , I also made a video about this question https://www.youtube.com/watch?v=J037aiMGGAw
create a js file ,for your component (logic) let's call it "aaaa.vue.js"
create an HTML file for your template that will be injected in your "aaaa.vue.js" and let's call it "aaaa.html"
Component file (Logic file javascript)
const aaaa = {
name:"aaaa",
template: ``,
data() {
return {
foo:"aaaa"
};
},
methods: {
async test() {
alert(this.foo)
},
},
};
Template file (HTML)
<!--template file-->
<div>
<button #click="test" > click me plz </button>
</div>
index.html
<html>
<head>
<title>my app</title>
</head>
<body>
<div id="app" class="main-content col-12">
<aaaa></aaaa>
</div>
</body>
</html>
<script src="axios.min.js"></script>
<script src="vue.js"></script>
<!-- load js file (logic) -->
<script src="aaaa.vue.js"></script>
<script>
document.addEventListener("DOMContentLoaded", async function () {
//register components
let html = await axios.get("aaaa.html"); // <---- Load HTML file
aaaa.template = html.data;
Vue.component("aaaa", aaaa);
new Vue({
el: "#app",
name: "main",
//... etc
});
});
</script>
Update :
I also created an example on github to see it in action
https://github.com/nsssim/Vue-CDN-load-component
Sure you can, this is the way we are doing it in all our components of our app.
<template src="../templates/the_template.html"></template>
<script>
export default {
name: 'ComponentName',
props: {},
computed: {},
methods: {},
};
</script>
<style lang="scss">
#import '../styles/myscss_file';
</style>
Will need to add
runtimeCompiler: true
to your vue.config.js file. That's it.

react-router Link doesn't render href attribute with server side rendering?

I have a expressjs app with the following code, what i am trying to do is to render a react component named Hello with the request to "/". Inside Hello component i am using two react-router Links, but these two Links doesn't render the href attributes.
I am using here react-router 2
Server.js file
var express = require("express");
var app = express();
var React = require("react");
var ReactDOM = require("react-dom/server");
var Hello = React.createFactory(require("./js/components/Hello"));
// The above is a reference to pre-compiled Hello.jsx to Hello.js using babel
app.set("view engine", "ejs");
app.set("views", "./views");
app.use(express.static("./public"));
app.get("/", function (req, res) {
res.render("Home",{data:ReactDOM.renderToString(Hello())});
});
app.listen(app.get("port"), function () {
console.log("server started on port " + app.get("port"));
});
Hello.jsx File
var React = require("react");
var Link = require("react-router/lib/Link");
var Hello = React.createClass({
callMe:function(){
alert("Hurray");
},
componentWillMount:function(){
console.log("componentWillMount fired");
},
render:function(){
// console.log(this);
return(
<div>
<h2 onClick={this.callMe}>Hello Boom Boom {this.props.name}</h2>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
// above two Links rendering anchor tags without href attribute
</div>
);
}
});
module.exports = Hello;
Home.ejs File
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<h2>Welcome to home page</h2>
<div id="container">
<%- data %>
</div>
</body>
</html>
Please consult the React Router server rendering guide: https://github.com/reactjs/react-router/blob/master/docs/guides/ServerRendering.md
You need to render your components in an appropriate routing context for <Link> to generate URLs.
I just had the same problem, and the thing I was missing was the surrounding <RouterContext>. <Link> components seem to have an empty href attribute when not inside of a <Router> or appropriate react-router environment. I improved the routing in the SSR code (I was doing a weird partial solution) and the links started appearing.