How to call array values dynamically from an existing array in Vuejs? - javascript

HelloWorld.vue
export const datalist = [
{ id: 1, val: "11", kk: "potter" },
{ id: 2, val: "22", kk: "james" },
{ id: 3, val: "55", kk: "limda" },
{ id: 4, val: "77", kk: "stepen" }
];
<template>
<div>
<b>Vuejs dynamic routing</b>
<div v-for="item in items" :key="item.id">
<b>{{ item.id }}.</b>
<router-link :to="{ name: 'UserWithID', params: { id: item.id } }">
{{ item.kk }}
</router-link>
</div>
<br /><br /><br />
<User />
</div>
</template>
<script>
import User from "./User.vue";
import { datalist } from "./datalist";
export default {
name: "HelloWorld",
components: {
User,
},
data() {
return {
items: datalist,
};
},
};
</script>
User.vue
import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import HelloWorld from "./components/HelloWorld.vue";
import book from "./components/book.vue";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: "/", name: "User", component: HelloWorld },
{ path: "/", name: "BookWithID", component: book },
{ path: "/:id", name: "UserWithID", component: HelloWorld }
]
});
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App)
}).$mount("#app");
export const datalisttwo = [
{ id: 1, book: "steel", pen: "p1", gap: "1" },
{ id: 2, book: "iron", pen: "jp2", gap: "5" },
{ id: 3, book: "platinium", pen: "p3", gap: "2" },
{ id: 4, book: "gold", pen: "p4", gap: "9" }
];
<template>
<div>
<router-link :to="{ name: 'BookWithID' }">
{{ user.book }}
</router-link>
</div>
</template>
<script>
import { datalisttwo } from "./datalisttwo";
export default {
name: "User",
components: {},
data() {
return {
lists: datalisttwo,
};
},
computed: {
user: function () {
return this.lists.find((item) => item.id === this.$route.params.id);
},
},
};
</script>
As per the below code, in the datalisttwo.js I have array values like steel and pen Where i want to call both of them together like steel/pen as an api call in the mounted() .
When i click on the router-link, {{ user.book }} from User.vue component.
Ex:- I want to pass the pen/gap array values as query parameters. when clicked on {{ user.book }} from user.vue componet. Please go through codesandbox once, I tried adding computed property for pen and gap. But pen/gap --- but not calling dynamically
Here is my code:- https://codesandbox.io/s/new-hill-6yum4o?file=/src/components/User.vue

Your question and description is quite unclear, so I'll try to answer how I understand it. If that is not what you were expecting, try to explain it again clearly.
First, define your routes clearly. Here your have two routes pointing to '/'. Try to do it to have your user index at '/', your book at '/book/:id', and your user at 'user/:id'.
Second, I am unsure why you have your HelloWorld.vue in both User and UserWithId routes. If intended, disregard. If not, you should clean up that whole file to get the right route pointing to the right component.
Third, used on your example of potter, if you are looking at the book component, for which you haven't provided the code, you can do it such as:
...
computed: {
book() {
if (this.$route.params.id == null || this.$route.params.id == undefined) {
throw new Error('No book id provided')
}
return datalisttwo.find(_ => _.id == this.$route.params.id)
},
pen() {
this.book.pen
},
gap() {
this.book.gap
}
}
...
With this you'll be able to do whatever you whish with this.pen and this .gap.
Now, if you were to want to not import data list again, you can pass your retrieved pen & gap as query parameters: https://router.vuejs.org/api/

import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import HelloWorld from "./components/HelloWorld.vue";
import book from "./components/book.vue";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: "/", name: "User", component: HelloWorld },
{ path: "/", name: "BookWithID", component: book },
{ path: "/:id", name: "UserWithID", component: HelloWorld }
]
});
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App)
}).$mount("#app");
export const datalisttwo = [
{ id: 1, book: "steel", pen: "p1", gap: "1" },
{ id: 2, book: "iron", pen: "jp2", gap: "5" },
{ id: 3, book: "platinium", pen: "p3", gap: "2" },
{ id: 4, book: "gold", pen: "p4", gap: "9" }
];
<template>
<div>
<router-link :to="{ name: 'BookWithID' }">
{{ user.book }}
</router-link>
</div>
</template>
<script>
import { datalisttwo } from "./datalisttwo";
export default {
name: "User",
components: {},
data() {
return {
lists: datalisttwo,
};
},
computed: {
user: function () {
return this.lists.find((item) => item.id === this.$route.params.id);
},
},
};
</script>
I ran this directly.
Error 1:
Imports must be at the top.
Look at 25, 0
Error 2:
Exports must be at the top
Look at 41, 8

Related

vue #/src/assets/images/1.jpg: hasn't been transpiled yet error

**I'm getting this error - vue #/src/assets/images/1.jpg: hasn't been transpiled yet error. I'm looping through tha App component static array. The src is specified correctly though. Using require vue method.
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="container">
<div class="v-carousel">
<v-carousel-item
v-for="item in carousel_data"
:key="item.id"
:item_data="item"
/>
</div>
</div>
</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>
You want to require the images upfront.
export default {
name: "App",
data() {
return {
sliderItems: [
{ id: 1, name: "img1", img: require("#/assets/images/1.jpg") },
{ id: 2, name: "img2", img: require("#/assets/images/2.jpg") },
{ id: 3, name: "img3", img: require("#/assets/images/3.jpg") },
],
};
},
Then update the carousel item component.
<div class="v-carousel-item">
<img :src="item_data.img" alt="" />
</div>
Example: https://codesandbox.io/s/little-bush-ino5zc?file=/src/components/v-carousel-item.vue:11-91

Pinia | Vue3 - Accessing array in deep object

In Pinia (base.js)
export const useBaseStore = defineStore('base', {
state: () => {
return {
areaLocal: [
{ id: 0, name: 'LAX' },
{ id: 1, name: 'SFO' },
{ id: 2, name: 'SAN' },
],
areaLocal2: {
area: [
{ id: 0, name: 'AAA'},
{ id: 1, name: 'BBB'},
{ id: 2, name: 'CCC'},
]},
}
},
getters: {
getAreaById: (state) => {
return (areaId) =>
state.areaLocal.find((areaLocal) => areaLocal.id === areaId)
},..
in Vue (area.vue)
<script setup>
import { computed, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useBaseStore } from '../stores/base'
const areaStore = useBaseStore()
const { getAreaById } = storeToRefs(areaStore)
const areaIndex = ref(0)
</script>
<template>
<div class="container">
<h2>AREA: {{ getAreaById(areaIndex).name }}</h2>
....
This, areaLocal, I get "AREA: LAX", which is correct,
but HOW I can write "getter" in the pinia for access to "areaLocal2", the object "area" then the array?
state.areaLocal2.area.find((areaLocal2.area) => areaLocal.id.area === areaId
The above throws an undefined error.
getArea2ById: (state) => (areaIa) => state.areaLocal2.area.find((area) => area.id === areaId)
You are already in area by the time you hit the find higher order function so no need to reference it again inside of it.

Vue.js update parent data with an input from a child component

I'm using Vue.js 2 and I'm trying to update the description of a file using an input in a child component. I've been reading a few related questions and read some of the official docs along with .sync but I'm struggling to get the result I want since files is a list of objects.
Here's what I've been trying.
Vue.component('myComponent', {
props: ["file"],
data() {
return {
myDescription: '',
}
},
mounted() {
this.myDescription = this.file.description;
},
template: `
<div>
<label>{{ file.name }}</label>
<br>
<input type="text" #input="update" :value="myDescription"></input>
<br><br>
</div>
`,
methods: {
update() {
this.$emit("update-description", this.myDescription, this.file);
},
}
})
var app = new Vue({
el: '#app',
methods: {
updateDescription(description, file) {
console.log(description);
}
},
data: {
files: [{
id: 1,
name: "Hello",
description: "",
},
{
id: 2,
name: "World",
description: "Foo",
},
{
id: 3,
name: "John",
description: "Bar",
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div> {{ files }} </div>
<br>
<my-component v-for="file in files" :key="file.id" :file="file" #update-description="updateDescription" />
</div>
You're almost there, you can see in the code you've provided that the child component event is being emitted but the value is empty. The problem is you're not updating myDescription, if you change your :value to v-model then it will update, as v-model uses two way binding.
Also, if you want to update the file description, you can just do:
file.description = description;
Vue.component('myComponent', {
props: ["file"],
data() {
return {
myDescription: '',
}
},
mounted() {
this.myDescription = this.file.description;
},
template: `
<div>
<label>{{ file.name }}</label>
<br>
<input type="text" #input="update" v-model="myDescription"></input>
<br><br>
</div>
`,
methods: {
update() {
this.$emit("update-description", this.myDescription, this.file);
},
}
})
var app = new Vue({
el: '#app',
methods: {
updateDescription(description, file) {
console.log(description);
file.description = description;
}
},
data: {
files: [{
id: 1,
name: "Hello",
description: "",
},
{
id: 2,
name: "World",
description: "Foo",
},
{
id: 3,
name: "John",
description: "Bar",
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div> {{ files }} </div>
<br>
<my-component v-for="file in files" :key="file.id" :file="file" #update-description="updateDescription" />
</div>

Bootstrap-vue - Modify Navbar from Vue component?

I have a Vue Bootstrap SPA with the following structure:
layout
navbar
breadcrumb
router view
component
some content
I would like my component to inject a submenu to the parent's navbar. For example:
export default {
name: 'Component',
data() {
return {
menu: [
'Item': {
href: '#'
}
]
}
},
mounted() {
parent.menu.addItem(this.menu)
}
}
Is this possible to do something like this?
Here the top layout:
<template>
<div>
<navbar :menu="menu"></navbar>
<router-view></router-view>
</div>
</template>
<script>
import NavBar from './navbar'
export default {
components: {
navbar: NavBar
},
data() {
return {
menu: [
{
text: "Foo",
href: "/foo",
},
{
text: "Bar",
href: "#",
},
],
};
},
};
</script>
You could emit an event to the parent component like :
data() {
return {
menu: [
{
href: '#'
}
]
}
},
mounted() {
this.$emit('emit-menu',this.menu)
}
in parent :
<template>
<navbar :menu="menu" #emit-menu="addItem"></navbar>
<router-view></router-view>
</div>
</template>
<script>
import NavBar from './navbar'
export default {
components: {
navbar: NavBar
},
methods:{
addItem(menu){
this.menu=[..this.menu,...menu]
}
},
data() {
return {
menu: [
{
text: "Foo",
href: "/foo",
},
{
text: "Bar",
href: "#",
},
],
};
},
};
</script>

Aurelia simple binding is not working

I have a very simple binding which isn't working as I'd expect it to:
app.js:
export class PupilsViewer {
pupilsInfo = [
{ name: 'John' },
{ name: 'Eric' },
{ name: 'Martin' },
{ name: 'Simon' }
];
}
app.html:
<template>
<require from="./pupil"></require>
<pupil repeat.for="pupilInfo of pupilsInfo" info="${pupilInfo}"></pupil>
</template>
pupil.js:
import {bindable} from 'aurelia-framework';
export class Pupil {
#bindable info = { name: 'unknown' };
}
pupil.html:
<template>
<div>Name: ${info.name}</div>
</template>
This results in the following output:
Name: unknown
Name: unknown
Name: unknown
Name: unknown
whilst I'd have expected:
Name: John
Name: Eric
Name: Martin
Name: Simon
right now i had the same problem. it seems to be a typo-problem. try to change or remove camel-case for your bindables. but your binding is also not ok.
export class PupilsViewer {
pupils = [
{ name: 'John' },
{ name: 'Eric' },
{ name: 'Martin' },
{ name: 'Simon' }
];
}
app.html
<template>
<require from="./pupil"></require>
<pupil repeat.for="pupil of pupils" info.bind="pupil"></pupil>
</template>
pupil.js
import {customElement, bindable} from 'aurelia-framework';
#customElement('pupil')
#bindable('info')
export class Pupil {
}

Categories