VueJS warunkowo dodaje atrybut do elementu

119

W VueJS możemy dodać lub usunąć element DOM za pomocą v-if:

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

ale czy istnieje sposób na dodanie / usunięcie atrybutów elementu dom, np. dla następującego warunkowego ustawienia wymaganego atrybutu:

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

przez coś podobnego do:

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

Jakieś pomysły?

Don Smythe
źródło
4
Chociaż nie jest to takie oczywiste (stąd zamieszanie), dokumentacja faktycznie mówi, że jeśli wartość atrybutu szacuje się na fałsz, to atrybut jest pomijany ( vuejs.org/v2/guide/syntax.html#Attributes )
AlexanderB,
Faktycznie, dokumentacja mówi, że atrybut nie zostanie dodana jeżeli „... ma wartość null, undefinedlub false , który różni się od skryptu JS oceniającego false. Oznacza to, że pusty łańcuch jest fałszywy w JavaScript, ale nadal dodawałby atrybut do DOM. Aby temu zapobiec, możesz spróbowaćv-bind:name="name || false"
Denilson Sá Maia
@AlexanderB Jeśli to prawda, w jaki sposób mogę przekazać jawnie falsekomponent podrzędny za pomocą właściwości?
Bruce Sun
@BruceSun, Jeśli atrybut w kontekście "nieumyślnie" znika, gdy nadasz mu wartość false - spróbuj przekazać go jako ciąg 'false'. W innych przypadkach, gdy chcesz kontrolować obecność atrybutu html niebędącego wartością boolowską w elemencie, możesz użyć renderowania warunkowego v-ifzgodnie z sugestią tutaj: github.com/vuejs/vue/issues/7552#issuecomment-361395234
AlexanderB
@AlexanderB Myślę, że muszę się poprawić - powinienem powiedzieć, attributeale NIE prop. Możemy bezpiecznie przekazać jawnie falsepoprzez właściwość komponentu, ale NIE atrybut (który nie jest rozpoznawany jako właściwość). Mam rację?
Bruce Sun

Odpowiedzi:

128

Próbować:

<input :required="test ? true : false">
cymruu
źródło
9
Długa forma to<input v-bind:required="test ? true : false">
nathanielobrown
8
anythingAtAll : ? true : false(lub if (condition) { return true; } else { return false; }) w jakimkolwiek języku jest ... niestosowne . Po prostu użyj return (condition)lub, w tym przypadku,<input :required="test">
Stephen P
5
jeśli jesteś pewien, że zmienna testjest boolean, możesz po prostu użyć:required="test"
strz
2
Należy pamiętać, że zależy to od elementu! Możliwe, że jeśli twoja właściwość akceptuje Stringwartość, to ustawiając ją na falseciebie, wystąpi type checkbłąd. Więc ustaw go na undefinedzamiast false. dokumenty
Traxo
użycie :required="required"gdzie requiredjest właściwością komponentu logicznego skutkuje <el required = "required"> dla mnie
Andrew Castellano,
65

Najprostsza forma:

<input :required="test">   // if true
<input :required="!test">  // if false
<input :required="!!test"> // test ? true : false
Syed
źródło
1
Należy pamiętać, że zależy to od elementu! Możliwe, że jeśli twoja właściwość akceptuje Stringwartość, to ustawiając ją na falseciebie, wystąpi type checkbłąd. Więc ustaw go na undefinedzamiast false. dokumenty
Traxo
@ Sprawdziłem twoją odpowiedź za pomocą podwójnych wykrzykników. !! Nigdy wcześniej nie widziałem tej składni, a podczas przeglądu kodu natknąłem się na to: - <input :required="!!!recipe.checked" v-model="recipe.pieType"><select :required="!!!recipe.checked" v-model="recipe.ingredients" :options="ingredients"></select> Czy wiesz, co !!!(3) oznacza dla :requiredwartości? Dzięki.
Chris 22
2
@ Chris22 Nie ma różnicy między! Test i !!! test, ponieważ !!! test to po prostu !! (! Test), a ponieważ! Test jest wartością logiczną, !! (! Test) jest po prostu jego podwójną negacją, dlatego podobnie. Sprawdź to: stackoverflow.com/a/25318045/1292050
Syed
@Syed thanks. Podążając za twoim linkiem, znalazłem również ten i zgadzam się . : ^)
Chris22
To, co powiedział @Syed, nie jest nieprawdą
goodson
16

<input :required="condition">

Nie potrzebujesz, <input :required="test ? true : false">ponieważ jeśli test jest prawdziwy , otrzymasz już requiredatrybut, a jeśli test jest fałszywy , nie otrzymasz atrybutu. true : falseCzęść jest zbędna, podobnie jak to ...

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

Najprostszym sposobem wykonania tego wiązania jest więc <input :required="condition">

Tylko jeśli test (lub warunek ) może zostać źle zinterpretowany, musisz zrobić coś innego; w takim przypadku użycie przez Syeda załatwia sprawę !!.
  <input :required="!!condition">

Stephen P.
źródło
11

Możesz przejść booleanprzez wymuszenie, wstawienie go !!przed zmienną.

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

Chciałbym jednak zwrócić uwagę na następujący przypadek, w którym komponent odbierający zdefiniował typedla rekwizytów. W takim przypadku, jeśli isRequiredzdefiniowano typ do stringprzejścia , spraw, booleanże sprawdzenie typu nie powiedzie się, a otrzymasz ostrzeżenie Vue. Aby to naprawić, możesz chcieć uniknąć przekazywania tej właściwości, więc po prostu undefinedustaw rezerwę, a prop nie zostanie wysłany docomponent

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

Wyjaśnienie

Przeszedłem przez ten sam problem i wypróbowałem powyższe rozwiązania !! Tak, nie widzę, propale to faktycznie nie spełnia tego, czego tutaj wymagamy.

Mój problem -

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

W powyższym przypadku spodziewałem się, że nie my-propzostanie przekazany do komponentu podrzędnego - <any-conponent/>nie widzę wejścia, ale propw DOMmoim <any-component/>komponencie wyskakuje błąd z niepowodzenia sprawdzania typu właściwości. Podobnie jak w przypadku komponentu podrzędnego, spodziewam my-propsię, że będzie to, Stringale tak jest boolean.

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

Co oznacza, że ​​komponent potomny otrzymał prop, nawet jeśli tak jest false. Ulepszenie tutaj polega na umożliwieniu komponentowi podrzędnemu przejęcia, default-valuea także pominięciu sprawdzania. Zdane undefinedjednak działa!

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

To działa, a mój atrybut podrzędny ma wartość domyślną.

Satyam Pathak
źródło
2

W html użyj

<input :required="condition" />

I zdefiniuj we właściwościach danych, takich jak

data () {
   return {
      condition: false
   }
}
Nipun Jain
źródło