v-binded image from local machine wont show, but from web does - vue.js

I want to change image dependent on variant of product selected, so I have to bind image property using v-bind.
When I put address of image on web in my variable it works, but when I put address of image from my PC (relative - using ../assets/image.jpeg, or using #/assets/image.jpeg or absolute address - /home/.../assets/image.jpeg) it won't show. I don't get any error message.
This is problematic code:
<template>
<div class="product" v-for="(product, prodId) in products" :key="prodId">
<!-- Element in question -->
<img :src="product.variants[product.selectedVariant].url" alt="picture">
<div v-for="(variant, variantId) in product.variants" :key="variantId"
:class="variant.color"
#mouseover="selectedVariant(prodId, variantId)"></div>
</div>
</template>
<script>
export default {
name:'ProductSection',
methods:{
selectedVariant(prodId, variantId){
this.products[prodId].selectedVariant= variantId
}
},
data(){
return {
products: [{
name: 'Billiard Balls',
//Image address is value of url key
variants: [{color: 'red', url: '#/assets/red.jpeg'}, {color: 'blue', url: '#/assets/blue.jpeg'}],
selectedVariant: 0
}, {
name: 'Car Toy',
variants: [{color: 'red', url: '#/assets/redCar.jpeg'}, {color: 'yellow', url: '../assets/YellowCar.jpeg'}],
selectedVariant: 0
}]
}
}
}
</script>
And side question is Where do my images end up when I build project? Do i have to deploy assets file along side built file?

I didn't import image. I should have done
import image from '#/assets/image.jpeg'
and then
variants: [{color: 'red', url: image}, ...]

Related

Dynamic TailwindCSS class is not working properly

Considering my code:
<template>
<section
class="bg-gradient-to-br h-40"
:class="
'from-palettes-' +
palette +
'-primary to-palettes-' +
palette +
'-secondary'
"
>
Topbar
</section>
</template>
<script>
export default {
data: function () {
return {
menuOpen: false,
palette: "green-dark",
};
},
methods: {},
};
</script>
<style>
</style>
And my tailwind file:
extend: {
colors: {
palettes: {
"green-dark": {
primary: "#57876E", //dark color
secondary: "#92BFA8", //light color
gray: "#333453",
accent: "#f8f2f2", //slight offset from white
white: "#FAF9FA",
},
},
},
},
Color is not loaded. When I check the console there are no errors, when I check source code, the class name is applied as it should. The corresponding class is however not found/applied. What am I doing wrong?
The most important implication of how Tailwind extracts class names is
that it will only find classes that exist as complete unbroken strings
in your source files.
If you use string interpolation or concatenate partial class names
together, Tailwind will not find them and therefore will not generate
the corresponding CSS.
https://tailwindcss.com/docs/content-configuration#dynamic-class-names

How can I customize a GChart in Vue.js?

Good evening. I am working on learning Vue.js and I want to make a basic charting website to practice and build skills. I am trying to customize my GChart.
Current chart: 1.
The first thing I am aiming to do is to customize the background color. The next thing I am looking to do is get rid of the label on the side, and lastly, although the chart says "you" above it that is not the chart's name. This is my code:
import { GChart } from "vue-google-charts";
export default {
name: 'HelloWorld',
components: {
GChart
},
computed: {
myStyles () {
return {
position: 'relative',
}
}
},
data () {
return {
chartData: [
['You', 'Percent'],
['Cute', 100],
],
chartOptions: {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
}
}
}
}
#chart{
padding:5px;
width:60%;
margin:auto;
background-color:rgb(241, 241, 129);
}
#actualChart{
margin:auto;
height:300px;
width:230px;
background-color:rgb(241, 241, 129);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.15/vue.js"></script>
<div id="chart">
<h1>You</h1>
<div id="actualChart">
<GChart
type="PieChart"
:data="chartData"
:options="chartOptions"
:styles="myStyles"
/>
</div>
</div>
I have tried looking online and at the documentation but they either don't show it in Vue.js or they just show how to create a chart but not customize it. If there is a better way to chart in Vue, I am open to trying it. I eventually plan on allowing the user to submit data to create the chart and potentially pull data from an API. Thank you for taking the time to read this, and maybe answering it!
The possible options for a PieChart can be found here.
For your use case it would be:
{
"chartOptions": {
"title": "Your Title",
"backgroundColor": "#00cc00",
"legend": "none"
}
}
Also check the following resource, available in the README.md file of the npm package.

Use html for a symbol marker with arcgis api

I'm trying to add custom html marker in my layer renderer.
<div>
<h1>Eg.</h1>
</div>
So far no success. From what I understand there's no way to do it but maybe someone has found a workaround.
https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-MarkerSymbol.html
layer.renderer = {
type: "simple",
symbol: {
type: "simple-marker", <-- this would be "html"
outline: {
width: 0.5,
color: "white"
}
}
};
I encountered the same scene and referred to this:
git repository
demo

Vue JS props is underfined

Im using Gridsome frame work for VUE JS
I am navigating to a new page by using this.$router.push(PATH, PARAMS)
this.$router.push({path: `/${value.sectionLink}/`, params: {pageOBJ: value}})
The page route works fine - however the PROP, pageOBJ is undefined in the page as seen in the VUE inspector:
it should be an object (which is what VALUE is set to) i.e.
I've tried a number of different techniques to resolve this but have not managed to figure this out so I assume I have missed something here?
gridsome auto generates the page routes when you add a new PAGE.VUE file to the /pages folder -
Is this the issue?
Gridsome also references graphQI, are you supposed to grab the data using graph and not by pushing Props?
Any help would be amazing here - please let me know if you need any further information.
Thanks -
W
UPDATE BASED ON CURRENT ANSWERS:
I have already added props:true to the component as shown below, but the issue is still present.
CODE SNIPPET - SUMMARY:
User clicks on the SectionTitle component, this then emits the page link
(each of the SectionTitle is a object from : sections array of Object)
To see the current online version of this please look at
wtwd.ninjashotgunbear.com
<template>
<Layout>
<div class="navs" v-for="section in sections" :key="section.sectionTitle">
<!-- On click delay for screen to come ove top -->
<!-- router to be put here -->
<SectionTitle :data="section" #routeChange="reRoute($event)"/>
</div>
<PageTransition :dataObj="transitionObj"/>
</Layout>
</template>
<script>
import SectionTitle from '#/components/SectionTitle.vue';
import PageTransition from '#/components/PageTransition.vue'
export default {
metaInfo: {
title: 'Hello, world!'
},
components: {
SectionTitle,
PageTransition
},
data(){
return {
// data to be passed to the components
sections: [
{
sectionTitle: 'Clients',
sectionLink: 'clients',
sectionSubTitle: '"Some of the amazing humans I have had the pleasure of working with"',
backgroundColor: '#F08080',
titleColor: '#E65454'
},
{
sectionTitle: 'Projects',
sectionLink: 'projects',
sectionSubTitle: '"I LIKE TO MAKE PROJECTS THAT WILL TEST MY KNOWEDGE AND EXPOSE MY WEAKNESSES"',
backgroundColor: '#20B2AA',
titleColor: '#11DACF'
},
{
sectionTitle: 'Skills',
sectionLink: 'skills',
sectionSubTitle: `"LEARNING WILL NEVER END, SO LONG AS YOUR AMBITIONS ARE STOKED, AND I've got plenty of ambition"`,
backgroundColor: '#A921B2',
titleColor: '#CA14D6'
},
{
sectionTitle: 'About Me',
sectionLink: 'aboutme',
sectionSubTitle: `"My joruney becoming a developer so far"`,
backgroundColor: '#FFFFFF',
titleColor: '#D1D1D1'
},
{
sectionTitle: 'Contact Me',
sectionLink: 'contactme',
sectionSubTitle: `"If you have any questions or want to reach out about a project then i'd love to speak with you"`,
backgroundColor: '#2185B2',
titleColor: '#0076AB'
}
],
divText: null,
transitionObj: null
}
},
methods:{
reRoute(value){
// 1)A) - change the text of the div to say the section it is being moved to
this.divText = value.sectionTitle
this.transitionObj = value
// FIND center pixcle value to place text - scrolled height + windowHeight / 2 = centerPos
let centerPos = window.scrollY+(window.innerHeight/2)
// Apply secific Title color - and center possitioning
document.querySelector('.leaveScreen p').style.cssText=`color: ${value.titleColor}; top: ${centerPos}px`
// 1) animate the loading screen
let screen = document.querySelector('.leaveScreen');
screen.style.cssText=`background: ${value.backgroundColor}; left: 0%`;
// 2) re-route the page
setTimeout(()=>{
this.$router.push({path: `/${value.sectionLink}/`, params: {pageOBJ: value}}) // << says that the route name is not found
// this.$router.push(value.sectionLink)
}, 700)
}
}
}
</script>
<style lang="scss">
// **** ERROR CAUSED BY NOT INSTALLING SCSS package ****
// https://gridsome.org/docs/assets-css/ &&&& npm install -D sass-loader node-sass
// Universal Font being used - LEMON MILK
#font-face {
font-family: LemonMilk;
src: url('../assets/fonts/LemonMilk.otf');
}
* {
box-sizing: border-box;
}
.navs {
font-family: LemonMilk;
}
.SectionTitle{
cursor: pointer;
}
</style>
Pass name rather than path in this.$router.push()
this.$router.push({name: ${value.sectionLink}, params: {pageOBJ: value}})
You should add props:true to the route definition :
{
path:'/thepath/:theParam',
component:SomeComponent,
props:true
}

Vue: Using material-design-icons offline / size

I am using materialdesignicons in my vue project.
require ('../node_modules/#mdi/font/css/materialdesignicons.min.css);
Vue.use(Vuetify, {iconfont:'mdi'});
I have a handful of icons which I dynamically create:
<v-icon>{{ some-mdi-file }}</v-icon>
When I build for production via (npm run build) I get the following error:
asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
img/materialdesignicons-webfont.someHash.svg (3.77 MiB)
That file size is huge because it includes every icon, regardless of whether it's being used. Is there a way to trim that file size down by only packaging the specific icons used. Is there a different package I should be using? Caveat: The project is hosted offline, so I need to include the fonts directly in my project.
I looked at vue-material-design-icons but it looks like it may not work for dynamic icon names and it says nothing about the overall file size/performance.
I have also looked here but clicking on the 'size warning' link brings me to a page where the Vue portion is not filled out
https://dev.materialdesignicons.com/getting-started/webfont
I would recommend using the #mdi/js package for this which provides SVG paths for each icon and supports tree shaking. Currently Vuetify doesn't support SVG icons but it should in the future.
For now, it's easy enough to create a custom icon component:
<template>
<svg :class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path :d="path" />
</svg>
</template>
<script>
export default {
name: 'my-icon',
data: () => ({
path: '',
}),
methods: {
updatePath() {
if (!this.$scopedSlots) return
if (typeof this.$scopedSlots.default !== 'function') return
this.path = this.$scopedSlots
.default()
.map((n) => n.text)
.join('')
},
},
mounted() {
this.updatePath()
},
updated() {
this.updatePath()
},
}
</script>
<style scoped>
.icon {
display: block;
color: inherit;
fill: currentColor;
width: 24px;
height: 24px;
}
<style>
Then to use it you just need to import your component and the icon you want to use:
<template>
<div class="app">
<my-icon>{{mdiCheck}}</my-icon>
</div>
</template>
<script>
import MyIcon from 'path/to/my/icon.vue'
import { mdiCheck } from '#mdi/js'
export default {
name: 'my-app',
components: {
MyIcon,
}
data: () => ({
mdiCheck,
}),
}
</script>