VueJS adiciona condicionalmente um atributo para um elemento

119

No VueJS, podemos adicionar ou remover um elemento DOM usando v-if:

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

mas existe uma maneira de adicionar / remover atributos de um elemento dom, por exemplo, para o seguinte definir condicionalmente o atributo obrigatório:

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

por algo semelhante a:

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

Alguma ideia?

Don Smythe
fonte
4
Embora não seja tão óbvio (daí a confusão), a documentação realmente diz que se o valor do atributo for avaliado como falso, então o atributo será omitido ( vuejs.org/v2/guide/syntax.html#Attributes )
AlexanderB
Na verdade, a documentação diz o atributo não será adicionado se “... tem o valor de null, undefinedou false , que é diferente de um script JS avaliar como false. Isso significa que uma string vazia é falsa em JavaScript, mas ainda adicionaria o atributo ao DOM. Para evitar isso você pode tentarv-bind:name="name || false"
Denilson Sá Maia
@AlexanderB Se isso for verdade, como posso passar explícito falseao componente filho por meio de um prop?
Bruce Dom
@BruceSun, Se o atributo no contexto "não intencionalmente" desaparecer quando você atribuir a ele um valor falso - tente passá-lo como uma string 'false'. Em outros casos, quando você precisa controlar a presença de atributo html não booleano no elemento, você pode usar a renderização condicional v-ifcomo sugerido aqui: github.com/vuejs/vue/issues/7552#issuecomment-361395234
AlexanderB
@AlexanderB Acho que tenho que me corrigir - devo dizer, attributemas NÃO prop. Podemos passar com segurança explícito falsepor meio de uma propriedade de componente, mas NÃO de um atributo (que não é reconhecido como uma propriedade). Estou correcto?
Bruce Dom

Respostas:

127

Experimentar:

<input :required="test ? true : false">
Cymruu
fonte
9
O formato longo é<input v-bind:required="test ? true : false">
nathanielobrown
8
anythingAtAll : ? true : false(ou if (condition) { return true; } else { return false; }) em qualquer idioma é ... impróprio . Basta usar return (condition)ou, neste caso,<input :required="test">
Stephen P
5
se tiver certeza de que a variável testé boolean, você pode usar:required="test"
strz
2
Observe que isso depende do componente! É possível que, se sua propriedade aceitar Stringvalor, ao defini-la como falsevocê receberá um type checkerro. Portanto, defina-o como em undefinedvez de falso. docs
Traxo
usar :required="required"where requiredis uma propriedade de componente Boolean resulta em <el required = "required"> para mim
Andrew Castellano
65

Forma mais simples:

<input :required="test">   // if true
<input :required="!test">  // if false
<input :required="!!test"> // test ? true : false
Syed
fonte
1
Observe que isso depende do componente! É possível que, se sua propriedade aceitar Stringvalor, ao defini-la como falsevocê receberá um type checkerro. Portanto, defina-o como em undefinedvez de falso. docs
Traxo
@Disse sua resposta usando pontos de exclamação duplos !! Nunca vi essa sintaxe antes de ontem e durante uma revisão de código me deparei com o seguinte: - <input :required="!!!recipe.checked" v-model="recipe.pieType"><select :required="!!!recipe.checked" v-model="recipe.ingredients" :options="ingredients"></select> Você saberia o que !!!(3) significa para um :requiredvalor? Obrigado.
Chris22
2
@ Chris22 Não há diferença entre! Teste e !!! teste, já que !!! teste é apenas !! (! Teste) e porque! Teste é um booleano, !! (! Teste) é apenas sua dupla negação, portanto, mesmo. Verifique isto: stackoverflow.com/a/25318045/1292050
Syed de
@Syed thanks. Seguindo seu link, encontrei este também e concordo . : ^)
Chris22
O que @Syed disse não é falso
goodson
16

<input :required="condition">

Você não precisa <input :required="test ? true : false">porque se teste for verdadeiro, você já obterá o requiredatributo, e se teste for falso, você não obterá o atributo. A true : falseparte é redundante, bem assim ...

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

A maneira mais simples de fazer essa ligação, então, é <input :required="condition">

Somente se o teste (ou condição ) puder ser mal interpretado, você precisará fazer outra coisa; nesse caso, o uso de Syed resolve !!o problema.
  <input :required="!!condition">

Stephen P
fonte
11

Você pode passar booleanpor coagir, colocar !!antes da variável.

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

Mas eu gostaria de chamar sua atenção para o seguinte caso em que o componente receptor foi definido typepara adereços. Nesse caso, se isRequiredtiver definido o tipo como sendo stringaprovado boolean, a verificação do tipo de make falha e você receberá o aviso Vue. Para consertar isso, você pode evitar passar pelo suporte, então apenas coloque undefinedfallback e o suporte não será enviado paracomponent

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

Explicação

Eu já passei pelo mesmo problema e tentei as soluções acima !! Sim, não vejo o, propmas isso realmente não cumpre o que é exigido aqui.

Meu problema -

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

No caso acima, o que eu esperava é não ter sido my-proppassado para o componente filho - <any-conponent/>não vejo a entrada prop, DOMmas no meu <any-component/>componente, surge um erro de falha na verificação do tipo de prop. Como no componente filho, espero my-propser um, Stringmas é boolean.

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

O que significa que esse componente filho recebeu o prop, mesmo que seja false. O ajuste aqui é permitir que o componente filho receba o default-valuee também ignore a verificação. undefinedObras aprovadas embora!

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

Isso funciona e meu objeto filho está tendo o valor padrão.

Satyam Pathak
fonte
2

Em uso html

<input :required="condition" />

E definir na propriedade de dados como

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