I am using vue2-leaflet in my vue component. I am facing issue when using vue2-leaflet-locationcontrol.
When I allow the browser to allow location access in the console i get the error
TypeError: max2 is undefined
Here is the sample code in the component:
<l-map :zoom="zoom" :center="center" :bounds="bounds">
<l-tile-layer :url="url" :attribution="attribution" :no-wrap="true"></l-tile-layer>
<l-marker :lat-lng="marker" :draggable="true" #update:lat-lng="updateMarker"></l-marker>
<v-geosearch :options="geosearchOptions" #showlocation="showLocation"></v-geosearch>
<v-locatecontrol />
</l-map>
import in component
import { LMap, LTileLayer, LMarker } from "vue2-leaflet";
import { OpenStreetMapProvider } from "leaflet-geosearch";
import VGeosearch from "vue2-leaflet-geosearch";
import VLocatecontrol from "vue2-leaflet-locatecontrol";
import in main.js
import L from 'leaflet';
L.Icon.Default.imagePath = '/themes/storefront/assets/public/image/';
L.Icon.Default.mergeOptions({
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png').split("/")[5],
iconUrl: require('leaflet/dist/images/marker-icon-2x.png').split("/")[5],
shadowUrl: require('leaflet/dist/images/marker-shadow.png').split("/")[5],
});
import 'leaflet/dist/leaflet.css';
import 'leaflet-geosearch/assets/css/leaflet.css';
What I am doing wrong?
Related
i installed font-awesome into my Vue project exactly like in Docs but i got that error
first i installed it using these commands
$ npm i --save #fortawesome/fontawesome-svg-core
$ npm i --save #fortawesome/free-solid-svg-icons
$ npm i --save #fortawesome/vue-fontawesome#prerelease
in main.js :
import Vue from 'vue'
import App from './App.vue'
import { library } from '#fortawesome/fontawesome-svg-core'
import { faUserSecret } from '#fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
library.add(faUserSecret)
Vue.component('font-awesome-icon', FontAwesomeIcon)
Navbar.vue:
<div class="nav-icons">
<font-awesome-icon icon="user-secret" />
</div>
Using Vue 2 and the CLI, I recently built a Font Awesome test project that works.
IconList.vue
<template>
<div class="icon-list">
<h3>Icon List</h3>
<div class="row">
<div class="col-md-6">
<ul class="list-group">
<li v-for="(iconName, index) in currentIcons" :key="index" class="list-group-item" >
<font-awesome-icon :icon="iconName" class="fa-2x" />
</li>
</ul>
<button v-if="displayMoreBtn" class="btn btn-secondary" #click="showMore" >
<font-awesome-icon icon="ellipsis-h" class="fa-2x" />
</button>
</div>
</div>
</div>
</template>
<script>
import { library } from "#fortawesome/fontawesome-svg-core";
import { faCoffee } from "#fortawesome/free-solid-svg-icons";
import { faCloudMoonRain } from "#fortawesome/free-solid-svg-icons";
import { faEnvelope } from "#fortawesome/free-solid-svg-icons";
import { faFan } from "#fortawesome/free-solid-svg-icons";
import { faEllipsisH } from "#fortawesome/free-solid-svg-icons";
import { faGuitar } from "#fortawesome/free-solid-svg-icons";
import { faPeace } from "#fortawesome/free-solid-svg-icons";
import { faRobot } from "#fortawesome/free-solid-svg-icons";
library.add(faCoffee);
library.add(faCloudMoonRain);
library.add(faEnvelope);
library.add(faFan);
library.add(faEllipsisH);
library.add(faGuitar);
library.add(faPeace);
library.add(faRobot);
export default {
data() {
return {
initialIcons: ["coffee", "cloud-moon-rain", "envelope", "fan"],
additionalIcons: ["guitar", "peace", "robot"],
displayMoreBtn: true,
currentIcons: [],
};
},
methods: {
showMore() {
this.currentIcons = this.currentIcons.concat(this.additionalIcons);
this.displayMoreBtn = false;
},
},
created() {
this.currentIcons = this.initialIcons;
},
};
</script>
App.vue
<template>
<div id="app" class="container">
<icon-list />
</div>
</template>
<script>
import IconList from '#/components/stackoverflow/font-awesome-list/IconList'
export default {
name: 'App',
components: {
IconList
},
}
</script>
main.js
import Vue from 'vue'
import App from './App.vue'
import 'bootstrap/dist/css/bootstrap.css'
// Font Awesome
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
Vue.component('font-awesome-icon', FontAwesomeIcon)
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
I want to connect fa in vue Doing
*************
import { library } from '#fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
import { faVuejs } from '#fortawesome/free-brands-svg-icons'
******************
library.add(faVuejs);
Vue.component('font-awesome-icon', FontAwesomeIcon)
************
In component:
<font-awesome-icon :icon="[ 'fab', 'twitter' ]" />
Console error:
Could not find one or more icon(s) {prefix: "fab", iconName: "twitter"}
But, if im use:
<font-awesome-icon :icon="[ 'fab', 'vuejs' ]" />
Working fine ... What's wrong?
You have to import the faTwitter icon, and add it to the library like you're doing with the Vue icon:
import { faTwitter } from '#fortawesome/free-brands-svg-icons'
library.add(faTwitter)
demo
Vue Util throws a console log error:
console.error
[Vue warn]: Invalid prop: type check failed for prop "icon". Expected Object, Array, String, got Undefined
I got a parent component in this case 'myComp' and inside I have another global component which is here Font Awesome, which is already imported. the error that I get is that prop icon is undefined, in 'myComp' prop icon doesn't exist, so I assume vue utils reads 'fa' component and looks for a prop icon in 'myComp'. All of my test pass, I just get this warning and want to get rid of it.
I Import my global components in an extra file called componentsbind.js, which already is tested and works.
import { library } from '#fortawesome/fontawesome-svg-core'
import { faUserSecret } from '#fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
library.add(faUserSecret)
my component: this is a reusable component that I am testing
<template>
<button #click="handleClick">
<template v-if="loading">
<fa :icon="faChevronRight " class="fa-spin text-xl" />
</template>
<template v-else>
<slot />
</template>
</button>
</template>
inside my component I already Imported with
<script>
import { faChevronRight } from '#fortawesome/free-solid-svg-icons'
...
my test
import { shallowMount, RouterLinkStub } from '#vue/test-utils'
import MyComp from '#/components/MyComp.vue'
let wrapper
beforeEach(() => {
wrapper = shallowMount(MyComp, {
slots: {},
stubs: {}
})
})
afterEach(() => {
wrapper.destroy()
})
describe('MyComp Test', () => {
//here are my tests...
})
So my problem was that I wasn't importing vue use composition api.
And because I return the icon on setup function it was always undefined.
so in the file where I import all my global components I just added:
import VueCompositionAPI from '#vue/composition-api'
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
Vue.use(VueCompositionAPI)
I'm new to Vue, can't find the exact answer how to use FA SVG icons in v-icon and prepend-icon.
If i use:
<font-awesome-icon :icon="dekstop" color="gray"></font-awesome-icon>
Icons are displayed, but how i can use FA SVG icons in v-icon and prepend-icon?
Sample:
<v-autocomplete v-model="replUser"
:items="users"
color="accent white--text"
label="User"
prepend-icon="dekstop></i>" // i can use material font icons here, but FA SVG not worked
>
</v-autocomplete>
my main.js:
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
// import colors from 'vuetify/es5/util/colors'
import './plugins/vuetify'
import App from './App.vue'
import i18n from './i18n'
import {
library
} from '#fortawesome/fontawesome-svg-core'
import {
FontAwesomeIcon
} from '#fortawesome/vue-fontawesome'
import {
fas
} from '#fortawesome/free-solid-svg-icons'
Vue.component('font-awesome-icon', FontAwesomeIcon) // Register component globally
library.add(fas) // Include needed icons.
Vue.use(Vuetify, {
iconfont: 'faSvg',
})
Vue.config.productionTip = false
new Vue({
i18n,
render: h => h(App)
}).$mount('#app')
What am I doing wrong?
If you want to use svg icons in v-icon/prepend-icon, then you need to access them through $vuetify.icons object. Any other text in the v-icon/prepend-icon will be interpreted as webfont/css class.
But for use $vuetify.icons object you should register custom icons. Example:
import Vue from "vue";
import Vuetify from "vuetify";
import { library } from "#fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "#fortawesome/vue-fontawesome";
import { faVuejs } from "#fortawesome/free-brands-svg-icons";
Vue.component("font-awesome-icon", FontAwesomeIcon); // Register component globally
library.add(faVuejs); // Include needed icons.
Vue.use(Vuetify, {
icons: {
vue: {
component: FontAwesomeIcon,
props: {
icon: ["fab", "vuejs"]
}
}
}
});
And now you can use vue-brand icon:
<v-icon>$vuetify.icons.vue</v-icon>
<v-text-field prepend-icon="$vuetify.icons.vue"/>
Also, you can use without register via font-awesome-icon:
<font-awesome-icon :icon="['fab', 'vuejs']" />
<v-text-field>
<font-awesome-icon :icon="['fab', 'vuejs']" slot="prepend"/>
</v-text-field>
Out of the box vuetify has a preset of icons config that can be associated with SVG:
...
import { fas } from "#fortawesome/free-solid-svg-icons";
...
library.add(fas);
...
Vue.use(Vuetify, {
iconfont: "faSvg"
});
But for use it you should call $vuetify.icons again (vuetify just wrap preset as component):
<v-icon>$vuetify.icons.warning</v-icon>
Full example codesandbox
From Vuetify documention:
Font Awesome is also supported. Simply use the fa- prefixed icon name.
Please note that you still need to include the Font Awesome icons in
your project.
Maybe it helps you. But, without your sample code I can't be sure
<v-autocomplete v-model="replUser"
:items="users"
color="accent white--text"
label="User"
prepend-icon="fa-dekstop">
</v-autocomplete>
I've been trying a bunch of stuff now. I've tried nuxt-leaflet dependency, I've tried writing my own plugin and including it. However, everything keeps ending in the "window is not defined" error.
The map should only be loaded on the client.
My vue component:
<template>
<no-ssr>
<l-map
id="map"
:zoom="zoom"
:min-zoom="3"
:center="center"
>
</l-map>
</no-ssr>
</template>
<script lang="ts">
import Vue from 'vue';
import {latLng, marker} from 'leaflet';
import {ExploreItemType} from '~/components/explore/ExploreItem';
import {Component} from "nuxt-property-decorator";
#Component()
export default class ExplorerMap extends Vue {
url = 'https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoia2dydWVuZWJlcmciLCJhIjoiY2puajJ3c3dmMGV1YzNxbDdwZ3Y5MXc0bCJ9.kuHo67NUkzqya1NtSjTYtw';
attribution = 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox';
zoom = 3;
center = latLng(51.505, -0.09);
drawCluster = true;
}
</script>
So I wrote my own plugin in plugins/vue-leaflet.ts
import Vue from 'vue'
import Vue2Leaflet from 'vue2-leaflet'
import Vue2LeafletMarkerCluster from 'vue2-leaflet-markercluster';
Vue.component('l-circle', Vue2Leaflet.LCircle);
Vue.component('l-geo-json', Vue2Leaflet.LGeoJson);
Vue.component('l-icon-default', Vue2Leaflet.LIconDefault);
Vue.component('l-layer-group', Vue2Leaflet.LLayerGroup);
Vue.component('l-map', Vue2Leaflet.LMap);
Vue.component('l-marker', Vue2Leaflet.LMarker);
Vue.component('l-popup', Vue2Leaflet.LPopup);
Vue.component('l-tile-layer', Vue2Leaflet.LTileLayer);
Vue.component('l-tooltip', Vue2Leaflet.LTooltip);
And included it in the nuxt.config.js
{src: "~/plugins/vue-leaflet.ts", ssr: false}
No matter what I've tried, I always end up getting the window is not defined error. I'm out of ideas.
Its because in your component you do
import {latLng, marker} from 'leaflet';
Which probably will do some window check and fail straight away. So you need to import it conditionally with if (process.client) check
Thanks to the hint from Aldarund, I got this to work:
<template>
<div>
<no-ssr>
<l-map
id="map"
:zoom="zoom"
:min-zoom="3"
:center="center"
>
<l-tile-layer :url="url" :attribution="attribution"/>
....
</l-map>
</no-ssr>
</div>
</template>
<script lang="ts">
const isBrowser = typeof window !== 'undefined';
let leaflet;
if (isBrowser) {
leaflet = require('leaflet');
}
import Vue from 'vue';
import {Component, Prop, Watch} from "nuxt-property-decorator";
#Component({})
export default class ExplorerMap extends Vue {
url = 'https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoia2dydWVuZWJlcmciLCJhIjoiY2puajJ3c3dmMGV1YzNxbDdwZ3Y5MXc0bCJ9.kuHo67NUkzqya1NtSjTYtw';
attribution = 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox';
zoom = 3;
center;
created() {
if (isBrowser) {
this.center = leaflet.latLng(51.505, -0.09);
}
....
}