require method images not rendered vue js - javascript

**The require method images are not rendered with Vuejs. Even though I've add the vue-loader dependency, and the props are delivered correctly. The template is simple - just an array in App component, a Parent and a Child component.
Can anyone help ?
https://codesandbox.io/s/eloquent-grass-j1usw8?file=/src/components/v-carousel-item.vue**
// App
<template>
<v-carousel :carousel_data="sliderItems" />
</template>
<script>
import vCarousel from "./components/v-carousel.vue";
export default {
name: "App",
data() {
return {
sliderItems: [
{ id: 1, name: "img1", img: "1.jpg" },
{ id: 2, name: "img2", img: "2.jpg" },
{ id: 3, name: "img3", img: "3.jpg" },
],
};
},
components: {
vCarousel,
},
};
</script>
//Parent
<template>
<div class="v-carousel"></div>
<v-carousel-item
v-for="item in carousel_data"
:key="item.id"
:item_data="item"
/>
</template>
<script>
import vCarouselItem from "./v-carousel-item.vue";
export default {
components: {
vCarouselItem,
},
props: {
carousel_data: {
type: Array,
default: () => [],
},
},
};
</script>
// Child
<template>
<div class="v-carousel-item">
<img src="require('../assets/images' + item_data.img)" alt="" />
</div>
</template>
<script>
export default {
props: {
item_data: {
type: Object,
default: () => {},
},
},
};
</script>

Related

Setting preselected value as object via v-model in child component made of DevExtreme DxSelectBox not working in Vue3 composition API

I have made a child component - Dropdown based on Devextreme DxSelectBox.
I set in parent component v-model as attribute and forward to it an variable as ref, which is set to initial selected valueconst item = ref({ value: "option 1" }), but the DxSelectBox is empty when loading the project.
Child component - Dropdown is emitting the right selected option, but unfortunately the initial selected value is not set.
Code for Parent App.vue component is:
<template>
<template>
<Dropdown :items="items" v-model:option="item" />
<div class="emitting">Emitting: {{ item }}</div>
</template>
<script>
import { ref } from "vue";
import Dropdown from "./components/Dropdown.vue";
export default {
name: "App",
components: {
Dropdown: Dropdown,
},
setup(props, context) {
const emitValue = (e) => {
context.emit("update:option", e.value);
};
const items = ref([
{
value: "option 1",
},
{
value: "option 2",
},
{
value: "option 3",
},
]);
const item = ref({
value: "option 1",
});
return {
items,
item,
emitValue,
};
},
};
</script>
<style>
#import "https://cdn3.devexpress.com/jslib/18.2.8/css/dx.light.css";
#import "https://cdn3.devexpress.com/jslib/18.2.8/css/dx.common.css";
</style>
and code for Dropdown.vue component is:
<template>
<template>
<div class="dx-field">
<DxSelectBox
:data-source="items"
:value="option"
#valueChanged="emitValue"
:width="width"
:height="height"
:drop-down-options="{ width: width }"
display-expr="value"
:disabled="disabled"
:read-only="readOnly"
:hint="hint"
:placeholder="placeholder"
/>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType, watch, ref } from "vue";
import DxSelectBox from "devextreme-vue/select-box";
export default defineComponent({
name: "DpmDropdown",
components: {
DxSelectBox,
},
emits: ["update:option"],
props: {
label: { type: String, default: "" },
showLabel: { type: Boolean, default: true },
headingTooltip: { type: String, default: "" },
items: { type: Array, default: () => [] },
option: { type: Object, default: () => ({}) },
width: { type: [Number, String], default: "100%" },
height: { type: String, default: "40px" },
icon: { type: String, default: "" },
hint: { type: String, default: "" },
disabled: { type: Boolean, default: false },
readOnly: { type: Boolean, default: false },
placeholder: { type: String, default: "" },
},
setup(props, context) {
const emitValue = (e: any) => {
context.emit("update:option", e.value);
};
return {
emitValue,
};
},
});
</script>
The link for sandbox project is here.

How to highlight active menu item with Typescript and Vue.js 3?

I have a menu and would like to highlight the currently active menu item.
I think I should write in the first template the following: v-if(selected) and some function maybe.
<template>
<MenuTreeView #selected='collapsedMenuSelected' :items='filteredFirstLevelNavigation' :filter="false"/>
</template>
MenuTreeView:
<template>
<Tree :value="items" filterPlaceholder="Suche" :expandedKeys="expandedKeys" filterMode="lenient" :filter="filter"
selectionMode="single" #nodeSelect="onNodeSelect"></Tree>
</template>
In such cases, you need to store the id of the active element in the data of the parent component. This can be done by saving the id when selecting one of the rows.
Parent
<template>
<div class="menu">
<MenuItem
v-for="row in rows"
:active-id="activeId"
:key="row.id"
#select="handleSelect"
/>
</div>
</template>
<script>
import MenuItem from "./MenuItem";
export default {
name: "TheMenu",
components: {
MenuItem,
},
data() {
return {
activeId: null,
rows: [
{
id: 1,
label: "First",
},
{
id: 2,
label: "Second",
},
{
id: 3,
label: "Third",
},
],
};
},
methods: {
handleSelect(id) {
this.activeId = id;
},
},
};
</script>
Child
<template>
<div
class="menu-item"
:class="{
'menu-item_active': activeId === row.id,
}"
#click="handleSelect"
>
{{ row.label }}
</div>
</template>
<script>
export default {
name: "MenuItem",
props: {
row: {
type: Object,
required: true,
},
activeId: {
type: Number,
required: true,
},
},
methods: {
handleSelect() {
this.$emit("select", this.row.id);
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.menu-item {
/* your styles */
display: flex;
width: 100%;
}
.menu-item_active {
background-color: red;
}
</style>

Vue.js (vuex). Computed property returns undefined when reloading the page. (Hard coded array of objects data in vuex)

I am building a shoe shop with Vue and the problem is that I am getting undefined when reloading the page when I am trying to access a getter through computed property on the ShoeDetail component.I am storing some hard coded array of objects data in the vuex state. In the Shoe component I am looping through the data with v-for and outputting in the Men view, that is working for me, all avaliable shoes are displayed. When a user clicks on the shoe image a new route is loaded for each shoe with further details for that shoe which got clicked. I am using the id for dynamic routing. Now i have a getter in vuex
getProductById: (state) => (id) => {
return state.sneakers.find((sneaker) => sneaker.productId === id);
},
then I access it through a computed property:
product() {
return this.$store.getters.getProductById(this.$route.params.id);
},
that works fine and I can output the data stored in vuex state by interpolitaion like:
{{product.brand}}
When I reload the page I get this error:
**[Vue warn]: Error in render: "TypeError: Cannot read property 'brand' of undefined"
found in
---> <Detail> at src/components/ShoeDetail.vue
<App> at src/App.vue
<Root>**
I have tried to use v-if="product" but since im not making an API call this shouldn't be relevant.
I have also installed the createPersistedState but it still doesn't work. I am really stuck here and a hint on why im getting undefined on page reload would be appreciated
My vuex:
import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate';
Vue.use(Vuex);
export default new Vuex.Store({
plugins: [
createPersistedState({
key: 'keyname',
storage: window.localStorage,
}),
],
state: {
sneakers: [
{
productId: 1,
productno: 1234,
brand: 'nike',
gender: 'men',
size: 5,
price: 150,
image: require('#/assets/images/nike-air-zoom.jpg'),
},
{
productId: 2,
productno: 1235,
brand: 'adidas',
gender: 'men',
size: 10,
price: 140,
image: require('#/assets/images/sneakers.jpg'),
},
{
productId: 3,
productno: 1236,
brand: 'adidas',
gender: 'men',
size: 10,
price: 130,
image: require('#/assets/images/man-holding-nikes.jpg'),
},
{
productId: 4,
productno: 1237,
brand: 'nike',
gender: 'men',
size: 5,
price: 120,
image: require('#/assets/images/nike-air-zoom.jpg'),
},
{
productId: 5,
productno: 1238,
brand: 'adidas',
gender: 'men',
size: 10,
price: 110,
image: require('#/assets/images/sneakers.jpg'),
},
{
productId: 6,
productno: 1239,
brand: 'adidas',
size: 10,
price: 100,
image: require('#/assets/images/man-holding-nikes.jpg'),
},
],
},
getters: {
getProducts: (state) => {
return state.sneakers;
},
getProductById: (state) => (id) => {
return state.sneakers.find((sneaker) => sneaker.productId === id);
},
},
});
The Shoe component:
<template>
<div class="shoe-container">
<div class="shoe-card" v-for="element in products" :key="element.id">
<router-link
:to="{ name: 'ShoeDetail', params: { id: element.productId } }"
><img :src="element.image" tag="img" alt="" class="shoe-card__image"
/></router-link>
<p class="shoe-card__model">{{ element.brand }}</p>
<p class="shoe-card__price">{{ element.price }} $</p>
</div>
</div>
</template>
<script>
export default {
computed: {
products() {
return this.$store.getters.getProducts;
},
product() {
return this.$store.getters.getProductById(this.$route.params.id);
},
},
};
</script>
<style lang="scss" scoped>
#import '../sass/components/shoe';
</style>
The men view:
<template>
<div>
<navbar></navbar>
<sub-nav></sub-nav>
<filter-section></filter-section>
<section class="shoes">
<shoe></shoe>
</section>
</div>
</template>
<script>
import Navbar from "../components/Navbar.vue";
import SubNav from "../components/SubNav.vue";
import FilterSection from "../components/FilterSection.vue";
import Shoe from "../components/Shoe.vue";
export default {
components: {
Navbar,
SubNav,
FilterSection,
Shoe
}
};
</script>
<style lang="scss" scoped>
#import "../sass/views/men";
</style>
The ShoeDetail component:
<template>
<div class="details">
<h1>This is details</h1>
<h2>{{ product.brand }}</h2>
</div>
</template>
<script>
export default {
name: 'detail',
computed: {
product() {
return this.$store.getters.getProductById(this.$route.params.id);
},
},
};
</script>
<style lang="scss" scoped>
#import '../sass/components/shoeDetail';
</style>
Thanks for the answer I was able to fix it by adding parseInt in the computed property of ShoeDetail.
computed: {
product() {
return this.$store.getters.getProductById(
parseInt(this.$route.params.id)
);
},
}
Do this in the ShoeDetail component:
data: () => {
data: '',
},
methods: {
getProduct () {
this.product = this.$store.getters.getProductById(this.$route.params.id);
},
},
mounted () {
this.getProduct();
}
and it should work :)

Vue.Js / Vuex - how to declare id of elements

This is a simple shopping Cart
Actually, when we clic on items, it updated the total number in the Cart.
But i want now to make a better Cart: showing each items in the list. Like when we chose 2 croissiants, it adds 2 croissiants in the Cart.
My problem is, in this course, i didn't really learn how to make a Mutation dependings of the ID of the item. I'm looking for the syntax witch is sending the ID of the item where we clicked, to the store.
Here my my 3 files : (Store's "index", "Home" and it's children "MenuItem")
Store :
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
restaurantName: 'Cafe with A Vue',
shoppingCart: 0,
croissiantNumber: 0,
baguetteNumber: 0,
eclairNumber: 0,
simpleMenu: [
{
id: 1,
name: 'Crossiant',
image: {
source: '/images/crossiant.jp',
alt: 'A crossiant'
},
inStock: true,
quantity: 1,
price: 2.99
},
{
id: 2,
name: 'French Baguette',
image: {
source: '/images/french-baguette.jpe',
alt: 'Four French Baguettes'
},
inStock: true,
quantity: 1,
price: 3.99
},
{
id: 3,
name: 'Éclair',
image: {
source: '/images/eclair.jp',
alt: 'Chocolate Éclair'
},
inStock: false,
quantity: 1,
price: 4.99
}
]
},
getters: {
copyright: state => {
const currentYear = new Date().getFullYear()
return `Copyright ${state.restaurantName} ${currentYear}`
}
},
mutations: {
ADD_ITEMS_TO_SHOPPING_CART(state, amount) {
state.shoppingCart += amount
}
},
actions: {
updateShoppingCart({ commit }, amount) {
commit('ADD_ITEMS_TO_SHOPPING_CART', amount),
commit('ADD_ITEM_TO_SHOPPING_CART', amount)
}
},
modules: {}
})
Home :
<template>
<div>
<h1>{{ restaurantName }}</h1>
<p class="description">
Welcome to {{ restaurantName }}! We are known for our freshly baked bread
and french pastries! Give you morning a warm start or treat yourself in
the middle of the day. Our butter is imported from local farmers in
France. Once you take your first bite, you will see why everyone can't get
enough!
</p>
<section class="menu">
<h2>Menu</h2>
<MenuItem
v-for="item in simpleMenu"
:name="item.name"
:image="item.image"
:price="item.price"
:quantity="item.quantity"
:inStock="item.inStock"
:key="item.name"
:id="item.id"
/>
</section>
<div class="shopping-cart">
<h2>Shopping Cart: {{ shoppingCart }} items</h2>
<h2>Croissiant: {{ croissiantNumber }} items</h2>
<h2 v-if="baguetteNumber">French Baguette: {{ baguetteNumber }} items</h2>
<h2 v-if="eclairNumber">Eclair: {{ eclairNumber }}items</h2>
</div>
<footer class="footer">
<p>{{ copyright }}</p>
</footer>
</div>
</template>
<script>
import MenuItem from '../components/MenuItem'
import { mapGetters, mapState } from 'vuex'
export default {
name: 'Home',
components: {
MenuItem
},
computed: {
...mapGetters({
copyright: 'copyright'
}),
...mapState({
restaurantName: 'restaurantName',
shoppingCart: 'shoppingCart',
croissiantNumber: 'croissiantNumber',
baguetteNumber: 'baguetteNumber',
eclairNumber: 'eclairNumber',
simpleMenu: 'simpleMenu'
})
}
}
</script>
MenuItem :
<script>
import { mapActions } from 'vuex'
import BaseButton from './BaseButton.vue'
export default {
name: 'MenuItem',
components: {
BaseButton
},
props: {
image: {
type: Object,
required: true
},
inStock: {
type: Boolean,
required: true
},
name: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
quantity: {
type: Number,
defaut: 1
}
},
data() {
return {
onSale: false
}
},
computed: {
generatedPrice() {
if (this.onSale) {
return (this.price * 0.9).toFixed(2)
} else {
return this.price
}
}
},
methods: {
...mapActions(['updateShoppingCart'])
},
beforeMount() {
const today = new Date().getDate()
if (today % 2 === 0) {
this.onSale = true
}
}
}
</script>
<template>
<div class="menu-item">
<img class="menu-item__image" :src="image.source" :alt="image.alt" />
<div>
<h3>{{ name }}</h3>
<p>Price: {{ generatedPrice }} <span v-if="onSale">(10% off!)</span></p>
<p v-if="inStock">In Stock</p>
<p v-else>Out of Stock</p>
<div>
<label for="add-item-quantity">Quantity: {{ quantity }}</label>
<input v-model.number="quantity" id="add-item-quantity" type="number" />
<BaseButton #click="updateShoppingCart(quantity, id)" class="test">
Add to shopping cart
</BaseButton>
</div>
</div>
</div>
</template>
So i want to update this value for example :
Croissiant: 0 items
Website preview
Thanks.
You have to pass either object or array to your action to handle multiple parameters.
#click="updateShoppingCart({quantity, id})"
and then in store:
...
actions: {
updateShoppingCart({ commit }, {quantity, id}) {
commit('ADD_ITEMS_TO_SHOPPING_CART', amount),
//here you have id that you can map to item type
}
},
I would suggest having item type that is constant in simpleMenu and not depending on IDs.

Vue.js - How to get "this" object in componenet?

console.log(this) in doSomthing method, it is displayed "null".
I thought of console.log(this.currentPage) is displayed "main" but "this" object is null.. :(
How to access "main" of currentPage?
<template>
<div class="tab_menu_wrap">
<ul class="tab_menu">
<li v-for="tab in tabMenus" v-bind:class="{ active: tab.isActive }" v-on:click="doSomthing">
{{ tab.text }}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'tab-menu',
props: {
},
data() {
return {
currentPage: "main",
isActive: true,
tabMenus: [
{
text: 'A',
isActive: true
},
{
text: 'B',
isActive: false
},
{
text: 'C',
isActive: false
}
],
doSomthing: function(e){
console.log(this)
}
};
},
method: {
},
computed: {
}
};
</script>
I think data() should only have the state of your component, no actions.
Try moving your doSomething to methods in your component, like:
<template>
<div class="tab_menu_wrap">
<ul class="tab_menu">
<li v-for="tab in tabMenus" v-bind:class="{ active: tab.isActive }" v-on:click="doSomething">
{{ tab.text }}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'tab-menu',
props: {
},
data() {
return {
currentPage: "main",
isActive: true,
tabMenus: [
{
text: 'A',
isActive: true
},
{
text: 'B',
isActive: false
},
{
text: 'C',
isActive: false
}
]
};
},
methods: {
doSomething: function(e){
console.log(this)
}
},
computed: {
}
};
</script>

Categories

Resources