运行方法Vuejs后,支持值丢失

时间:2017-04-09 06:58:01

标签: javascript vue.js vuejs2

我将材质设计输入字段设为Vue组件。我监听焦点事件并运行一个函数来检查每次用户聚焦时的值。这是代码:

<template>
<span class="h-input-container">
    <input :type="type" :name="name" v-validate="validation" 
@focusout="classHandle" :id="id" :value="value">
    <p :class="focusClass"><i :class="icon"></i>&nbsp;{{placeholder}}</p>
</span>
</template>

<script>
export default {
    mounted: function(){
        if (this.value != '') {
            this.focusClass = 'focused'
        }
    },
    props: {
        placeholder: {
            default: ''
        },
        name: {
            default: 'no-name'
        },
        type: {
            default: 'text'
        },
        validation: {
            default: ''
        },
        icon: {
            default: ''
        },
        id: {
            default: ''
        },
        value: {
            default: ''
        }
    },
    data: function(){
        return {
            focusClass: '',
        }
    },
    methods: {
        classHandle: function(event){
            if (event.target.value != '') {
                this.focusClass = 'focused'
            } else {
                this.focusClass = ''
            }
        }
    }
};
</script>

我将值作为名为value的道具传递,我使用:value="value"将该值用于输入字段。问题是,每次方法classHandle运行时,输入字段的值都会消失。我无法弄清楚原因。

2 个答案:

答案 0 :(得分:2)

为了澄清接受的答案,Vue没有&#34;刷新&#34; focusout处理程序触发时的值。属性value从未更改过,输入元素的值已更改。

更改focusClass强制Vue将组件重新呈现给DOM。因为您已告诉Vue使用该属性value作为通过:value="value"输入的值,它使用属性的当前状态,从未更改如上所述,渲染组件和输入中输入的内容都会消失。

接受的答案继续说明你应该通过更新this.value来解决这个问题。在组件中,Vue将允许您这样做,但它会在控制台中发出警告。

  

[Vue警告]:避免直接改变道具,因为该值将是   父组件重新渲染时会覆盖。相反,使用   基于prop值的数据或计算属性。支持存在   变异:&#34;价值&#34;

Vue中组件的属性就像javascript中的函数参数一样。在组件内部,可以更改它们,但该更改仅限于组件的范围。如果组件必须重新渲染,那么属性&#34; value&#34;您的输入将使用父版本的值重新绘制,您将失去更改。

在Vue&#34;

Component communication支持事件,#34;要更改组件外部的值,您必须$emit它。以下是适用的组件版本,不会发出任何警告,并且可以正确地发出更改。

{
  props: {
    placeholder: {
      default: ''
    },
    name: {
      default: 'no-name'
    },
    type: {
      default: 'text'
    },
    validation: {
      default: ''
    },
    icon: {
      default: ''
    },
    id: {
      default: ''
    },
    value: {
      default: ''
    }
  },
  template:`
    <div class="h-input-container" style="background-color: lightgray">
        <input :type="type" :name="name"  
    @focusout="classHandle" :id="id" :value="value" @input="$emit('input', $event.target.value)" />
        <p :class="focusClass"><i :class="icon"></i>&nbsp;{{placeholder}}</p>
    </div>
  `,
  data: function() {
    return {
      focusClass: '',
    }
  },
  methods: {
    classHandle: function(event) {
      if (event.target.value != '') {
        this.focusClass = 'focused'
      } else {
        this.focusClass = ''
      }
    }
  }
}

我已经整理了example来证明这两种方法的不同之处。

通常情况下,我不会使用:value="value" @input="$emit('input', $event.target.value)"而是使用v-model,但您也使用:type="type",而Vue会发出警告,要求v-model使用awk动态类型。

答案 1 :(得分:0)

当您在输入中进行更改时,您当前的组件似乎不会刷新this.value。当您使用focusOut时,Vue会导致组件刷新,并且由于您的值未更新,因此显示为empy。要解决您的问题,您需要更新活动this.value

上的input

new Vue(
{
  el: '#app',
  props: {
    placeholder: {
      default: ''
    },
    name: {
      default: 'no-name'
    },
    type: {
      default: 'text'
    },
    validation: {
      default: ''
    },
    icon: {
      default: ''
    },
    id: {
      default: ''
    },
    value: {
      default: ''
    }
  },
  data: function() {
    return {
      focusClass: '',
    }
  },
  methods: {
    updateValue(event) {
    	this.value = event.target.value
    },
    classHandle: function(event) {
      if (event.target.value != '') {
        this.focusClass = 'focused'
      } else {
        this.focusClass = ''
      }
    }
  }
});
<script src="https://vuejs.org/js/vue.min.js"></script>

<div id="app">
<span class="h-input-container">
    <input :type="type" :name="name" v-validate="validation" 
@focusout="classHandle" :id="id" :value="value" @input="updateValue" />
    <p :class="focusClass"><i :class="icon"></i>&nbsp;{{placeholder}}</p>
</span>
</div>

所以你应该注意:

@input="updateValue"

updateValue(event) {
    this.value = event.target.value
}