Vue 组件没有正确更新属性

Posted

技术标签:

【中文标题】Vue 组件没有正确更新属性【英文标题】:Vue component not updating property correctly 【发布时间】:2020-01-07 15:48:55 【问题描述】:

我有一个chat 组件,它有一个multiline textboxchat room,其中messages 所在的位置,当用户键入它时,多行文本框以44pxheight 的单行开头增长,chat room 变小,如下图所示。

我在下一个代码中得到了这种行为

//chat room in the chat-room i use css variables to calculate the height
//template
<vue-perfect-scrollbar ref="chatRoomScrollbar" :style="css">
    <div  v-viewer="viewerOptions" class="chat-room px-3 py-3">\
        ...
    </div>
</vue-perfect-scrollbar>
//script
props: 
  textFieldSize: 
    type: Number,
    default: 44,
  ,
,
computed:  
    css() 
      return 
        '--height': `calc(310px - $this.textFieldSizepx)`,
        '--max-height': `calc(310px - $this.textFieldSizepx)`,
      ;
    ,
,
//style
.chat-room-container > .ps-container 
  height: var(--height);
  min-height: var(--max-height);
  background-color: #eceff1 !important;

@input 事件被触发时,我在父组件中得到textFieldSize

//chat-room
<chat-room
    :text-field-size="textFieldSize">
</chat-room>
// textbox
<v-text-field
    id="messageField"
    v-model="form.text"
    @input="getTextboxSize">
    <v-icon slot="append-icon">send</v-icon>
</v-text-field>
// script
data() 
    return 
        textFieldSize: 44,
    ;
,
methods: 
    getTextboxSize() 
      if (document.getElementById('messageField')) 
        const height = document.getElementById('messageField').offsetHeight;
        this.textFieldSize = height;
        this.updateChatScrollbar = true;
      
      if (this.form.text === '') 
        this.textFieldSize = 44;
      
    ,
,

当用户键入时,我得到textfield 的高度,并将其传递给chat room,并使用 css 变量得到高度差。

问题

当我选择文本并删除它,或者我使用ctrl+z 时,textFieldSize 的值在我再次输入之前不会重新计算,我尝试在文本字段中使用input 事件,使用form.text 中的观察者,但他们都没有工作,如何才能做到这一点?

在下面的图片中,我选择了文本,然后将其删除,并显示textFieldSize 值没有改变

【问题讨论】:

试试@change而不是@input 【参考方案1】:

问题在于 Ctrl+Z 不会触发 input 事件。我认为您最好不要绑定到文本框的input 事件,而是查看form.text 属性以进行更改。

watch:
    'form.text':function()
        getTextBoxSize();
    

【讨论】:

【参考方案2】:

我会提出 2 点:

    您为什么不在getTextboxSize() 中使用$refs - 我认为这不是您的问题的原因,但它肯定是。当您可以在 v-text-field 元素上设置 ref="message-field" 然后使用 this.$refs['message-field'] 以 Vue 方式 直接访问该元素时,看到您跳入原始 js 真是很奇怪。我可能对此不以为然,但每当我遇到这类反应性丧失的问题时,通常是由于这样的原因。

    这很便宜,通常不是最佳实践,但您可以尝试将this.$forceUpdate() 放在getTextboxSize() 函数的末尾。这是一种告诉 Vue 再次更新布局的方法。我会尝试一下,如果它解决了问题,那么你就知道这是一种反应性/竞争条件问题。我不使用this.$forceUpdate() 发布生产代码,因为如果您需要使用它,通常表明存在更基本的设计问题。

【讨论】:

以上是关于Vue 组件没有正确更新属性的主要内容,如果未能解决你的问题,请参考以下文章

Vue 道具没有在子组件中正确更新

Vue - 组件道具没有正确观察对象变化

Vue没有根据方法更新计算属性,但是直接调用时相同的方法返回正确的值

Laravel - Vue - 组件不更新

Vue2:数据更新但html没有?

为啥 Vue 渲染组件不正确?