Vue.js2 style binding not working - vuejs2

I'm pass a collection, rows, as an array of objects.
Inside the v-for:
<th class="line-checkboxes" #click="row.checked = !row.checked" >
<div :class="{'line-checked' : row.checked }">
<i class="line-checkboxes-icon"></i>
</div>
</th
However, the class property is no reactive.
What could be the reason for it?

Related

Vue Component that Can Override What Child Renders Dynamically

I am working on a component (InfoCard) that should be able to render any number of fields passed into it with a 'fields' prop, as an array of json objects with a name, value, and some styling options. For certain fields, I want to be able to override what component is used to render, but do it from the parent (Table) rather than inside the InfoCard component, as it should be generic. My first thought was to use a <component :is='field.component'></component>, where it will render as plaintext if field.component is not defined, but to my understand it will be difficult to pass in any potential children necessary for the <component/>. My second thought is to use named slots from within the parent, but I don't think this is possible either in a good way. I'll show my current code.
In my example, I want to be able to detect if the field being rendered is 'status', and if it is, use a different rendering mechanism than displayValue(attribute), without hardcoding it inside InfoCard; I want the parent to be able to override this rendering conditionally. Is there a way to do this in Vue? Thanks
From Table, where data.records is an array of JSON objects:
<info-card
v-for="(record,index) in data.records"
:key="index"
:fields="record"
>
<div v-for="key in Object.keys(record)" :key="key">
<template v-if="field.name=='status'" v-slot:[`${field.name}_value`]>
<p> Field is status !</p>
</template>
</div>
</info-card>
From InfoCard:
<template>
<el-col
:lg="3"
:md="3"
:sm="3"
:xs="3"
v-for="(attribute, index) in fields"
:key="index"
class="attribute"
>
<div
#click="$emit('fieldClicked', attribute)"
>
<el-row
:class="`mid-gray f6 clipped fw5-ns m-b-10 ${attribute.nameClasses}`"
:title="displayName(attribute)"
:style="attribute.nameStyle?attribute.nameStyle:''"
>
<slot
v-if="Object.keys($scopedSlots).includes(`${attribute.name}_name`)"
:name="$scopedSlots[`${attribute.name}_name`]"
>
</slot>
<div v-else>
{{ displayName(attribute) }}
</div>
</el-row>
<el-row
:class="`mid-gray f6 clipped fw5-ns m-b-10 ${attribute.valueClasses}`"
:title="displayValue(attribute)"
:style="attribute.valueStyle?attribute.valueStyle:''"
>
<slot
v-if="Object.keys($scopedSlots).includes(`${attribute.name}_value`)"
:name="$scopedSlots[`${attribute.name}_value`]"
>
</slot>
<div v-else>
{{ displayValue(attribute) }}
</div>
</el-row>
</div>
</el-col>
</template>

Vue refs undefined in modal

I do have a for loop and inside i want to have a modal for each image
<div class="col pb-3" v-for="(item, index ) in img" :key="index" style="width: 300px;height:auto;">
<img v-b-modal="'modal-'+index" :ref="'image'" #mouseover="mouseOver" #mouseleave="mouseOut" /><br>
<b-modal :id="'modal-'+index" title="BootstrapVue">
<p class="my-4">Hello from modal - {{index}}</p>
<img :ref="'imagex'" />
</b-modal>
<div class="progress pt-2 mt-1" style="width: 100px;margin: 0 auto;">
<div class="progress-bar " :style="[{'width':width[index]+'px'}]" role="progressbar"
aria-valuenow="0" ref="'progress'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
In methods i am giving src value to each image that has :ref="'image'" and i can actually give a src to them its work fine but, i also want be able to give src value images in modal. Its called :ref="'imagex'" but its undefined.
this.$refs.image[i].src = event.target.result //works
this.$refs.imagex[i].src = event.target.result //undefined
What is the problem an is there anyway to solve it ?
When used on elements/components with v-for, the registered reference will be an Array containing DOM nodes or component instances.
An important note about the ref registration timing: because the refs themselves are created as a result of the render function, you cannot access them on the initial render - they don’t exist yet! $refs is also non-reactive, therefore you should not attempt to use it in templates for data-binding.
.
can use it in events and only at mounted function.
https://v2.vuejs.org/v2/api/#ref

How to update an ancestral element class in response to child input change with Vue.js?

I'm using Vue (v2.6.11) and I want to add/remove a class on an ancestor (grandparent) element of an input (checkbox) when it's value is changed. There are an unknown number of checkboxes so they are generated using v-for on the element that I want to add/remove the class. I have a function registered with my Vue instance methods when the checkbox value is changed.
In my code below, the <label> is the element to which I want to add/remove the class in response to the checkbox value changing. I'm trying to resist the urge to apply an :id attribute to the label and then do a lookup in my updateCounter method that will use the id of the checkbox to find the label and add/remove the class using pure JS. Is there a more Vue-esque way to do this?
<label class="item"
v-for="item in myItems"
v-bind:key="item.id"
:for="'item'+item.id">
<div>
<input type="checkbox"
:id="'item'+item.id"
v-model="item.isAccepted"
#change="updateCounter($event)" />
<span>{{ item.name }}</span>
<span>{{ item.status }}</span>
</div>
<div>{{ item.date }}</div>
</label>
just use a dynamic class like so: :class="item.applyClass ? 'item' : ' ' " so put a property on the item and then you can dynamically change that in your updatedCounter function
You can do
<label class="item"
v-for="item in myItems"
v-bind:key="item.id"
:for="'item'+item.id"
:class="{test: item.isAccepted === true}">
<div>
<input type="checkbox"
:id="'item'+item.id"
v-model="item.isAccepted"
#change="updateCounter($event)" />
<span>{{ item.name }}</span>
<span>{{ item.status }}</span>
</div>
<div>{{ item.date }}</div>
This would apply test class only when is Accepted is true for that particular checkbox.

VueJS: read div content from its id

In my first example, I have in my component's template:
<div id="hello">hello world</div>
When console.log(this.$refs['hello']) is called in myMethod(), I get undefined in the console.
In my second example, I have:
<div v-for="item in data">
<div :id="'hello-'+item.id">hello {{ item.id }}</div>
</div>
When console.log(this.$refs['hello-1']) is called in myMethod(), I also get undefined in the console.
What's wrong in my code ?
You cannot get element with refs by giving that element id. You should bind ref to that element. Here is an example:
<div v-for="item in data" :key="item.id">
<div :id="'hello-'+item.id" :ref="'hello-'+item.id">hello {{ item.id }}</div>
</div>
And also don't forget to bind key to your iterating elements with v-for

In Aurelia, can a slot be used in a repeat.for binding?

I'd like to create a custom element that loops through an array and applies the to each item in the array. For example, the view template of the custom element would contain something like:
<div repeat.for="i of items">
<div with.bind="i">
<slot></slot>
</div>
</div>
When I remove the repeat.for and with.bind attributes, the slot displays a single time. Is there a way to make it repeat for each item in the list?
No, you cannot use slots with repeat.for or bind today. To do this you have to use replaceable parts. For example:
<div repeat.for="i of items">
<div with.bind="i">
<template replaceable part="content"></template>
</div>
</div>
Usage:
<my-component>
<template replace-part="content">Some Content - ${somePropertyOfI}</template>
</my-component>
Runnable example: https://gist.run/?id=29aa1c1199f080c9ba0e72845044799b