link1918 link1919 link1920 link1921 link1922 link1923 link1924 link1925 link1926 link1927 link1928 link1929 link1930 link1931 link1932 link1933 link1934 link1935 link1936 link1937 link1938 link1939 link1940 link1941 link1942 link1943 link1944 link1945 link1946 link1947 link1948 link1949 link1950 link1951 link1952 link1953 link1954 link1955 link1956 link1957 link1958 link1959 link1960 link1961 link1962 link1963 link1964 link1965 link1966 link1967 link1968 link1969 link1970 link1971 link1972 link1973 link1974 link1975 link1976 link1977 link1978 link1979 link1980 link1981 link1982 link1983 link1984 link1985 link1986 link1987 link1988 link1989 link1990 link1991 link1992 link1993 link1994 link1995 link1996 link1997 link1998 link1999 link2000 link2001 link2002 link2003 link2004 link2005 link2006 link2007 link2008 link2009 link2010 link2011 link2012 link2013 link2014 link2015 link2016 link2017 link2018 link2019 link2020 link2021 link2022 link2023 link2024 link2025 link2026 link2027 link2028 link2029 link2030 link2031 link2032 link2033 link2034 link2035 link2036 link2037 link2038 link2039 link2040 link2041 link2042 link2043 link2044 link2045 link2046 link2047 link2048 link2049 link2050 link2051 link2052 link2053 link2054

[Vue.js] Passing Array as prop not received on the other component Subscribe to RSS

when trying to pass an array of objects as a prop to a component. The Array is being passed without an array. when neither receiving any compilation error.

I tried actually looking on to the object tried some stuff. But it did not work

Here is the code:

CardRenderer.vue:

<template lang=”html”>

<div>
<b-container class=”bv-example-row”>
<b-row v-for=”(row, i) of rows” v-bind:key=”i”>
<b-col v-for=”(item, j) of row” v-bind:key=”j” >
<!– you card –>
<b-card
:title=”item.title”
img-src=”item.icon”
img-alt=”Image”
img-top
tag=”article”
style=”max-width: 20rem;”
class=”mb-2”
\>
<b-card-text>
<h1>{item.name}</h1>
<pre>{item.description}</pre>
</b-card-text>
<b-button :href=”‘/dashboard/‘+item.name” variant=”primary”>More</b-button>
</b-card>
</b-col>
</b-row>
</b-container>
</div>

</template>

<script lang=”js”>
export default {
name: ‘CardRenderer’,
props: {
renderData: {
type: Array,
required: true,
default: () => ([]),
}
},
data() {
return {
rows: null
}
},
mounted() {

const itemsPerRow = 3
let rowss = []
// eslint-disable-next-line
console.log(this.renderData)
let arr = this.renderData

for (let i = 0; i < arr.length; i += itemsPerRow) {
let row = []
for (let z = 0; z < itemsPerRow; z++) {
row.push(arr[z])
}
rowss.push(row)
}

this.rows = rowss

// eslint-disable-next-line
// console.log(this.rows)

},

methods: {

},
computed: {
// rows() {
// }

}
}
</script>

<style scoped>

</style>

Something.vue

<template lang=”html”>
<!– <h1>Something</h1> –>
<CardRenderer :renderData=valObj />
</template>

<script lang=”js”>
import CardRenderer from ‘./CardRenderer’

export default {
name: ‘something’,
components: {
CardRenderer
},
props: [],

data() {
return {
valObj: []
}
},
mounted() {
let key = this.findUrl()
let value = this.$store.getters.responseAPI.apps.filter((elem) => {
if(elem.name == key) return elem.apps
})

if (value && value.length > 0)
this.valObj = value[0].apps
//eslint-disable-next-line
console.log(this.valObj)
},
methods: {
findUrl() {
let url = window.location.pathname.split(“/“).slice(-1)[0];
return url
}
},
computed: {

}
}
</script>

<style scoped >
.something {

}
</style>

This is what when sending as a prop.

This is what i receive on the component

Solution :

There’s a couple of issues here.

First, you should be using kebab-cased attribute names and quotes around the value…

<CardRenderer :render-data=”valObj” />

The second issue is timing related. In the component, you calculate rows based on the initial renderData in the mounted hook but this will not update when the parent component alters valObj.

What you should do instead is use a computed property which will react to valObj / renderData changes.

For example

data () { return {} }, // removed rows from data
computed: {
rows () {
let itemsPerRow = 3
let rows = []
for (let i = 0; i < this.renderData.length; i += itemsPerRow) {
rows.push(this.renderData.slice(i, i + itemsPerRow))
}
return rows
}
}

[Vue.js] Filter based on multiple conditions and multiple arrays? Subscribe to RSS

there is a list of products in JSON like this:

{
“products”: [
{
“tags”: [“filter-color-White”, “filter-style-Low 1”, “5”, “6”, “7”, “8”, “9”, “10”, “11”, “12”, “13”],
“styles”: [“filter-style-Low 1”],
“colors”: [“filter-color-White”],
“sizes”: [“5”, “6”, “7”, “8”, “9”, “10”, “11”, “12”, “13”]
},
{
“tags”: [“filter-color-Black”, “filter-color-Red”, “filter-color-Blue”, “filter-style-Boot”, “7”, “8”, “9”, “12”, “13”],
“styles”: [“filter-style-Boot”],
“colors”: [“filter-color-Black”, “filter-color-Red”, “filter-color-Blue”],
“sizes”: [“7”, “8”, “9”, “12”, “13”]
},
{
“tags”: [“filter-color-Black”, “filter-color-Red”, “filter-style-Gat”, “7”, “8”, “9”, “10”, “11”, “12”, “13”],
“styles”: [“filter-style-Gat”],
“colors”: [“filter-color-Black”, “filter-color-Red”],
“sizes”: [“7”, “8”, “9”, “10”, “11”, “12”, “13”]
}



]
}

As you can see, there are styles, colors, and sizes. And there’s also a tags item which is actually made up out of all three of those previous ones.

I need for someone to be able to filter based on multiple selections. As in, if someone selects the Low 1 style and then black, then show them black items in that style. But if they ALSO select white, then show them white OR black, or both. Same with size selections. Example: Low 1 items that are black, or white, AND size 5, or size 6, or both.

Lastly, multiple styles should be selectable at once and also colors and sizes should be selectable without a style being selected. So the above example, but then add in another style on top like the Boot style. It should then return products that match ALL the criteria.

Is this even doable?

Currently I’m doing it like this:

let filterOptions = this.selectedOptions;
this.products.forEach(product => {
if (filterOptions.some(item => product.tags.includes(item))) {
return product.visible = true;
} else if(filterOptions.length == 0) {
return product.visible = true;
} else {
return product.visible = false;
}
})

where product.visible is just a simple bool that allows vuejs to show the item on the page or not and this.selectedOptions is an array that gets dynamically populated every time someone adds/removes an option inside the filter. Example of what it would like like:

this.selectedOptions = [“filter-style-Erving”,”filter-color-Black”,”filter-color-Brown”,”8”,”9”]

The above filtering code works but not reliably. It returns all items that match any of the criteria, irrespective of the other selected filters. If I change some to every the opposite happens where it then tries to only find items that have a red AND black color. Or a 5 AND 6 size, etc.

I’m more or less trying to replicate the filtering on https://www.everlane.com/collections/mens-tees

Solution :

This filter is actually open.

But I think you are looking for something where some items are AND and others OR

So if user picks a size you want to filter those.

But color is an || option?

If so, I will correct to that model.
Let me know.

const p = {
“products”: [
{
“tags”: [“filter-color-White”, “filter-style-Low 1”, “5”, “6”, “7”, “8”, “9”, “10”, “11”, “12”, “13”],
“styles”: [“filter-style-Low 1”],
“colors”: [“filter-color-White”],
“sizes”: [“5”, “6”, “7”, “8”, “9”, “10”, “11”, “12”, “13”]
},
{
“tags”: [“filter-color-Black”, “filter-color-Red”, “filter-color-Blue”, “filter-style-Boot”, “7”, “8”, “9”, “12”, “13”],
“styles”: [“filter-style-Boot”],
“colors”: [“filter-color-Black”, “filter-color-Red”, “filter-color-Blue”],
“sizes”: [“7”, “8”, “9”, “12”, “13”]
},
{
“tags”: [“filter-color-Black”, “filter-color-Red”, “filter-style-Gat”, “7”, “8”, “9”, “10”, “11”, “12”, “13”],
“styles”: [“filter-style-Gat”],
“colors”: [“filter-color-Black”, “filter-color-Red”],
“sizes”: [“7”, “8”, “9”, “10”, “11”, “12”, “13”]
}
]
};

const getFiltered = ( ({products}, filterValues) =>
products.filter(p => Object.entries(p)
.flatMap(([k, v]) => v)
.some(entry => filterValues.includes(entry))));

console.log(getFiltered(p, [“5”, “filter-style-Gat”]));

Assuming we want some conditional:

const p = {
“products”: [{
“tags”: [“filter-color-White”, “filter-style-Low 1”, “5”, “6”, “7”, “8”, “9”, “10”, “11”, “12”, “13”],
“styles”: [“filter-style-Low 1”],
“colors”: [“filter-color-White”],
“sizes”: [“5”, “6”, “7”, “8”, “9”, “10”, “11”, “12”, “13”]
},
{
“tags”: [“filter-color-Black”, “filter-color-Red”, “filter-color-Blue”, “filter-style-Boot”, “7”, “8”, “9”, “12”, “13”],
“styles”: [“filter-style-Boot”],
“colors”: [“filter-color-Black”, “filter-color-Red”, “filter-color-Blue”],
“sizes”: [“7”, “8”, “9”, “12”, “13”]
},
{
“tags”: [“filter-color-Black”, “filter-color-Red”, “filter-style-Gat”, “7”, “8”, “9”, “10”, “11”, “12”, “13”],
“styles”: [“filter-style-Gat”],
“colors”: [“filter-color-Black”, “filter-color-Red”],
“sizes”: [“7”, “8”, “9”, “10”, “11”, “12”, “13”]
}
]
};

const getFiltered = (({ products }, {
tags,
styles,
colors,
sizes
}) => {
// Filter size fully.
return products.filter(({
sizes: s
}) => (sizes) ? s.some(size => sizes.includes(size)) : true)
// Now color
.filter(({
colors: c
}) => (colors) ? c.some(color => colors.includes(color)) : true)
// style etc.
.filter(({
styles: s
}) => (styles) ? s.some(style => styles.includes(style)) : true)

});

const filter = {
sizes: [“6”, “7”],
colors: [“filter-color-Red”]
};

console.log(getFiltered(p, filter));

Solution 2:

You might find this useful.

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
el: ‘#hook’,
template: ‘#app-template’,
data: () => ({
data: [{
styles: [“filter-style-Low 1”],
colors: [“filter-color-White”],
sizes: [“5”, “6”, “7”, “8”, “9”, “10”, “11”, “12”, “13”]
},
{
styles: [“filter-style-Boot”],
colors: [“filter-color-Black”, “filter-color-Red”, “filter-color-Blue”],
sizes: [“7”, “8”, “9”, “12”, “13”]
},
{
styles: [“filter-style-Gat”],
colors: [“filter-color-Black”, “filter-color-Red”],
sizes: [“7”, “8”, “9”, “10”, “11”, “12”, “13”]
}
],
filters: {
styles: [],
colors: [],
sizes: []
},
additiveFiltering: false
}),
computed: {
products() {
return this.data.map(product => ({
…product,
tags: this.tags(product)
}))
},
filteredProducts() {
return this.products.filter(
this.additiveFiltering
? p => this.x(this.filters.styles, p.styles).length
|| this.x(this.filters.colors, p.colors).length
|| this.x(this.filters.sizes, p.sizes).length
: p => (!this.filters.styles.length
|| this.x(this.filters.styles, p.styles).length)
&& (!this.filters.colors.length
|| this.x(this.filters.colors, p.colors).length)
&& (!this.filters.sizes.length
|| this.x(this.filters.sizes, p.sizes).length)

)
},
allStyles() {
return this.getAll(‘styles’)
},
allColors() {
return this.getAll(‘colors’)
},
allSizes() {
return this.getAll(‘sizes’)
}
},
methods: {
tags(product) {
return [].concat(product.styles, product.colors, product.sizes)
},
logger(obj) {
return JSON.stringify(obj, null, 2)
},
getAll(prop) {
return [ …new Set([].concat.apply([], this.data.map(item => item[prop])))]
},
x(arr1, arr2) {
return arr1.filter(val => arr2.includes(val))
}
}
})
ul>li>span {
background-color: #333;
color: white;
padding: 0 5px 2px;
margin: 0 5px 5px 0;
border-radius: 3px;
font-variant: all-petite-caps;
font-family: monospace;
}
.filters {
display: flex;
}
.filters > div {
flex: 1;
}
.filters > div:last-child {
columns: 2;
}
.filters > div:last-child div{
column-span: all;
}
.filters label {
display: block;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin: 5px;
border: 1px solid transparent;
padding: 1rem;
}
.selected {
background-color: #f5f5f5;
border-color: red;
}
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script type=”text/template” id=”app-template”>
<div id=”app”>
<div class=”filters”>
<div>
<div>Style</div>
<label v-for=”style in allStyles” :key=”style”>
<input type=”checkbox” v-model=”filters[‘styles’]“ :value=”style”>
{style}
</label>
</div>
<div>
<div>Colors</div>
<label v-for=”color in allColors” :key=”color”>
<input type=”checkbox” v-model=”filters[‘colors’]“ :value=”color”>
{color}
</label>
</div>
<div>
<div>Sizes</div>
<label v-for=”size in allSizes” :key=”size”>
<input type=”checkbox” v-model=”filters[‘sizes’]“ :value=”size”>
{size}
</label>
</div>
</div>
Additive filtering: <input type=”checkbox” v-model=”additiveFiltering”>
<h3>Products</h3>
<ul>
<li v-for=”(product, key) in products” :key=”key”
:class=”{selected: filteredProducts.includes(product)}”>
<span v-for=”tag in product.tags” :key=”tag” v-text=”tag”></span>
</li>
</ul>
<pre v-text=”{filters}”></pre>
</div>
</script>
<div id=”hook”></div>

The relevant bit is the x method, which is an array intersection.

[Vue.js] Not displayed correctly in elementUI Cascader Subscribe to RSS

I use elementUI’s cascading selector to display the data, I wrote this code according to the official documentation.

<el-cascader
v-model=”address”
:options=”addressOptions”
:props=”{expandTrigger: ‘hover’}”
\></el-cascader>

data() {
return {
address: ‘’,
addressOptions: [
{
value: ‘Beijing’,
label: ‘Beijing’,
children: this.getOptions(“Beijing”)
},
{
value: ‘Shanghai’,
label: ‘Shanghai’,
children: this.getOptions(“Shanghai”)
}
]
}
}
methods: {
getOptions(val) {
let res = [];
for(let i=1; i<=5; i++) {
let floor = Object.create(null);
floor.value = i;
floor.label = i;
floor.children = [];
for(let j=1; j<=5; j++) {
let obj = Object.create(null);
obj.value = j < 10 ? `0${j}` : `${j}`;
obj.label = j < 10 ? `0${j}` : `${j}`;
floor.children.push(obj);
}
res.push(floor);
}
return res;
}
}

It seems to be correct, but when I select the option, its first and second level data is unchanged. As shown below.

there is been thinking for a long time and still can’t find out why. What surprised me even more is that if my third-level data is stitched with the previous parameters, the results will be displayed normally.

// Can be displayed normally
// obj.value = j < 10 ? `0${j}${val}` : `${j}${val}`;
// obj.label = j < 10 ? `0${j}${val}` : `${j}${val}`;

// This cannot be displayed normally.
obj.value = j < 10 ? `0${j}` : `${j}`;
obj.label = j < 10 ? `0${j}` : `${j}`;

Do you know the reason? Please help me with the questions. Thanks

You can test here: https://jsfiddle.net/DangoSky/7osfp265/1/

Solution :

I think I know what the issue is, when you click on the option with the following hierarchy Shanghai > 3 > 03, the library searches top-down of where 03’s value is be located. The first hierarchy where 03 is located is Beijing > 1 > 03. Hence it shows the wrong label. This seems to be an issue with the library (or this is how they have designed) because when you use the handleChange method and do a console.log, it prints the value correctly.

To get around the issue, you can have the labels you want but the value needs to be unique to all the options. Something like ‘Shanghai+3+03’ can be value so that split and you can recover the original values.

Check out the working fiddle https://jsfiddle.net/n365ecuk/

getOptions(val) {
let res = [];
for(let i=1; i<=5; i++) {
let floor = Object.create(null);
floor.value = val + ‘+’ + i;
floor.label = i;
floor.children = [];
for(let j=1; j<=5; j++) {
let obj = Object.create(null);
// Can be displayed normally
// obj.value = j < 10 ? `0${j}${val}` : `${j}${val}`;
// obj.label = j < 10 ? `0${j}${val}` : `${j}${val}`;
// This cannot be displayed normally.
obj.value = val + ‘+’ + i + ‘+’ + j;
obj.label = j < 10 ? `0${j}` : `${j}`;
floor.children.push(obj);
}
res.push(floor);
}
return res;
}

[Vue.js] How do I display a second array inside my computed property in vue.js Subscribe to RSS

to display a second array inside my computed property, but only if a checkbox is checked. Otherwise the first list should only display.

I’ve managed to get my fist list to work with my code and it displays as it should, I’ve also got a method that makes the list sort alfabetically (that is what I refer to as categories).

How do I merge in the other array if my checkbox value is true?

Here’s some code

data: function() {
return {
checked: false,
fruitList: [ //Fist list
“Apple”,
“Grapes”,
“Mango”,
“Oranges”,
“Banana”,
“Dragon fruit”,
“Pinapple”,
“Coconut”,
“Strawberry”
],
vegetableList:[ //Second list, should only display if checkbox is true
“cucumber”,
“tomato”,
“onion”
]
};
},
methods:{
return{
sorted(list) {
return list.sort();
}
}
},
computed: {
categorizedWords() {
let map = {};
this.fruitList.forEach(word => {
let key = word.charAt(0).toUpperCase();
let list = map[key];
if (list === undefined) {
list = [];
map[key] = this.sortedList(list);
}
list.push(word);
});

var sortedCategories = this.sorted(Object.keys(map));
var sortedMap = sortedCategories.map(category => {
return { category: category, word: map[category] };
});
return sorteradMap;
}
}

Solution :

ok, so I had it allmost and I’ve figured it all out now.
So I changed my code to this and it worked, this is inside my computed property:

computed: {
categorizedWords() {
let map = {};
let isCheched = this.checked;

let allGreens = this.fruitList;

if (isChecked === true) {
allGreens = allGreens.concat(this.vegetableList);
}

allGreens.forEach(word => {
let key = word.charAt(0).toUpperCase();
let list = map[key];
if (list === undefined) {
list = [];
map[key] = this.sortedList(list);
}
list.push(word);
});

var sortedCategories = this.sorted(Object.keys(map));
var sortedMap = sortedCategories.map(category => {
return { category: category, word: map[category] };
});
return sorteradMap;
}
}

[Vue.js] How to get Parent Element from json object using Vue Subscribe to RSS

there is some flattened out json data that when working with and I’m having trouble accessing parts of it, so I’m hoping to use the elements I can access, then get their parent elements for display. I need to get the count of any arrays with multiple values and just display the value if there’s only one, which I can do. Where I’m running into the issue is trying to display the parent(maybe not the best term?) value of the array.

For Example, if this is my json data:

{
“Dogs”: [
{
“Name”: “Gus”,
“Leashes”: {
“564”: [
6
]
}

},
{
“Name”: “Jake”,
“Leashes”: {
“15775”: [
“457”,
“787”,
“278”
]
}
},
]
}

What can I do to access the “564” and “15775” values so I can display them in the left column of a table? I know the data is bad and should be standardized with an ID or something there, but it isn’t, and there’s nothing I can do about that until they fix their transform and get the data corrected. In this example, to get the length or to just display the data I need can use something like this (Please ignore the spans, this data will go in a table):

<template v-for=”Dog in Dogs”>
<template v-for=”Leash in Dog.Leashes”>
<span v-if=”Leash.length <= ‘1’”>{ Leash[0] }</span> (Gives me
the values which is good)
<span v-if=”Leash.length > ‘1’”>{ Leash.length }</span> (Gives
me the count, also good)
</template>
</template>

Where when stuck is trying to get those parent values to display. I’m using a table and need the parent “IDs” for the left column and the values (which I can get) for the right column. Any help would be greatly appreciated. Trying to use a function or a vue.js instance for the data is slightly out of the question at the moment. I saw some complicated examples on how to do this, and I wasn’t able to get them to work. is there something like the following:

<template v-for=”Dog in Dogs”>
<template v-for=”Leash in Dog.Leashes”>
<span>{ Leash.parent }</span>
</template>
</template>

Using { Leash } gives me the arrays.

Any help would be tremendously appreciated here. I’ll have to redo some of this once they actually get the data right, but for now, this is sort of what I’m working with.

Solution :

You need to access keys of the Leash so you need to do this:

<template v-for=”Dog in dogs”>
<template v-for=”(Leash, name, index) in Dog.Leashes”>
<span>{ name } </span>
</template>
</template>

Data:

data() {
return {
dogs: [
{
Name: ‘Gus’,
Leashes: {
564: [
6,
],
},

},
{
Name: ‘Jake’,
Leashes: {
15775: [
457,
787,
278,
],
},
},
],
}
}

I reproduce this code and in my case gives me 564 and 15775. Is that what do you want?

[Vue.js] How can I pass my context variables to a javascript file in Django? Subscribe to RSS

This question must be obvious but I can’t figure it out.

In a template, I link to a js file in my media directory. From that file, I would like to access a context variable like {my_chart}.

But is the syntax different?? Thank you!!

Solution :

I don’t think it’s possible this way. If you want to access some data provided by the view, you have to pass it to the js function.

Example

js file:

my_cool_js_function(some_param){
// do some cool stuff
}

view

// some html code

my_cool_js_function({param})

hope this helps :)

Solution 2:

In addition to Andrzej Bobak’s answer, you can also generate a global variable in Javascript from the template. For example, the template might generate code like this:

<script>
var my_chart = { the_chart };
</script>

the script could then refer to my_chart.

Solution 3:

I would also add because I ran into the error a few times that if the python variable is an object it will throw a syntax error unless you put it in quotes, in other words, within the template,

<script>
var my_var = ‘{ python_object|escapejs }’;
</script>

Furthermore, before putting that object in the context it is best to first serialize it to JSON, or you’ll end up having to do string parsing. I found also that date objects needed to be converted to strings before this step.

import jsonpickle

context[‘python_object’] = jsonpickle.encode(python_object)

And finally, in the JS you can then iterate through the object properly and use the values as you probably would have in python by doing:

var my_var_parsed = jQuery.parseJSON(my_var);

[Vue.js] One Request to index.php pausing other request until finish Subscribe to RSS

I’m creating a single page application using php, where there is separate index.php 3 parts using URI like below,

if(count($uri_segments) < 2) {
// print the template, if no URI found.
}else {
switch($route) {
case ‘start’:
// a CURL request via ajax from frontend, curl request taking 30s to complete even more.
break;
case ‘status’ :
// other ajax call to display status
break;
default: break;
}
}

Now I did async call to /start and /status normal like below

async function() {
await axios.get(‘./index.php/start’).then((res) => {
console.log(res);
});
}
axios.get(‘./index.php/status’).then((res)=> {
console.log(res);
});

But /start call blocking /status as you can see the below image.

Img url: https://www.screencast.com/t/EXjyL8fYCl2q

there is to use only index.php page to build, any suggestions to solve it. Thanks in advance.

Solution :

If you want to call endpoint one after another you can do like below.

function() {
axios.get(‘./index.php/start’).then((res) => {
axios.get(‘./index.php/status’).then((res)=> {
console.log(res);
});
});
}

As you mentioned above you want to get status once start request is completed.

[Vue.js] Props change parent if object Vue js Subscribe to RSS

My question it’s more a search for explanation.

there is two components, father and child.

Father:

<template>
<Child :data=”testData” />
{testData} //for print data in father
</template>

<script>
export default {
name: “Father”,
data() {
return {
testData: {name: “hello”}
}
}
}
</script>

And then My Child

<template>
<input v-model=”data.name” />
</template>
<script>
export default {
name: “Child”,
props: [“data”]
}
}
</script>

As documentation say in this section:
https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

I expected that it will return error, but no, it’s work, if I try to change input the father component show the correct new value, without console error.

So there is tested with simple string for data instead of object in father like:

Father :

<template>
<Child :data=”testData” />
{testData} //for print data in father
</template>

<script>
export default {
name: “Father”,
data() {
return {
testData: “hello”
}
}
}
</script>

Child :

<template>
<input v-model=”data” />
</template>
<script>
export default {
name: “Child”,
props: [“data”]
}
}
</script>

And in this case I will get the correct error:

[vue.js warn]: Avoid mutating a prop directly since the value will be
overwritten whenever the parent component re-renders. Instead, use a
data or computed property based on the prop’s value. Prop being
mutated: “data”

found in

Yes I know that in JS the object are different and “magic”, but I expected that Vuejs not allowed this.

Is this desired/due(for JS specifics) behavior?

Thankyou.

Solution :

In both exemples, the prop value is an object, or a link to an object (and its attributes/properties).

When you use v-model=”data.name”, you are not changing the prop, you are following the link, accessing the object, and only changing one of its attributes.
Can’t say if this is bad practice, but it works great for me.

In the second exemple, the v-model=”data” would actually change the link to another object, not only the prop internals.
This results in an error.

This thread can also help: https://forum.vuejs.org/t/pass-object-via-props-reference-vs-emit-value-best-practices/45683/5

[Vue.js] Scoping of HTML element id in Vue component Subscribe to RSS

Is there some built-in scoping mechanism for vue.js component in the sense that value of id attribute of html element inside vue.js component be uniquely defined without programmer’s efforts to do it?

In the following code, I create two components and hope each behaves independently to each other. So, ideally if I click on each button, each is required to print out “foo” but actually not because value of ids are duplicated.

<!DOCTYPE html>

<head>
<title></title>
</head>

<body>
<div id=”app”>
<my-comp></my-comp>
<my-comp></my-comp>
</div>
<script src=”https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src=”https://unpkg.com/vue"></script>
<script>
Vue.component(‘my-comp’, {
template: `
<div>
<button id=”btn” @click=”onClick”>Click me</button>
<div id=”pid”></div>
</div>
`,
methods: {
onClick(e) {
$(‘#pid’).text(“foo”);
}
},
});

const vm = new Vue({
el: ‘#app’,
data: () => ({}),
methods: {}
});
</script>
</body>

</html>

Solution :

It looks like the vue-uniq-ids package is what you’re looking for.

It is a trend to use components. Components are cool, they are small,
obvious, easy to use and modular. Untill it comes to the id property.

Some HTML tag attributes requires using an id property, like
label[for], input[form] and many of aria-* attributes. And the problem
with the id is that it is not modular. If several id properties on the
page will has the same value they can affect each other.

VueUniqIds helps you to get rid of this problem. It provides the set
of id-related directives which value is automatically modified by
adding unique string while keeping the attrbitue easy to read.

Solution 2:

Don’t use id in vue.js components unless you are passing a unique value for it using props. You should very rarely ever actually need to get a reference to an element in vue.js and if you do find you need to then you should be using refs.

In the case you can just use a property and template binding to handle things for you:

Vue.component(‘my-comp’, {
template: `
<div>
<button @click=”onClick”>Click me</button>
<div>{ text }</div>
</div>
`,
data() {
text: ‘’
},
methods: {
onClick(e) {
this.text = ‘foo’
},
},
})

[Vue.js] Loop using v-for in vuejs? Subscribe to RSS

when trying to use v-for to loop through data which included title and icons. Right now I can get only one icon by looping through, My question is how can I get more than one icon when looping through?

there is made a codepen: https://codepen.io/anon/pen/MMaGOZ?&editable=true&editors=101. So basically in this example how can I get more than one icon. So if I also want a search icon alongside dashboard.

<div id=”app”>
<v-app id=”inspire”>
<v-navigation-drawer
class=”blue lighten-3”
dark
permanent
\>
<v-list>
<v-list-tile
v-for=”item in items”
:key=”item.title”
@click=””
\>
<v-list-tile-action>
<v-icon>{ item.icon }</v-icon>
</v-list-tile-action>

<v-list-tile-content>
<v-list-tile-title>{ item.title }</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>

new Vue({
el: ‘#app’,
data () {
return {
items: [
{ title: ‘Dashboard’, icon: ‘dashboard’,’search’ },
{ title: ‘Account’, icon: ‘account_box’ },
{ title: ‘Admin’, icon: ‘gavel’ }
]
}
}
})

If I do icon: ‘dashboard’, ‘search’ => This gives me an error message. Not sure how can I get this?

Thanks in advance.

Solution :

As mentioned in the comments, { icon: ‘dashboard’, ‘search’ } is invalid and you’ll want to use an array (or similar list / collection), eg

items: [
{ title: ‘Dashboard’, icon: [‘dashboard’,’search’] },
{ title: ‘Account’, icon: [‘account_box’] },
{ title: ‘Admin’, icon: [‘gavel’] }
]

Note that I’ve made all icon properties into array, even if they only have one icon. This is to make everything consistent and easy to work with.

Then in the template, you can iterate the icons in another v-for

<v-list-tile-action>
<v-icon v-for=”icon in item.icon” :key=”icon”>{ icon }</v-icon>
</v-list-tile-action>