【问题标题】:Vuetify Menu, edit text field with custom component keypadVuetify Menu,使用自定义组件键盘编辑文本字段
【发布时间】:2022-01-04 07:16:35
【问题描述】:

我正在使用 vuetify 创建一个应用,但我在使用 v-menu 时遇到了一些问题。

我有一个文本输入,当我点击它时,它会打开一个 v 菜单。在菜单中,我制作了一个组件,它是一个从 0 到 9 的简单键盘。用那个键盘我想改变文本输入。 我想要一个保存按钮来保存所做的更改并关闭菜单。但我无法让它工作。

我怎样才能让它与多个文本输入一起工作。我知道这对于编辑文本输入可能看起来过于复杂,但该应用程序将在更大的触摸屏上运行,我不想为了更改数字而打开大屏幕键盘。

你会怎么做?

<v-menu bottom :close-on-content-click="false">
  <template v-slot:activator="{ on, attrs }">
    <v-text-field
      v-bind="attrs"
      v-on="on"
      v-model="result"
      readonly
    ></v-text-field>
  </template>
  <Calculator :data.sync="result" /> <-------- My keypad component
</v-menu>

键盘组件

    <template>
  <v-card class="widget" @contextmenu.prevent="" color="grey lighten-2" max-width="260" >
    <v-card-text>
      <v-card class="mb-2" elevation="1" min-height="64px" max-height="64px" tile flat color="lighten-grey" >
        <v-card-text>
          <v-text-field dense flat reverse v-model="value" :suffix="suffix" ></v-text-field>
        </v-card-text>
      </v-card>
      <v-row no-gutters class="pb-1">
        <v-col align="center" justify="center">
          <v-btn color="grey lighten-5" @click="click1" tile elevation="1" height="55px" >1</v-btn>
        </v-col>
        <v-col align="center" justify="center">
          <v-btn color="grey lighten-5" @click="click2" tile elevation="1" height="55px" >2</v-btn>
        </v-col>
        <v-col align="center" justify="center">
          <v-btn color="grey lighten-5" @click="click3" tile elevation="1" height="55px" >3</v-btn>
        </v-col>
      </v-row>
      <v-row no-gutters class="pb-1">
        <v-col align="center" justify="center">
          <v-btn color="grey lighten-5" @click="click0" tile elevation="1" height="55px" >0</v-btn >
        </v-col>
        <v-col align="center" justify="center">
          <v-btn color="grey lighten-5" @click="clickDecimal" tile elevation="1" height="55px" >.</v-btn >
        </v-col>
        <v-col align="center" justify="center">
          <v-btn color="grey lighten-5" @click="clickClear" tile elevation="1" height="55px" >C</v-btn >
        </v-col>
      </v-row>
      <v-row no-gutters class="pt-2">
        <v-col align="right">
          <v-btn @click="cancel" tile small>Cancel</v-btn>
          <v-btn class="ml-2 mr-0" @click="onSave" tile small>Save</v-btn>
        </v-col>
      </v-row>
    </v-card-text>
  </v-card>
</template>

<script>
export default {
  props: ['data', 'suffix'],
  data() {
    return { value: '0', };
  },
  methods: {
    click0() {
      if (this.value.toString().length > 9) return;
      if (this.value === '0') { this.value = ''; }
      this.value = this.value + '0';
    },
    click1() {
      if (this.value.toString().length > 9) return;
      if (this.value === '0') { this.value = ''; }
      this.value = this.value + '1';
    },
    click2() {
      if (this.value.toString().length > 9) return;
      if (this.value === '0') { this.value = ''; }
      this.value = this.value + '2';
    },
    click3() {
      if (this.value.toString().length > 9) return;
      if (this.value === '0') { this.value = ''; }
      this.value = this.value + '3';
    },
    clickClear() {
      this.value = '0';
    },
    clickDecimal() {
      if (this.value.includes('.')) return;
      this.value = this.value + '.';
    },
    onSave() {},
    cancel() {},
  },
};
</script>

【问题讨论】:

  • 考虑从子Calculator 组件发射result 并从parent 设置相同的值。
  • 你能分享你的键盘组件吗?像 Anees 所说的发出事件来更新父 v-text-field 是正确的方法。我可以为你制作一个密码箱。
  • 我厌倦了使用 emit,但不知道如何处理多个文本字段。我可以分享我的组件,但这个评论太重要了。
  • 我在我的问题@cmfc31 中添加到组件

标签: javascript vue.js vuetify.js


【解决方案1】:

感谢您分享您的键盘组件代码。检查我制作的这个代码框:https://codesandbox.io/s/stack-70120821-5uyq4?file=/src/components/Keypad.vue

我通过删除内部文本字段和取消/保存按钮简化了您的键盘组件的使用,还优化了小键盘的生成方式,但您可以根据自己的喜好对其进行修改。

我为键盘的内部 value 编号设置了一个监视程序。并且每当它更新时,都会向其父级发出一个名为 "output" 的事件,并带有新值。

 watch: {
    ...
    // When inner value gets a new value, emits and event to parent
    value(val) {
      this.$emit('output', val)
    }
  },

在父端,您通过设置自定义事件 @output 接收新值。 $event 变量包含从子组件发出的数据。在这个例子中,我只是简单地更新了父组件的 v-text-field 的值。但是,如果您需要验证某事或用它做其他事情,您也可以将此值传递给方法。

    <Keypad :input="result" @output="result = $event" />

如果您需要从父组件更新键盘值,您可以使用我定义的称为 input 的道具来完成。为了能够在页面的初始加载时正常工作,您需要使用 v-menu 上的 eager 属性。这样一来,自定义键盘组件就会从一开始就呈现出来。

【讨论】:

  • 哇,谢谢!我真的很感激?我无法让观察者输入工作,我不得不更改为input: { immediate: true, handler(val) { this.value = val; }, }, 我还有一个问题,我真的需要一个保存按钮作为额外的保护。我为此设置方法没有问题,但我不知道如何关闭 v-menu。我可以用 v-model 来做,但是因为有很多文本输入,所以会有很多方法。似乎是一种更好的方法,我可以以某种方式传递 attrs 吗?
  • 您好,很高兴为您提供帮助。我更新了代码框以实现取消/保存功能。多文本输入是什么意思?
  • 感谢您的帮助。我在一个组件中有很多文本输入,当使用 v-model 打开 v-menu 时,我不知道如何使用它。但后来我发现,我使用 v-for 和数组来渲染所有 v-menu。效果很好!
猜你喜欢
  • 2023-04-11
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 2014-11-19
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
相关资源
最近更新 更多