Vue2:使用输入类型为 textarea 的表单组件来显示和编辑数据(无需直接操作道具)

Posted

技术标签:

【中文标题】Vue2:使用输入类型为 textarea 的表单组件来显示和编辑数据(无需直接操作道具)【英文标题】:Vue2: Use form component with input type textarea to display AND edit data (without directly manipulating props) 【发布时间】:2021-02-19 03:28:48 【问题描述】:

我正在构建 MVP,这是我第一次进行 Web 开发。我正在使用 Vue2 和 Firebase,到目前为止,一切顺利。

但是,我遇到了一个无法单独解决的问题。我知道它应该如何工作,但无法将其写入代码,希望你们能帮助我理清思路。到现在为止,我感到非常困惑和越来越沮丧:D

让我们看看我得到了什么:

子组件 我已经构建了一个子组件,它是一个具有三个文本区域的表单。为简单起见,我的代码 sn-ps 仅包含一个。

<template>
  <div class="wrap">
    <form class="form">
    
      <p class="label">Headline</p>
      <textarea rows="2" 
      v-model="propHeadline" 
      :readonly="readonly">
      </textarea>
      
      // To switch between read and edit
      <button
        v-if="readonly"
        @click.prevent="togglemode()">
        edit
      </button>
      <button
        v-else
        type="submit"
        @click.prevent="togglemode(), updatePost()"
      >
        save
      </button>
    </form>
  </div>
</template>

<script>
export default 
name: 'PostComponent'
  data() 
    return 
      readonly: true
    
  ,

  props: 
    propHeadline: 
      type: String,
      required: true
    
  ,
  
  methods: 
    togglemode() 
      if (this.readonly) 
        this.readonly = false
       else 
        this.readonly = true
      
    ,
    updatePost() 
      // updates it to the API - that works
    
  

</script>
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"&gt;&lt;/script&gt;
还有我的父组件:

<template>
  <div class="wrap">
      <PostComponent
        v-for="post in posts"
        :key="post.id"
        :knugHeadline="post.headline"
      />
  </div>
</template>

<script>
import PostComponent from '@/components/PostComponent.vue'

export default 
  components:  PostComponent ,
  data() 
    return 
      posts: []
    
  ,
  created() 
    // Gets all posts from DB and pushes them in array "posts"

</script>
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"&gt;&lt;/script&gt;

当前状态 到目前为止,一切正常。我可以显示所有帖子,当点击“编辑”时,我可以进行更改并保存它们。一切都更新到 Firebase - 太棒了!

问题/错误消息 我收到以下错误消息:

[Vue 警告]:避免直接改变 prop,因为每当父组件重新渲染时,该值都会被覆盖。相反,使用基于 prop 值的数据或计算属性。

正如错误所说,我应该使用基于 props 值的计算属性。但是我怎样才能做到这一点呢?

解决方法 我相信我必须使用计算的 getter 来返回 prop 值 - 怎么做?

然后我必须使用 setter 向父级发出一个事件以更新值,以便 prop 将其向下传递 - 该怎么做?

我在网上找到了一些零碎的东西,但现在我看到的只是幸福的家庭传递小包数据...

非常感谢您提供有关如何解决此问题的建议! :)

非常感谢!

【问题讨论】:

【参考方案1】:

显示此错误是因为您在 texterea 上的 v-model 改变了道具,但在 vue 中改变道具是非法的:

<textarea rows="2" 
  v-model="propHeadline" 
  :readonly="readonly">
  </textarea>

所以,你可以做的是使用这个 created() 生命周期钩子并将 propHeadline 属性设置为数据:

<script>
export default 
name: 'PostComponent'
  data() 
    return 
      readonly: true,
      headline: ""
    
  ,

  props: 
    propHeadline: 
      type: String,
      required: true
    
  ,
  
  created() 
     this.headline = this.propHeadline
  

</script>

然后,更新你的 textarea 上的新变量:

<textarea rows="2" 
  v-model="headline" 
  :readonly="readonly">
  </textarea>

【讨论】:

天哪 - 生活可以如此轻松,当您知道自己在做什么时:D 工作就像一个魅力,非常感谢!

以上是关于Vue2:使用输入类型为 textarea 的表单组件来显示和编辑数据(无需直接操作道具)的主要内容,如果未能解决你的问题,请参考以下文章

vue 2 - 输入时按钮@click不起作用:焦点随高度变化

创建具有多种输入类型的表单

用于表单数据的 FastAPI Textarea OpenAPI

如何在仅使用 PHP 发布后保留 textarea 表单值

用表单处理用户输入

textarea数据输入检查,如果为空,则提醒