I’m trying to use a function in a v-if directive like that in a vue template
<template>
<ul class="list-group">
<li class="list-group-item list-group-item-info">
<div class="row">
<div v-for="col in colss" class="" :class="bootstrapClass">{{col | capitalize}}</div>
</div>
</li>
<li v-for="item in datas[collectionsindatas['reference']]" class="list-group-item">
<div class="row">
<div v-for="property in columns.slice(0,(columns.length))" class="" :class="bootstrapClass">{{ item[property] }}</div>
<div v-if="compareCollections(item[comparecol],datas[collectionsindatas['compare'][comparecol]])" class="" :class="bootstrapClass">
OK
</div>
<div v-else class="" :class="bootstrapClass">!!NOK!!</div>
</div>
</li>
</ul>
</template>
and my methods are like that :
methods:{
compareCollections:function(reference,compare){
if(compare!='undefined' && compare!=''){
if(compare===reference){
return true;
}
return false;
}
return false;
},
}
It fails with this message : [Vue warn]: Property or method is not defined on the instance but referenced during render
It fells myself better to use a method instead writing many things ugly in the v-if directive like
v-if="datas[collectionsindatas['compare'][comparecol]]!='undefined'&&(item[comparecol]===datas[collectionsindatas['compare'][comparecol]])"
what is the right way to do this ?
Thanks for your help
You can pass an arbitrary JavaScript expression to the v-if directive in Vue, including a complex boolean expression which contains operators || or && . You can test this on your own.
v-else-if directive is a Vue. js directive used to toggle the display CSS property of an element depending on a condition when the if condition is not satisfied. First, we will create a div element with id as app and let's apply the v-else-if directive to an element with data.
The v-if directive is used to conditionally render a block meaning the block with the v-if attribute will only be produced if the directive's expression returns a true value. If the expression produces an invalid result (for example, null , 0 , empty string, false ), the element is deleted from the DOM.
The v-show directive is a Vue. js directive used to toggle the display CSS property of a element with our data via inline styles. If the data is true it will make it visible else it will make it invisible.
In order to get rid of this comparison in your v-if
I'd use a component with your parameters. In the component you can calculate the values and provide them using computed
. You won't have to pass any parameters to computed
because they will already be the parameters of the component:
<template>
<div>
<div v-if="compEqRef" class="" :class="bootstrapClass">
OK
</div>
<div v-else class="" :class="bootstrapClass">!!NOK!!</div>
</div>
</template>
<script>
export default {
methods: {
compareCollections(reference, compare) {
return (compare !== 'undefined' && compare !== '' && compare === reference);
}
},
computed: {
compEqRef() {
const left = this.item[this.comparecol];
const right = this.datas[this.collectionsindatas['compare'][this.comparecol]];
return this.compareCollections(left, right);
}
},
props: {
item: {
required: true
},
datas: {
required: true
},
comparecol: {
required: true
},
collectionsindatas: {
required: true
}
}
}
</script>
OK, it could be improved but here is my way to resolve this :
My list component receive by props a reference list of avalaible permissions and receive a comparing list to the role's permission so when the comparing returns true it will display a toggle switch wich appear set on ON position and OFF if it's false. So here is the app.js :
Vue.component('sort-table', sortTable);
Vue.component('list-items', listItems);
var csrf_token = $('meta[name="csrf-token"]').attr('content');
var newTable = new Vue({
el: '#appTableRoles',
data: {
columns: ['id', 'name', 'description', 'action'],
cols: ['Id', 'Rôle', 'Description', 'Actions'],
// ajax url
url: 'Role/ajaxQuery',
},
components: {sortTable},
});
var listTable = new Vue({
el: '#listmodal',
data: {
// collection des propriétés
columns: ['id', 'name', 'description'],
// collection d'affichage
colss: ['Id', 'Nom', 'Description', 'Attribution'],
urlajax:'',
datas:[],
//
collectionsInDatas:{'reference':'allPermissions','compare':'rolePermissions'},
// critère de comparaison entre la collection de référence et la collection appartenant à l'item
comparecol:'name',
//objet contenant tous les résultats de comparaisons
lastcol:{equal:[],display:[]},
},
methods: {
showModal () {
$('#permissionsModal').modal('show');
},
hideModal () {
$('#permissionsModal').modal('hide');
},
getDatas(){
this.lastcol.equal =[];
this.lastcol.display =[];
MonThis = this;
$.ajax({
url: this.urlajax,
cache: false,
dataType: 'json',
success: function (data, textStatus, jqXHR) {
if (jqXHR.status === 200) {
//console.log(data);
MonThis.datas = data;
var index=0;
//console.log(MonThis.datas[MonThis.collectionsInDatas['reference']]);
for(item in MonThis.datas[MonThis.collectionsInDatas['reference']]){
//var index = MonThis.datas[MonThis.collectionsInDatas['reference']].indexOf(item);
//console.log('index : '+index);
console.log('reference name : '+MonThis.datas[MonThis.collectionsInDatas['reference']][index]['name']);
//console.log('compare : '+MonThis.datas[MonThis.collectionsInDatas['compare']][index]);
var j = 0;
for(compare in MonThis.datas[MonThis.collectionsInDatas['compare']]){
//console.log('compare name : '+MonThis.datas[MonThis.collectionsInDatas['compare']][j]['name']);
if(MonThis.datas[MonThis.collectionsInDatas['compare']][j]['name']===MonThis.datas[MonThis.collectionsInDatas['reference']][index]['name']){
MonThis.lastcol.equal.push(true);
MonThis.lastcol.display.push('OK');
break;
}else{
MonThis.lastcol.equal.push(false);
MonThis.lastcol.display.push('Not OK');
}
j++;
}
index++;
}
}
}
});
},
},
components:{listItems},
});
$(document).ready(function () {
$(document).on('click', '.modal-permissions', function (e) {
//console.log($(e.target).attr('href'));
listTable.showModal();
listTable.$data.urlajax = $(e.target).attr('href');
listTable.getDatas();
});
});
Here is the component call in the blade template :
<list-items :colss="colss":columns="columns"
:urlajax="urlajax"
:datas="datas"
:lastcol="lastcol"
:collectiondatas="collectionsInDatas">
</list-items>
and Here is the vue file code :
<template>
<ul class="list-group">
<li class="list-group-item list-group-item-info">
<div class="row">
<div v-for="col in colss" class="" :class="bootstrapClass">{{col | capitalize}}</div>
</div>
</li>
<li v-for="(item,index ) in datas[collectiondatas['reference']]" class="list-group-item">
<div class="row">
<div v-for="property in columns.slice(0,(columns.length))" class="" :class="bootstrapClass">{{
item[property] }}</div>
<div class="" :class="bootstrapClass">{{ lastcol.display[index] }}</div>
</div>
</li>
</ul>
</template>
<script>
var csrf_token = $('meta[name="csrf-token"]').attr('content');
export default {
name: 'listItems',
data(){
return {
}
},
props: ['colss','columns','lastcol','urlajax','datas','collectiondatas'],
methods: {
},
computed: {
bootstrapClass: function() {
return 'col-sm-' + (12 / this.colss.length );
},
},
mounted: function () {
},
filters: {
capitalize: function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
},
}
</script>
If your method returns a boolean you can use
v-if="!!compareCollections(params)"
simple and clean
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With