How to change the two switch data with click with Vuejs - javascript

Please can someone teach me the method to swap two different data on click
For example, we have a data
data() {
return {
data_one: [
{
name: "Simo",
age: "32"
}
],
data_two: [
{
name: "Lisa",
age: "25"
}
],
}
},
then I want to put this data on v-for, and I want to add two buttons to swap from data_one and data_two and display data_one as default.
<button #click="change_to_data_one">Data 1<button>
<button #click="change_to_data_two">Data 2<button>
<li v-for="item in data_one">{{item.name}} - {{item.age}}<li>
🙏🙏🙏🙏🙏

Try to use computed property:
new Vue({
el: "#demo",
data() {
return {
data_one: [{name: "Simo", age: "32"}],
data_two: [{name: "Lisa", age: "25"}],
selected: "data_one"
}
},
computed: {
showData(){
return this[this.selected]
}
},
methods: {
swap(val) {
this.selected = val
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<button #click="swap('data_one')">Data 1</button>
<button #click="swap('data_two')">Data 2</button>
<ul>
<li v-for="(item, i) in showData" :key="i">{{item.name}} - {{item.age}}</li>
</ul>
</div>

Related

Search function not searching for list of movies [duplicate]

I just got started with Vue.js and here is what I'm doing: I am rendering a list of products, and each product has a name, a gender and a size. I'd like users to be able to filter products by gender, by using an input to type the gender.
var vm = new Vue({
el: '#product_index',
data: {
gender: "",
products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
},
methods:{
updateGender: function(event){
this.gender = $(event.target).val()
}
}
}
)
<div v-for="product in products" v-if="...">
<p>{{product.name}}<p>
</div>
<input v-on:change="updateGender">
I managed to get the gender updated, but I have an issue with the filtering part. When the page loads, I don't want any filtering. In the documentation, they advise to use v-if but it doesn't seem compatible with this configuration.
If I use v-if, I could do:
v-if="product.gender == gender"
But again, this doesn't work when the page load because gender is empty.
I couldn't find a workaround for this.
How should I approach this issue ?
Use computed properties - something like this (Example bellow filter items by type)
const app = new Vue({
el: '#app',
data: {
search: '',
items: [
{name: 'Stackoverflow', type: 'development'},
{name: 'Game of Thrones', type: 'serie'},
{name: 'Jon Snow', type: 'actor'}
]
},
computed: {
filteredItems() {
return this.items.filter(item => {
return item.type.toLowerCase().indexOf(this.search.toLowerCase()) > -1
})
}
}
})
Template:
<div id="app">
<div v-for="item in filteredItems" >
<p>{{item.name}}</p>
</div>
<input type="text" v-model="search">
</div>
Demo: http://jsbin.com/dezokiwowu/edit?html,js,console,output
You can try v-if="!gender || product.gender == gender"
Just modified #Nora's answer.
You need to change in the template as:
<div id="product_index">
<div v-for="product in products" v-if="!gender || product.gender===gender">
<p>{{product.name}}<p>
</div>
<input v-on:change="updateGender">
</div>
and in JS file as:
var vm = new Vue({
el: '#product_index',
data: {
gender: "",
products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
},
methods:{
updateGender: function(event){
this.gender = event.target.value
}
}
}
);
Working Demo: https://jsbin.com/qocuraquki/edit?html,js,console,output
computed: {
filteredItems() {
return this.allStartupData.filter(item => {
let byName =
item.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
let byDescription =
item.description.toLowerCase().indexOf(this.search.toLowerCase()) >
-1;
if (byName === true) {
return byName;
} else if (byDescription === true) {
return byDescription;
}
});
}
}
and then u can iterate through filteredItems like e.g
<v-flex v-for="(obj,index) in filteredItems" :key="index" xs12 md4>
computed: {
filteredItems() {
return myObject.filter((val) => {
return val.some((val) => val.toString().toLowerCase().includes(this.searchString))
})
}}
Iterate over the Object as already described above

How to iterate array value by comparing it with another array in Vuejs?

HelloWorld.vue
<template>
<div>
<div v-for="box in boxes" :key="box.sname">
<BaseAccordian>
<template v-slot:title>{{ box.sname }}</template>
<template v-slot:content>
<div v-for="paint in paints" :key="paint.tname" class="line">
<List :content="matchingdata" :sname="box.sname" />
</div>
</template>
</BaseAccordian>
</div>
</div>
</template>
<script>
import BaseAccordian from "./BaseAccordian.vue";
import List from "./List.vue";
export default {
name: "HelloWorld",
components: {
BaseAccordian,
List,
},
data() {
return {
boxes: [
{
sname: "apple",
},
{
sname: "bananna",
},
{
sname: "grapes",
},
{
sname: "choc",
},
],
paints: [
{
tname: "a",
},
{
tname: "b",
},
{
tname: "c",
},
{
tname: "d",
},
{
tname: "e",
},
],
matchingdata: [
{
matchid: "1",
OverallStatus: "ok",
sname: "choc",
},
{
matchid: "2",
OverallStatus: "notok",
sname: "grapes",
},
],
};
},
};
</script>
BaseAccordion.vue
<template>
<div class="wrapper">
<div class="accordion">
<input type="checkbox" #click="toggleItem" />
<h2 class="title">
<slot name="title"></slot>
</h2>
</div>
<div v-show="show" class="content">
<slot name="content"></slot>
</div>
</div>
</template>
<script>
export default {
components: {},
data: function () {
return {
show: false,
};
},
methods: {
toggleItem: function () {
this.show = !this.show;
},
},
};
</script>
List.vue
<template>
<div class="">
<div
v-for="match in matchingData"
:key="match.matchid"
:class="{
green: match.OverallStatus === 'ok',
red: match.OverallStatus === 'notok',
}"
>
{{ match.OverallStatus }}
</div>
</div>
</template>
<script>
export default {
components: {},
props: {
content: {
type: Array,
required: true,
},
sname: {
type: String,
required: true,
},
},
data: function () {
return {};
},
methods: {},
computed: {
matchingData() {
return this.content.filter((a) => {
if (a.sname === this.sname) {
return true;
} else {
return false;
}
});
},
},
};
</script>
<style scoped>
</style>
I three arrays called matchingdata,boxes,paints array based on this three arrays, i am trying to filter the array.(nested v-for)
Now, I want to iterate the matchingdata array by comparing it with sname in boxes array. and Common value between matchingdata and boxes array is ""sname""
I tried above logic, and struck with computed property.
Expected Output:-
In List.vue component , i have
{{ match.OverallStatus }} where that field , i want to show,(from the matchingdata array) when user clicked on checkbox.
Taking the ""sname"" the common value from the matchingdata array and the boxes array
code:- https://codesandbox.io/s/damp-pine-27s2kn?file=/src/components/List.vue
As you're passing the sname property as a string via a prop to your List.vue component, you'll just need to use that string in your filter function.
matchingData() {
return this.content.filter((a) => a.sname === this.sname)
},
I've tried this in your codesandbox link and it is giving some output - but I'm not clear enough on what you're trying to achieve to know if this is the intended outcome.
Just incase you're not aware the 'filter' function returns a new array. It's not going to return a 'true/false' which I feel you may be trying to do.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Vue filter state array

My component state has an array named concessions with 35 objects, here's the structure of one of those objects:
{
address:"Some street"
brands: [{
id: 1,
name: 'fiat'
}]
city:"Paris"
contact_name:""
email:""
id:1
latitude:"11.11111"
longitude:"22.22222"
name:"AGORA Cars"
opening_hours:"something"
phone:"969396973"
phone2:""
zipcode:"19100"
}
Now, I have a list rendered with all car brands and a checkbox for each one like this:
<div class="brands-filter col-10">
<span v-for="brand in brands" :key="brand.key" class="brand-card">
<div>
<input
type="checkbox"
:value="brand.name"
v-model="search_filters"
#click="filterConcessions()"
/>
<label class="form-check-label">{{brand.name}}</label>
</div>
</span>
</div>
Basically, for each clicked checkbox, I'm adding the brand to searched_filters and after that I want to filter the concessions array based on those filters.
In that click method, #click="filterConcessions()", I'm doing this:
filterConcessions: function () {
let concessions = this.concessions;
let search_filters = this.search_filters;
let filteredConcessions = [];
filteredConcessions = concessions.filter((concession) =>
concession.brands.some((brand) => search_filters.includes(brand.name))
);
this.concessions = filteredConcessions;
}
But, no matter what, it gives me an empty array.
Any advice?
It's because you need to use the #change event instead of #click.
Otherwise, search_filters isn't populated before filterConcessions is run:
new Vue({
el: "#app",
data: {
search_filters: [],
concessions: [{
address: "Some street",
brands: [{
id: 1,
name: 'fiat'
}],
city: "Paris",
contact_name: "",
email: "",
id: 1,
latitude: "11.11111",
longitude: "22.22222",
name: "AGORA Cars",
opening_hours: "something",
phone: "969396973",
phone2: "",
zipcode: "19100"
}]
},
methods: {
filterConcessions: function() {
let concessions = this.concessions;
let search_filters = this.search_filters;
let filteredConcessions = concessions.filter((concession) =>
concession.brands.some((brand) => search_filters.includes(brand.name))
);
console.log(filteredConcessions)
this.concessions = filteredConcessions;
}
}
});
Vue.config.productionTip = false;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="brands-filter col-10" v-if="concessions[0]">
<span v-for="brand in concessions[0].brands" :key="brand.key" class="brand-card">
<div>
<input type="checkbox" :value="brand.name" v-model="search_filters" #change="filterConcessions()" />
<label class="form-check-label">{{brand.name}}</label>
</div>
</span>
</div>
</div>
After some search i figure how to solve this.
I've created a computed method:
computed: {
filteredConcessions() {
if (!this.search_filters.length) {
return this.concessions;
} else {
return this.concessions.filter((concession) =>
concession.brands.some((brand) =>
this.search_filters.includes(brand.name)
)
);
}
},
}
and at the for loop i iterate throw the "filteredConcessions":
<li v-for="concession in filteredConcessions" :key="concession.id" class="p-2">
And that solved my case!

How to add shopping cart with vue.js?

I try to add shopping cart,but I do not know how to do it. When count = 0,- is hidden.And when count > 0,- is show.When i try to click +, automatically increase 1, click - automatically reduced by 1. But can not be displayed.jsfiddle
Look at the Javascript file:
const goods = [{
id: "1",
goods_name: "水立方",
goods_price: "30.00",
goods_num: "15",
count:"0"
}, {
id: "2",
goods_name: "农夫山泉",
goods_price: "28.00",
goods_num: "10",
count:"0"
}]
var app = new Vue({
el: "#app",
data: {
list: goods,
},
methods: {
addCart(item,event) {
if (!this.item.count) {
Vue.set(this.item, 'count', 1);
} else {
this.item.count++;
}
},
lessCart(event) {
this.item.count--;
}
}
})
HTML file:
<div id="app">
<ul>
<li v-for="item in list">
<p>{{item.goods_name}}</p>
<p>{{item.goods_price}}</p>
<a v-show="item.count > 0" #click.stop.prevent="lessCart(item,$event)">-</a>
<input v-show="item.count > 0" v-model="item.count">
<a #click.stop.prevent="addCart(item,$event)">+</a>
</li>
</ul>
</div>
You are mutating the same state each time and not the state from the list.
You should simply do:
const goods = [{
id: "1",
goods_name: "水立方",
goods_price: "30.00",
goods_num: "15",
count:"0"
}, {
id: "2",
goods_name: "农夫山泉",
goods_price: "28.00",
goods_num: "10",
count:"0"
}]
var app = new Vue({
el: "#app",
data: {
list: goods,
},
methods: {
addCart(item) {
item.count++;
},
lessCart(item) {
item.count--;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<ul>
<li v-for="item in list">
<p>{{item.goods_name}}</p>
<p>{{item.goods_price}}</p>
<a v-show="item.count > 0" #click.stop.prevent="lessCart(item)">-</a>
<input v-show="item.count > 0" v-model="item.count">
<a #click.stop.prevent="addCart(item)">+</a>
</li>
</ul>
</div>
Note that you do not need the event argument in your method.

Filter list with Vue.js

I just got started with Vue.js and here is what I'm doing: I am rendering a list of products, and each product has a name, a gender and a size. I'd like users to be able to filter products by gender, by using an input to type the gender.
var vm = new Vue({
el: '#product_index',
data: {
gender: "",
products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
},
methods:{
updateGender: function(event){
this.gender = $(event.target).val()
}
}
}
)
<div v-for="product in products" v-if="...">
<p>{{product.name}}<p>
</div>
<input v-on:change="updateGender">
I managed to get the gender updated, but I have an issue with the filtering part. When the page loads, I don't want any filtering. In the documentation, they advise to use v-if but it doesn't seem compatible with this configuration.
If I use v-if, I could do:
v-if="product.gender == gender"
But again, this doesn't work when the page load because gender is empty.
I couldn't find a workaround for this.
How should I approach this issue ?
Use computed properties - something like this (Example bellow filter items by type)
const app = new Vue({
el: '#app',
data: {
search: '',
items: [
{name: 'Stackoverflow', type: 'development'},
{name: 'Game of Thrones', type: 'serie'},
{name: 'Jon Snow', type: 'actor'}
]
},
computed: {
filteredItems() {
return this.items.filter(item => {
return item.type.toLowerCase().indexOf(this.search.toLowerCase()) > -1
})
}
}
})
Template:
<div id="app">
<div v-for="item in filteredItems" >
<p>{{item.name}}</p>
</div>
<input type="text" v-model="search">
</div>
Demo: http://jsbin.com/dezokiwowu/edit?html,js,console,output
You can try v-if="!gender || product.gender == gender"
Just modified #Nora's answer.
You need to change in the template as:
<div id="product_index">
<div v-for="product in products" v-if="!gender || product.gender===gender">
<p>{{product.name}}<p>
</div>
<input v-on:change="updateGender">
</div>
and in JS file as:
var vm = new Vue({
el: '#product_index',
data: {
gender: "",
products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
},
methods:{
updateGender: function(event){
this.gender = event.target.value
}
}
}
);
Working Demo: https://jsbin.com/qocuraquki/edit?html,js,console,output
computed: {
filteredItems() {
return this.allStartupData.filter(item => {
let byName =
item.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
let byDescription =
item.description.toLowerCase().indexOf(this.search.toLowerCase()) >
-1;
if (byName === true) {
return byName;
} else if (byDescription === true) {
return byDescription;
}
});
}
}
and then u can iterate through filteredItems like e.g
<v-flex v-for="(obj,index) in filteredItems" :key="index" xs12 md4>
computed: {
filteredItems() {
return myObject.filter((val) => {
return val.some((val) => val.toString().toLowerCase().includes(this.searchString))
})
}}
Iterate over the Object as already described above

Categories