VueJS agrega condicionalmente un atributo para un elemento

119

En VueJS podemos agregar o eliminar un elemento DOM usando v-if:

<button v-if="isRequired">Important Button</button>

pero, ¿hay alguna manera de agregar / eliminar atributos de un elemento dom? Por ejemplo, para lo siguiente, establezca condicionalmente el atributo requerido:

Username: <input type="text" name="username" required>

por algo similar a:

Username: <input type="text" name="username" v-if="name.required" required>

¿Algunas ideas?

Don Smythe
fuente
4
Si bien no es tan obvio (de ahí la confusión), la documentación en realidad dice que si el valor del atributo se evalúa como falso, el atributo se omite ( vuejs.org/v2/guide/syntax.html#Attributes )
AlexanderB
En realidad, la documentación dice que no se añadirá el atributo si “... tiene el valor de null, undefinedo false , que es diferente de un script JS evaluar a falso. Esto significa que una cadena vacía es falsa en JavaScript, pero aún agregaría el atributo a DOM. Para evitar que puedas intentarlov-bind:name="name || false"
Denilson Sá Maia
@AlexanderB Si eso es cierto, ¿cómo puedo pasar explícito falseal componente secundario a través de un accesorio?
Bruce Sun
@BruceSun, si el atributo en el contexto "involuntariamente" desaparece cuando le da un valor falso, intente pasarlo como una cadena 'false'. En otros casos, cuando necesite controlar la presencia de un atributo html no booleano en el elemento, puede usar la representación condicional v-ifcomo se sugiere aquí: github.com/vuejs/vue/issues/7552#issuecomment-361395234
AlexanderB
@AlexanderB Creo que tengo que corregirme, debería decir, attributepero NO prop. Podemos pasar de forma segura explícitamente a falsetravés de una propiedad de componente pero NO de un atributo (que no se reconoce como una propiedad). ¿Estoy en lo correcto?
Bruce Sun

Respuestas:

127

Tratar:

<input :required="test ? true : false">
Cymruu
fuente
9
La forma larga es<input v-bind:required="test ? true : false">
nathanielobrown
8
anythingAtAll : ? true : false(o if (condition) { return true; } else { return false; }) en cualquier idioma es ... indecoroso . Simplemente use return (condition)o, en este caso,<input :required="test">
Stephen P
5
si está seguro de que la variable testes boolean, puede usar:required="test"
strz
2
¡Tenga en cuenta que esto depende del componente! Es posible que si su propiedad acepta un Stringvalor, al configurarlo false, obtenga un type checkerror. Así que configúrelo en undefinedlugar de falso. docs
Traxo
usar :required="required"where requiredes una propiedad de componente booleana da como resultado <el required = "required"> para mí
Andrew Castellano
65

La forma mas simple:

<input :required="test">   // if true
<input :required="!test">  // if false
<input :required="!!test"> // test ? true : false
Syed
fuente
1
¡Tenga en cuenta que esto depende del componente! Es posible que si su propiedad acepta un Stringvalor, al configurarlo false, obtenga un type checkerror. Así que configúrelo en undefinedlugar de falso. docs
Traxo
@Sé tu respuesta usando signos de exclamación dobles !! Nunca había visto esa sintaxis antes de ayer y durante una revisión de código me encontré con esto: - <input :required="!!!recipe.checked" v-model="recipe.pieType"><select :required="!!!recipe.checked" v-model="recipe.ingredients" :options="ingredients"></select> ¿Sabes qué !!!significa (3) para un :requiredvalor? Gracias.
Chris22
2
@ Chris22 No hay diferencia entre! Test y !!! test, ya que !!! test es solo !! (! Test) y porque! Test es un booleano, !! (! Test) es solo su doble negación, por lo tanto el mismo. Compruebe esto: stackoverflow.com/a/25318045/1292050
Syed
@Syed gracias. Siguiendo su enlace, encontré este también y estoy de acuerdo . : ^)
Chris22
Lo que dijo @Syed no es falso
goodson
16

<input :required="condition">

No es necesario <input :required="test ? true : false">porque si la prueba es verdadera , ya obtendrá el requiredatributo, y si la prueba es falsa , no obtendrá el atributo. La true : falseparte es redundante, muy parecida a esta ...

if (condition) {
    return true;
} else {
    return false;
}
// or this...
return condition ? true : false;
// can *always* be replaced by...
return (condition); // parentheses generally not needed

La forma más sencilla de hacer este enlace, entonces, es <input :required="condition">

Solo si la prueba (o condición ) puede malinterpretarse, necesitaría hacer otra cosa; en ese caso, el uso de Syed !!hace el truco.
  <input :required="!!condition">

Stephen P
fuente
11

Puede pasar booleanforzándolo, ponerlo !!antes de la variable.

let isRequired = '' || null || undefined
<input :required="!!isRequired"> // it will coerce value to respective boolean 

Pero me gustaría llamar su atención sobre el siguiente caso en el que el componente receptor se ha definido typepara accesorios. En ese caso, si isRequiredha definido el tipo para stringpasar, booleanhaga que la verificación de tipo falle y obtendrá una advertencia de Vue. Para solucionarlo, es posible que desee evitar pasar ese accesorio, así que simplemente coloque el undefinedrespaldo y el accesorio no se enviará acomponent

let isValue = false
<any-component
  :my-prop="isValue ? 'Hey I am when the value exist' : undefined"
/>

Explicación

¡He pasado por el mismo problema y he probado las soluciones anteriores! Sí, no veo el proppero eso en realidad no cumple con lo requerido aquí.

Mi problema -

let isValid = false
<any-component
  :my-prop="isValue ? 'Hey I am when the value exist': false"
/>

En el caso anterior, lo que esperaba es que no se haya my-proppasado al componente secundario; <any-conponent/>no veo el propin, DOMpero en mi <any-component/>componente, aparece un error del error de verificación del tipo de prop. Como en el componente hijo, espero my-propser un Stringpero lo es boolean.

myProp : {
 type: String,
 required: false,
 default: ''
}

Lo que significa que el componente hijo recibió el accesorio incluso si lo es false. El ajuste aquí es permitir que el componente secundario tome default-valueel control y también se salte la verificación. ¡ undefinedTrabajos aprobados !

<any-component
  :my-prop="isValue ? 'Hey I am when the value exist' : undefined"
/>
 

Esto funciona y mi accesorio infantil tiene el valor predeterminado.

Satyam Pathak
fuente
2

En uso html

<input :required="condition" />

Y definir en propiedad de datos como

data () {
   return {
      condition: false
   }
}
Nipun Jain
fuente