Как скрыть всплывающие подсказки в Vue

#javascript #vue.js

Вопрос:

Моя цель — получить всплывающее окно всплывающей подсказки при каждом неправильном или пустом поле ввода при нажатии кнопки «Сохранить». Мне удалось отобразить всплывающие подсказки, нажав кнопку «Сохранить», но когда я ввожу правильный текст (цифры), всплывающая подсказка не скрывается, а показывает всплывающую подсказку «false». Как полностью скрыть всплывающие подсказки при правильном вводе?

полный код: https://jsfiddle.net/a8bnp6m4/1 /

 var productForm = Vue.createApp ({})

productForm.component('custom-form', {
  props: {
    modelValue: {
      type: String,
      default: ''
    },
  },   
  components: ['status-bar', 'tooltips'],
  template: `
<button v-on:click="submitProduct">Save</button>
<h1>Product Add</h1>
<div class="lines">
<label>SKU<input type="text" id="sku" v-model="this.product.sku" placeholder="ID"></label>
<tooltips v-if="this.tooltipText.show amp;amp; showTooltip!=false" :tooltip="this.showTooltip(this.product.sku)" />
<label>Name<input type="text" id="name" v-model="this.product.name" placeholder="Please, provide name"></label>
<tooltips v-if="this.tooltipText.show amp;amp; showTooltip!=false" :tooltip="this.showTooltip(this.product.name)" />
<label>Price<input type="text" id="price" v-model="this.product.price" placeholder="Please, provide price"></label>
<tooltips v-if="this.tooltipText.show amp;amp; showTooltip!=false" :tooltip="this.showTooltip(this.product.price)" />
</div>
` ,

  data: function() {
    return {
      product: {
        sku: null,
        name: null,
        price: null,
      },
      options: ['DVD', 'Book', 'Furniture'],
      selected: 'DVD',
      tooltipText: {
        onSubmit: 'Please, submit required data',
        onType: 'Please, provide the data of indicated type',
        show: false
      }
    }
  },
  computed:{
    model:{
      get(){ return this.modelValue },
      set(v){ this.$emit('update:modelValue',v)}
    }
  },

  methods:{
    updateValue: function () {
      return this.$emit('sendData')
    },
    submitProduct: function(){
      for(var i in this.product){
        this.showTooltip(this.product[i])
        if(this.product[i]==null){
          this.tooltipText.show = true
          //this.product[i]=null
        }
      }
    },
    showData: function(){
      //console.log(this.product.sku)
      return JSON.stringify(this.product)
    },
    showTooltip: function(v){
      if(v == null){ return this.tooltipText.onSubmit }
      else if(!Number.isInteger(parseInt(v))){ return this.tooltipText.onType }    

      else { return false  }
    },
    created() {

      this.showData()
    }
  }
})

productForm.component ('tooltips', {             
  template: `
<div class="tooltip" :tooltip="tooltip" :showTooltip="showTooltip">
<span class="tooltiptext">{{tooltip}}</span>
</div>
`
})

const vm = productForm.mount('#product_form')
 

Ответ №1:

Сегодня примерно за 10 минут с ясной головой я решил свою проблему, заменив содержимое ‘v-if’ this.tooltipText.show amp;amp; showTooltip(this.product.sku)!=false на в моем пользовательском теге всплывающей подсказки. 🙂 Я просто забыл добавить аргумент this.product.sku в showTooltip функцию.

полный код: https://jsfiddle.net/amwfcv2o /

 <label>SKU<input type="text" id="sku" v-model="this.product.sku" placeholder="ID"></label>
<tooltips v-if="this.tooltipText.show amp;amp; showTooltip(this.product.sku)!=false" :tooltip="this.showTooltip(this.product.sku)" />

 showTooltip: function(v){
      if(v == null) { return this.tooltipText.onSubmit }
      else if(!Number.isInteger(parseInt(v))) { return this.tooltipText.onType }    
      else { return false  }
    }
  }
})
 

Комментарии:

1. Ха-ха! Да, минутная промашка!

Ответ №2:

Я подозреваю, что проблема связана с this.ToolTipText.show amp;amp; showTooltip!=false». Можете ли вы попробовать изменить его на this.ToolTipText.show amp;amp; showTooltip»

Комментарии:

1. Пробовали любыми способами. Также пытался изменить метод, чтобы возвращать разные значения. Но не повезло.

Ответ №3:

Попробуйте без this в шаблоне и передайте поле в v-if showTooltip :

 <label>SKU<input type="text" id="sku" v-model="product.sku" placeholder="ID"></label>
<tooltips v-if="tooltipText.show amp;amp; showTooltip(product.sku)" :tooltip="showTooltip(product.sku)" />
...
 

Пожалуйста, проверьте следующий фрагмент:

 var productForm = Vue.createApp ({})

productForm.component('custom-form', {
  props: {
    modelValue: {
      type: String,
      default: ''
    },
  },   
  components: ['status-bar', 'tooltips'],
  template: `
<button v-on:click="submitProduct">Save</button>
<h1>Product Add</h1>
<div class="lines">
<label>SKU<input type="text" id="sku" v-model="product.sku" placeholder="ID"></label>
<tooltips v-if="tooltipText.show amp;amp; showTooltip(product.sku)" :tooltip="showTooltip(product.sku)" />
<label>Name<input type="text" id="name" v-model="product.name" placeholder="Please, provide name"></label>
<tooltips v-if="tooltipText.show amp;amp; showTooltip(product.name)" :tooltip="showTooltip(product.name)" />
<label>Price<input type="text" id="price" v-model="product.price" placeholder="Please, provide price"></label>
<tooltips v-if="tooltipText.show amp;amp; showTooltip(product.price)" :tooltip="showTooltip(product.price)" />
</div>
` ,

  data: function() {
    return {
      product: {
        sku: null,
        name: null,
        price: null,
      },
      options: ['DVD', 'Book', 'Furniture'],
      selected: 'DVD',
      tooltipText: {
        onSubmit: 'Please, submit required data',
        onType: 'Please, provide the data of indicated type',
        show: false
      }
    }
  },
  computed:{
    model:{
      get(){ return this.modelValue },
      set(v){ this.$emit('update:modelValue',v)}
    }
  },

  methods:{
    showSelected: function(){
      //return console.log(this.selected)
    },
    updateValue: function () {
      return this.$emit('sendData')
    },
    submitProduct: function(){
      for(var i in this.product){
        this.showTooltip(this.product[i])
        if(this.product[i]==null){
          this.tooltipText.show = true
          //this.product[i]=null
        }
      }
      if (this.tooltipText.show == false){
        //window.location.href = '../';
      }
      //console.log(this.product)
      //return this.postData(this.product)
    },
    showData: function(){
      //console.log(this.product.sku)
      return JSON.stringify(this.product)
    },
    showTooltip: function(v){
      if(v == null){ return this.tooltipText.onSubmit }
      else if(!Number.isInteger(parseInt(v))){ return this.tooltipText.onType }    

      else { return false  }
    },
    created() {

      this.showData()
    }
  }
})

productForm.component ('tooltips', {
  props: ['tooltip', 'showTooltip'],
  //data: function(){
  //    return {
  //        tooltipText: this.tooltipText.onType
  //    }
  //},                
  template: `
<div class="tooltip" :tooltip="tooltip" :showTooltip="showTooltip">
<span class="tooltiptext">{{tooltip}}</span>
</div>
`
})

const vm = productForm.mount('#product_form') 
 <!DOCTYPE html>
<html>
  <head>
    <title>scandiweb task</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
    <link href="../styles.css" rel="stylesheet" type="text/css" media="all">
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> -->
    <script src="https://unpkg.com/vue@next"></script>

  </head>
  <body>
    <style>

      div input {
        display:inline-block;
        justify-content:space-between;
        align-items:center;
        border:3px solid black;
        margin:10px;
        padding:10px;
      }

      div label{
        display:block;
      }

      .tooltip {
        position: relative;
        display: inline;
        border-bottom: 1px dotted black;
      }

      .tooltip .tooltiptext {
        position: absolute;
        width: 400px;
        background-color: black;
        color: #fff;
        text-align: center;
        border-radius: 6px;
        padding: 5px;
        margin-left:300px;
        z-index: 1;
        visibility: visible;
      }

    </style>
    <div id="product_form" v-cloak>
      <custom-form>

      </custom-form>
    </div>

  </body>
</html>