Maria Minh
Maria Minh

Reputation: 1249

How to add an attribute dynamically in VueJs

I'm using vuejs and I wanna know how to have control on inputs (add disabled attribute when necessary). Is there any way to add dynamically attribute in vuejs ? Below my Textfield component :

    <template>
     <input type="text" placeholder="{{ placeholder }}" v-model="value">
    </template>
    <script>
    export default  {
      props: {
       disabled: {type: Boolean, default: false},
       placeholder: {type: String, default: ""},
       value: {twoWay: true, default: ""}
      }
     }
    </script>

Usage :

<textfield placeholder="Name" value.sync="el.name" :disabled="true"></textfield>

Upvotes: 87

Views: 171933

Answers (8)

Unmitigated
Unmitigated

Reputation: 89472

To set an attribute whose name is dynamic (e.g. a variable), one can pass a dynamic argument to v-bind using square brackets.

<div :[attrName]="attrValue">Content...</div>

This is the shorthand for v-bind:[attrName]="attrValue".

See Vue SFC Playground example

Upvotes: 1

Yogesh Waghmare
Yogesh Waghmare

Reputation: 1045

ok, try this if you are passing i18 -

:placeholder="$t('languagePlaceholder')"

Upvotes: 2

rosell.dk
rosell.dk

Reputation: 2502

As pointed out, you don't need dynamic attributes in your case.

But well, you asked if it is possible, and the answer is yes. You can have dynamic attributes, as of 2.6.0.

Example:

<a v-bind:[attributeName]="whatever">

It is documented here

Upvotes: 26

Pankaj Rupapara
Pankaj Rupapara

Reputation: 780

base one condition we can define or change attributes in vue

Please refer official document for the same https://v2.vuejs.org/v2/guide/syntax.html#Attributes

Upvotes: 3

Mises
Mises

Reputation: 4623

Vue3 Example with error:

BaseInput.vue

<template>
    <div>
        <label>{{ label }}</label>
        <input v-bind="$attrs" :placeholder="label" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
        <p v-if="error">{{ error }}</p>
    </div>
</template>

<script setup>
defineProps(['label', 'modelValue', 'error'])
defineEmits(['update:modelValue'])
</script>

v-bind="$attrs" is necessary if you want to pass attributes to child tag or there are multiple tag in <template> you can specify with tag need to get attributes.

Login.vue

<template>
    <form @focusout="validateForm" @submit.prevent="onSubmit">
        <BaseTitle title="Log in" h="h1"/>
        <BaseInput type="email" v-model="email" label="Email" :error="emailError"/>
        <BaseInput type="password" v-model="password" label="Password" :error="passwordError"/>
        <BaseButton type="submit" label="LogIn" />
    </form>
</template>

<script setup lang="ts">

const email = ref('')
const password = ref('')
const emailError = ref('')
const passwordError = ref('')

function validateForm() {
    emailError.value = "Error"
}

function onSubmit() {
    signIn({ email: email.value, password: password.value})
}
</script>

Upvotes: 0

Cyebukayire
Cyebukayire

Reputation: 947

I did that with checkboxes:

 <select id="newTwootType" v-model="state.selectedTwootType">
      <option 
      :value="option.value" 
      v-for="(option, index) in state.twootTypes" 
      :key="index">
        {{ option.name }}
      </option>
    </select>

my scripts

export default {
name: 'CreateNewTwootPanel',
setup(props, ctx) {
  const state = reactive({  
      selectedTwootType: 'instant',
      twootTypes: [
          { value: 'draft', name: 'Draft' },
          { value: 'instant', name: 'Instant Twoot' }
      ],
  })

  return {
    state,
    }
  }
}

Upvotes: 0

Jeff
Jeff

Reputation: 25221

You can bind it to a variable using v-bind:disabled="foo" or :disabled="foo" for short:

<textfield label="Name" value.sync="el.name" :disabled="myVar">

Then in Vue you can just set this.myVar = true and it will disable the input.

Edit: add this to your template:

<template>
  <input type="text" :disabled="disabled" :placeholder="placeholder" v-model="value">
</template>

Upvotes: 82

Black Horse
Black Horse

Reputation: 71

I am trying to figure out how to set the attribute of the html tags from the array value dynamically when using the Vue v-for loop.

What I am going to show:

Example

  1. There are 3 div elements with different background colors from array value(not static).
  2. Each divs have a input tag and change the value when the user input value

    • The first div's input converts lowercase to uppercase.
    • second represents the mood, if enter 'happy', present 'good'. if enter 'sad', output 'bad'
    • The third div input doubles the input value.
    {{ box.outputData }} Rounded Box
    new Vue({
     el: "#app",
      data: {
        isRounded: false,
          boxes: [
            {
              inputData: "",
              outputData: "",
              color: "green",
              operation: "uppercase"
            },
            {
              inputData: "",
              outputData: "",
              color: "red",
              operation: "feeling"
            },
            {
              inputData: "",
              outputData: "",
              color: "blue",
              operation: "multiple"
            }
          ],
          feeling: {
            good: ["happy", "joyful", "calm"],
            bad: ["sad", "mad", "depressed"]
          }
      },
      methods: {
        toggle: function(todo){
            todo.done = !todo.done
        }
      },
      watch: {
        boxes: {
          deep: true,
          immediate: true,
          handler: function(val) {
            this.boxes.map(box => {
              if (box.operation === "uppercase")
                box.outputData = box.inputData.toUpperCase();
              else if (box.operation === "feeling") {
                box.outputData = this.feeling.good.includes(box.inputData)
                  ? "GOOD"
                  : this.feeling.bad.includes(box.inputData)
                  ? "BAD"
                  : "";
              } else if (box.operation === "multiple") {
                if (box.inputData == "") box.outputData = "";
                else box.outputData = parseInt(box.inputData) * 2;
              }
            });
          }
        }
      },
      mounted() {
        for (var i = 0; i < this.numBox; i++) {
          this.boxValue[i] = "";
          this.bxData[i] = "";
        }
      },
    })
    
    
    
    .clearfix{
     clear: both;
    }
    .full-width{
      width:100%;
    }
    input {
      background: transparent;
      text-decoration: underline;
      color: white;
      border: none;
      text-align: center;
      font-size:30px;
    }
    .box {
      float:left;
      color: white;
      width: 24%;
      margin-right: 1%;
      padding: 20px;
      background: blue;
      height: 100px;
    }
    .box-output {
      width: 100%;
      text-align: center;
      font-size:30px;
    }
    .box-rounded {
      border-radius: 50px;
    }
    

Upvotes: 5

Related Questions