Converting index.html into a vue component - javascript

I'm building a webpage using Vue.js, and I'm relatively new to Javascript. I'm using Vue because I find the way it uses component .vue files makes it easier to program in Javascript.
However, looking at GitHub to help with libraries, code, etc. makes it hard, since they are usually written as one .html page.
I found a library that I'd like to use, but I'm not sure how I would create a Vue component out of it. This is because it isn't really returning anything. I'm not sure how to export default{} the stuff so that I'm able to use it in my App.vue.
Furthermore, the HTML and the script are kinda integrated so I was wondering would this change how I implement it?
Here is the index.html:
$(document).ready(function() {
var map = new FlightsMap("schedules_map", {
width: 960,
height: 440,
stations: "stations.json",
flights: "flights.json"
});
$("#reset").click(function() { map.reset(); });
$("#zoom_in").click(function() { map.zoomIn(); });
$("#zoom_out").click(function() { map.zoomOut(); });
$("#show_schedules").click(function() { map.showSchedules(); });
});
#station_name {
display: inline-block;
float: right;
}
a {
cursor: pointer;
}
<script src="https://cdn.rawgit.com/santiagohecar/flights-map/master/dist/flights-map.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="schedules_map"></div>
<div style="width:800px;">
<a id="reset" href="javascript:void(0)">Reset</a>
<a id="zoom_in" href="javascript:void(0)">Zoom in</a>
<a id="zoom_out" href="javascript:void(0)">Zoom out</a>
<a id="show_schedules" href="javascript:void(0)">all</a>
<div id="station_name" ></div>
</div>
From here

This should work for you:
Map.vue - this is a Vue component
<template>
<div>
<div id="schedules_map"></div>
<div style="width:800px;">
<a #click="map.reset()" href="#">Reset</a>
<a #click="map.zoomIn()" href="#">Zoom in</a>
<a #click="map.zoomOut()" href="#">Zoom out</a>
<a #click="map.showSchedules()" href="#">All</a>
<div id="station_name"></div>
</div>
</div>
</template>
<script>
import FlightsMap from "../../node_modules/flights-map/src/flights-map";
export default {
name: "Map",
props: ["flights", "stations"],
data() {
return {
map: {}
};
},
watch: {
flights() {
this.createMap();
},
stations() {
this.createMap();
}
},
methods: {
createMap() {
this.map = new FlightsMap("schedules_map", {
width: 960,
height: 440,
stations: this.stations,
flights: this.flights
});
}
},
mounted() {
this.createMap();
}
};
</script>
<style scoped>
#station_name {
display: inline-block;
float: right;
}
a {
cursor: pointer;
margin: 1rem;
}
</style>
Installation
You'll need to install flights-map with npm, or reference it from some local source. flights-map isn't a npm package, so you will have to install it directly from GitHub:
npm install https://github.com/hrcarsan/flights-map.git
Depending on where you locate your component, you will need to change the path to flights-map accordingly. When I was testing it, I had this file structure:
node_modules/
┗ flights-map/
┣ src/
┗ ┗ flights-map.js
src/
┗ components/
┗ Map.vue
┣ main.js
┗ App.vue
So you need to go two levels up from Map.vue to get above node_modules and src, then down to flights_map/src/flights-map.js Also note that there is a dist/ directory in flights-map/, with a different flights-map.js, but that one doesn't work properly. So make sure that your path goes to the src directory, not dist
Using Map.vue
App.vue
<template>
<Map
stations="https://raw.githubusercontent.com/hrcarsan/flights-map/master/example/stations.json"
flights="https://raw.githubusercontent.com/hrcarsan/flights-map/master/example/flights.json"
></Map>
</template>
<script>
import Map from "#/components/Map.vue";
export default {
name: "App",
components: {
Map
}
};
</script>
Whenever you want use the Map component, just call it like so (note that you need to import it on each seperate view you use it on) :
<Map
stations="https://raw.githubusercontent.com/hrcarsan/flights-map/master/example/stations.json"
flights="https://raw.githubusercontent.com/hrcarsan/flights-map/master/example/flights.json"
></Map>
stations is the url of stations.json.
flights is the url of flights.json
Sidenote:
The watchers in Map.vue aren't required, they are there just to make the map reactive. You can remove them and the createMap() method too. Just put the contents of createMap() in mounted()

Related

Third party VueJS component can't be found in node_modules

Using vue-cli version 3 for a new vuejs project (I've been studying a lot of vuejs, but this is the first time trying to implement a third-party component). I'm trying to use a grid component that looks impressive. The component is here.
I've setup my environment, installed the grid and component using npm as instructed from their site, configured my own component and imported everything (I thought) properly. I've even setup an data array property to use as a test to fill my grid. I ran npm install and confirmed the folders were installed in my node_modules folder (they are there). Here is my main.js:
import Vue from 'vue'
import App from './App.vue'
import CGrid from 'vue-cheetah-grid'
Vue.config.productionTip = false;
Vue.use(CGrid);
new Vue({
render: h => h(App)
}).$mount('#app')
And here is my App.vue :
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<reports-grid></reports-grid>
</div>
</template>
<script>
import ReportsGrid from './components/ReportsGrid.vue'
export default {
name: 'app',
components: {
reportsGrid: ReportsGrid
}
}
</script>
Here is my component file, ReportsGrid.vue:
<template>
<div class="grid">
<c-grid ref="grid" :data="records" :frozen-col-count="1">
<c-grid-column field="team" width="85">
Team
</c-grid-column>
<c-grid-column-group caption="Estimate">
<c-grid-column field="quotenum">
Quote #
</c-grid-column>
<c-grid-column field="quotedate">
Date
</c-grid-column>
<c-grid-column field="customer">
Customer
</c-grid-column>
<c-grid-column field="country">
Country
</c-grid-column>
<c-grid-column field="type">
Type
</c-grid-column>
<c-grid-column field="quoteamount">
Quote Amount
</c-grid-column>
</c-grid-column-group>
<c-grid-column-group caption="Sales Order">
<c-grid-column field="salesordernum">
Sales Order #
</c-grid-column>
<c-grid-column field="salesorderamount">
Sales Order Amount
</c-grid-column>
<c-grid-column field="margin">
Average Margin
</c-grid-column>
<c-grid-column field="status">
Status
</c-grid-column>
</c-grid-column-group>
</c-grid>
</div>
</template>
<script>
export default {
name: 'app',
data: function() {
return {
records: [
{
team: 'GG', quotenum: '20211', quotedate:'today', customer: 'AirNN', country: 'Peru', salesordernum: '11111',
type: 'Production', quoteamount: '$1300', salesorderamount: '$1200', margin: '25%', status: 'WIN Partial'
},
{
team: 'LL', quotenum: '20200', quotedate:'today', customer: 'Paris', country: 'Mexico', salesordernum: '11122',
type: 'Bid', quoteamount: '$12300', salesorderamount: '$10300', margin: '20%', status: 'WIN Partial'
}
]
}
}
}
</script>
When I run this I don't see anything on my page (no errors either). I noticed in my main.js my linter is throwing an error on the line import CGrid from 'vue-cheetah-grid' (this error doesn't show up in my terminal, just in my main.js:
[ts]
Could not find a declaration file for module 'vue-cheetah-grid'. 'path.to/node_modules/vue-cheetah-grid/dist/vueCheetahGrid.js' implicitly has an 'any' type.
Try `npm install #types/vue-cheetah-grid` if it exists or add a new declaration (.d.ts) file containing `declare module 'vue-cheetah-grid';`
This is a new error to me. The folders are in the node_modules folder. I even tried the npm install #types/vue-cheetah-grid but it still didn't work.
The problem appears to be with the height style.
Looking at the page source for the Cheetah Vue demo, they have dropped in some styles that seem to override the standard cheetah styles.
If you add this to your component, it looks ok
<style scoped>
html {
height: 100%;
}
body {
height: calc(100% - 100px);
}
.contents {
padding: 30px;
box-sizing: border-box;
}
.demo-grid {
width: 100%;
height: 300px;
box-sizing: border-box;
border: solid 1px #ddd;
}
.demo-grid.large {
height: 500px;
}
.demo-grid.middle {
height: 300px;
}
.demo-grid.small {
height: 240px;
}
.log {
width: 100%;
height: 80px;
background-color: #F5F5F5;
}
.hljs {
tab-size: 4;
}
</style>

Dynamic image is not loaded via :src

I am working on a simple Vue app, using vue-cli and webpack for that purpose.
So basicly i have 2 components, a parent and a child component ~
like this:
<template>
<div class="triPeaks__wrapper">
<div class="triPeaks">
<tri-tower class="tower"></tri-tower>
<tri-tower class="tower"></tri-tower>
<tri-tower class="tower"></tri-tower>
</div>
<div class="triPeaks__line">
<tower-line :towerLine="towerLineCards" />
</div>
<tri-pack />
</div>
</template>
the towerLineCards is the important thing there, it is a prop that is passed to the tower-line component, it is basicly a array with 10 elements, it is a array with 10 numbers that are shuffled, so it can be something like that:
[1,5,2,6,8,9,16,25,40,32]
this array is create via beforeMount on the lifecycle.
On the child component:
<template>
<div class="towerLine-wrapper">
<div class="towerLine">
<img v-for="index in 10" :key="index" class="towerLine__image" :src="getImage(index)" alt="">
</div>
</div>
</template>
<script>
export default {
props: {
towerLine: {
type: Array,
required: true
}
},
method: {
getImage (index) {
return '#/assets/images/cards/1.png'
}
}
}
</script>
<style lang="scss">
.towerLine {
display: flex;
position: relative;
top: -90px;
left: -40px;
&__image {
width: 80px;
height: 100px;
&:not(:first-child) {
margin-left: 3px;
}
}
}
</style>
the issue is with the :src image that i am returning via the getImage(), this way it is not working. If i change to just src it works just fine, i did this way just to test, because the number in the path should be dynamic when i got this to work.
What is wrong with this approach? any help?
Thanks
Firstly, you should use a computed property instead of a method for getImage().
And to solve the other problem, you could add require(YOUR_IMAGE_PATH) when you call your specific image or put it inside /static/your_image.png instead of #/assets/images/cards/1.png.

Scoped style in vue.js isn't scoped at all

Good afternoon,
I'm having a difficulty scoping imported CSS file within bounds of my HTMLEditor vue component.
Here's the component:
<template>
<div class="htmleditor">
<div class="htmleditor-input">
<h3>Header</h3>
<p>Paragraph of text</p>
</div>
<div class="htmleditor-output">
</div>
</div>
</template>
<script>
export default
{
data: () =>
({
html: ''
}),
}
</script>
<style scoped src="~/css/default.min.css">
.htmleditor
{
display: flex;
}
.htmleditor-input
{
border: 1px solid green;
}
.htmleditor-output
{
border: 1px solid yellow;
}
</style>
The issue I'm having is, if I do it this way - it says
Module not found: Error: Can't resolve '~/css/default.min.css'
If I try putting #import '~/css/default.min.css' inside .htmleditor in CSS, all I get is a non-scoped style.
I found the fix.
If you are getting the same error - know that nodejs' vue compiler requires somewhat 'absolute' paths to files.
You can't use '~/' nor '/' nor '.' as the first thing in your path, you have to navigate directly - which in my case (Laravel) meant putting: '../../../../css/default.min.css'.

Nuxtjs error render function or template not defined in component: carousel

I have installed vue carousel via npm
"dependencies": {
"nuxt": "^1.0.0",
"vue-carousel": "^0.6.9"
},
Now in my nuxt configurations
plugins: [
'~/plugins/vue-carousel'
],
And the vue-carousel.js
import Vue from 'vue';
import VueCarousel from 'vue-carousel';
Vue.use(VueCarousel);
Now in my components am using it as
<template>
<div>
<carousel>
<slide>
Slide 1 Content
</slide>
<slide>
Slide 2 Content
</slide>
</carousel>
</div>
</template>
<script>
import Carousel from 'vue-carousel';
import Slide from 'vue-carousel';
export default {
components:{
Carousel,Slide
}
}
Where am i going wrong as am getting an error
render function or template not defined in component: carousel
Nuxt has a different way to configure and include packages like vue-carousel in the project
Below are the steps
Install vue-carousel as local dependency
npm install --save vue-carousel
In nuxt project, under plugins directory create a file plugins/externalVueCarousel.js and add vue-carousel as a global component (reference link)
import Vue from 'vue'; import VueCarousel from 'vue-carousel'; Vue.use(VueCarousel);
In nuxt.config.js file , include below code under plugins
plugins: [{ src: '~/plugins/externalVueCarousel.js', ssr: false }],
The project is now ready to use vue-carousel in pages or components. vue-carousel is configured with global scope.
Under pages or components try the examples given in vue-carousel official website
Sample program
Place below code under pages/components and validate the result in-case if you would like to test a program ASAP
<template>
<div class="mycarousel">
<carousel :perPage="1">
<slide>
<span class="label">Slide 1 Content</span>
</slide>
<slide>
<span class="label">Slide 2 Content</span>
</slide>
<slide>
<span class="label">Slide 3 Content</span>
</slide>
</carousel>
</div>
</template>
<style>
body{
background-color: yellow;
}
.mycarousel{
left: 50%;
top: 50%;
position: relative;
width: 700px;
transform: translateX(-50%);
}
.VueCarousel{
display:inline-block;
}
.VueCarousel-slide {
position: relative;
background: #42b983;
color: #fff;
font-family: Arial;
font-size: 24px;
text-align: center;
min-height: 100px;
}
</style>
Referred from https://nuxtjs.org/examples/plugins/

VueJS error compiling template

I just made my first project with VueJS and Vue-loader.
So I made my first component to show a simple message, it works fine when I make one message, but I get an error when I make multiple messages:
(Emitted value instead of an instance of Error)
Error compiling template:
<message>This is a small message!</message>
<message>Another one</message>
- Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
This is my code. I'm very new to this and I can't figure out what's wrong.
App.vue
<template>
<message>This is a small message!</message>
<message>Another one</message>
</template>
<script>
import Message from './Components/Message.vue';
export default {
name: 'app',
components: {
Message,
},
data () {
return {
}
}
}
</script>
Message.Vue
<template>
<div class="box">
<p>
<slot></slot>
</p>
</div>
</template>
<script>
export default {
}
</script>
<style>
.box { background-color: #e3e3e3; padding: 10px; border: 1px solid #c5c5c5; margin-bottom: 1em;}
</style>
I hope somebody can help!
The error is pretty self-explanatory. You should have only one root element in each component. So just pack everything in a div.
<template>
<div>
<message>This is a small message!</message>
<message>Another one</message>
</div>
</template>

Categories