弹出编辑

QPopupEdit 组件可用于“就地”编辑值,例如 QTable 中的单元格。默认情况下,单元格显示为字符串,如果您使用 QPopupEdit,当用户单击表格单元格,将弹出一个编辑框,用户可以使用它编辑文本字段。

这个组件会将一个 QMenu 注入到它的父 DOM 元素中来实现上述的行为,所以它可以被用在任何地方,而不仅仅是在 QTable 中。

QPopupEdit API

QPopupEdit API


auto-save
: Boolean
说明
当用户在弹出窗口外部点击/触摸时,自动保存模型(如果有更改);不适用于 ESC 键。
touch-position
: Boolean
说明
允许通过鼠标位置设置目标位置,当菜单的目标被点击或触摸时。
persistent
: Boolean
说明
避免通过按下 ESC 键或在弹出窗口外部点击/触摸来关闭菜单
separate-close-popup
: Boolean
说明
与父菜单分离,将其标记为 v-close-popup 的独立关闭点(如果没有此选项,链接的菜单会一起关闭)。

用法

WARNING

如果用于一个 QTable 中, QPopupEdit 无法在单元格范围的插槽中工作。

标准



<template>
  <div class="q-pa-md">
    <div class="cursor-pointer">
      {{ label }}
      <q-popup-edit v-model="label" auto-save v-slot="scope">
        <q-input v-model="scope.value" dense autofocus counter @keyup.enter="scope.set" />
      </q-popup-edit>
    </div>
  </div>
</template>

Click me

在 QTable 中使用

点击单元格来查看弹出的编辑器。“Name” 列展示了 title 属性的用法。“Calories” 列展示了数字类型数据的用法。“Fat” 列展示了 disable 属性的用法。如果您看一下源代码,您会发现 “Fat” 单元格使用了 QPopupEdit,但是当点击该单元格时,弹出窗口并没有显示。



<template>
  <div class="q-pa-md">
   <q-table
      :rows="rows"
      :columns="columns"
      title="QDataTable with QPopupEdit"
      :rows-per-page-options="[]"
      row-key="name"
    >
      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td key="desc" :props="props">
            {{ props.row.name }}
            <q-popup-edit v-model="props.row.name" title="Edit the Name" auto-save v-slot="scope">
              <q-input v-model="scope.value" dense autofocus counter @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="calories" :props="props">
            {{ props.row.calories }}
            <q-popup-edit v-model.number="props.row.calories" auto-save v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="fat" :props="props">
            {{ props.row.fat }}
            <q-popup-edit disable v-model="props.row.fat" auto-save v-slot="scope">
              <div class="text-italic text-primary q-mb-xs">
                My Custom Title
              </div>

              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="carbs" :props="props">
            {{ props.row.carbs }}
          </q-td>
          <q-td key="protein" :props="props">
            {{ props.row.protein }}
          </q-td>
          <q-td key="sodium" :props="props">
            {{ props.row.sodium }}
          </q-td>
          <q-td key="calcium" :props="props">
            {{ props.row.calcium }}
            <q-popup-edit v-model="props.row.calcium" v-slot="scope">
              <div class="text-italic text-primary">
                My Custom Title
              </div>
              <q-input v-model="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="iron" :props="props">
            {{ props.row.iron }}
          </q-td>
        </q-tr>
      </template>
    </q-table>
  </div>
</template>

QDataTable with QPopupEdit
Dessert (100g serving)CaloriesFat (g)Carbs (g)Protein (g)Sodium (mg)Calcium (%)Iron (%)
Frozen Yogurt 159 6 2448714% 1%
Ice cream sandwich 237 9 374.31298% 1%
Eclair 262 16 2363376% 7%
Cupcake 305 3.7 674.34133% 8%
Gingerbread 356 16 493.93277% 16%
1-5 / 10

自定义



<template>
  <div class="q-pa-md">
    <div class="q-gutter-md">
      <div class="cursor-pointer" style="width: 100px">
        {{ label }}
        <q-popup-edit v-model="label" class="bg-accent text-white" v-slot="scope">
          <q-input dark color="white" v-model="scope.value" dense autofocus counter @keyup.enter="scope.set">
            <template v-slot:append>
              <q-icon name="edit" />
            </template>
          </q-input>
        </q-popup-edit>
      </div>

      <div class="cursor-pointer" style="width: 100px">
        {{ label2 }}
        <q-popup-edit v-model="label2" :cover="false" :offset="[0, 10]" v-slot="scope">
          <q-input color="accent" v-model="scope.value" dense autofocus counter @keyup.enter="scope.set">
            <template v-slot:prepend>
              <q-icon name="record_voice_over" color="accent" />
            </template>
          </q-input>
        </q-popup-edit>
      </div>
    </div>
  </div>
</template>

Click me
Also click me

保持且带有按钮的

还可以使用 buttons 为其添加两个按钮,“Cancel” 和 “Set”(默认标签,但是您可以通过 label-setlabel-cancel 属性来自定义它们的标签内容),这有助于用户控制用户的输入。除此之外,您还可以使用 persistent 来取消用户使用 escape 键和点击 QPopupEdit 外部可以关闭弹窗的行为。

下面的示例中,“carbs” 列展示了 persistent 属性的用法。“Protein” 列展示了 label-setlabel-cancel 的用法,注意其中,“Save” 替换了默认的 “Set”,“Close” 替换了默认的 “Cancel”。



<template>
  <div class="q-pa-md">
   <q-table
      :rows="rows"
      :columns="columns"
      title="QDataTable with QPopupEdit"
      :rows-per-page-options="[]"
      row-key="name"
    >
      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td key="desc" :props="props">
            {{ props.row.name }}
            <q-popup-edit v-model="props.row.name" buttons v-slot="scope">
              <q-input v-model="scope.value" dense autofocus counter @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="calories" :props="props">
            {{ props.row.calories }}
            <q-popup-edit v-model.number="props.row.calories" buttons v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="fat" :props="props">
            <div class="text-pre-wrap">{{ props.row.fat }}</div>
            <q-popup-edit v-model.number="props.row.fat" buttons v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="carbs" :props="props">
            {{ props.row.carbs }}
            <q-popup-edit v-model.number="props.row.carbs" buttons persistent v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="protein" :props="props">
            {{ props.row.protein }}
            <q-popup-edit v-model.number="props.row.protein" buttons label-set="Save" label-cancel="Close" v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="sodium" :props="props">
            {{ props.row.sodium }}
            <q-popup-edit v-model.number="props.row.sodium" buttons v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="calcium" :props="props">
            {{ props.row.calcium }}
            <q-popup-edit v-model="props.row.calcium" buttons v-slot="scope">
              <q-input v-model="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
          <q-td key="iron" :props="props">
            {{ props.row.iron }}
            <q-popup-edit v-model="props.row.iron" buttons v-slot="scope">
              <q-input v-model="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
        </q-tr>
      </template>
    </q-table>
  </div>
</template>

QDataTable with QPopupEdit
Dessert (100g serving)CaloriesFat (g)Carbs (g)Protein (g)Sodium (mg)Calcium (%)Iron (%)
Frozen Yogurt 159
6
24 4 87 14% 1%
Ice cream sandwich 237
9
37 4.3 129 8% 1%
Eclair 262
16
23 6 337 6% 7%
Cupcake 305
3.7
67 4.3 413 3% 8%
Gingerbread 356
16
49 3.9 327 7% 16%
1-5 / 10

默认插槽

默认插槽的参数是:

{ initialValue, value, validate, set, cancel, updatePosition }

WARNING

不要破坏槽的参数结构,因为直接对 value 使用 v-model 时,会产生格式错误。



<template>
  <div class="q-pa-md">
    <div class="cursor-pointer">
      {{ nickname }}
      <q-popup-edit v-model="nickname" :validate="val => val.length > 5" v-slot="scope">
        <q-input
          autofocus
          dense
          v-model="scope.value"
          :model-value="scope.value"
          hint="Your nickname"
          :rules="[
            val => scope.validate(val) || 'More than 5 chars required'
          ]"
        >
          <template v-slot:after>
            <q-btn
              flat dense color="negative" icon="cancel"
              @click.stop="scope.cancel"
            />

            <q-btn
              flat dense color="positive" icon="check_circle"
              @click.stop="scope.set"
              :disable="scope.validate(scope.value) === false || scope.initialValue === scope.value"
            />
          </template>
        </q-input>
      </q-popup-edit>
    </div>
  </div>
</template>

Click me

Textarea / QEditor

由于 QPopupEdit 封装了 QInput,所以您基本上可以使用任意类型的 QInput。例如,您还可以使用下面的 “Comments” 列中所示的文本域。

TIP

当使用多行输入控件(textarea、QEditor)时,您还需要在组件上使用 @keyup.enter.stop,以阻止回车键关闭弹出窗口。 您还需要添加按钮来控制弹窗。



<template>
  <div class="q-pa-md">
   <q-table
      :rows="rows"
      :columns="columns"
      title="QDataTable with QPopupEdit"
      :rows-per-page-options="[]"
      row-key="name"
      wrap-cells
    >
      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td key="desc" :props="props">
            {{ props.row.name }}
          </q-td>

          <q-td key="comment" :props="props">
            <div>{{ props.row.comment }}</div>
            <q-popup-edit
              buttons
              v-model="props.row.comment"
              v-slot="scope"
            >
              <q-input
                type="textarea"
                v-model="scope.value"
                autofocus
                counter
                @keyup.enter.stop
              />
            </q-popup-edit>
          </q-td>

          <q-td key="calories" :props="props">
            {{ props.row.calories }}
          </q-td>

          <q-td key="fat" :props="props">
            <div>{{ props.row.fat }}</div>
          </q-td>
        </q-tr>
      </template>
    </q-table>
  </div>
</template>

QDataTable with QPopupEdit
DessertComment (editable)CaloriesFat (g)
Frozen Yogurt
It's cold but great and tastes different than normal ice cream, but it's great too! Have a taste!
159
6
Ice cream sandwich
It's also cold but great! Have a taste!
237
9
Eclair
It's not cold and also great! Have a taste!
262
16
Cupcake
It could be warm and it's great! Have a taste!
305
3.7
Gingerbread
It's spicy and great! Have a taste!
356
16
1-5 / 10


<template>
  <div class="q-pa-md">
   <q-table
      :rows="rows"
      :columns="columns"
      title="QDataTable with QPopupEdit"
      :rows-per-page-options="[]"
      row-key="name"
      wrap-cells
    >
      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td key="desc" :props="props">
            {{ props.row.name }}
            <q-popup-edit v-model="props.row.name" v-slot="scope">
              <q-input v-model="scope.value" dense autofocus counter @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>

          <q-td key="comment" :props="props">
            <div v-html="props.row.comment"></div>
            <q-popup-edit
              buttons
              v-model="props.row.comment"
              v-slot="scope"
            >
              <q-editor
                v-model="scope.value"
                min-height="5rem"
                autofocus
                @keyup.enter.stop
              />
            </q-popup-edit>
          </q-td>

          <q-td key="calories" :props="props">
            {{ props.row.calories }}
            <q-popup-edit v-model.number="props.row.calories" v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>

          <q-td key="fat" :props="props">
            <div class="text-pre-wrap">{{ props.row.fat }}</div>
            <q-popup-edit v-model.number="props.row.fat" v-slot="scope">
              <q-input type="number" v-model.number="scope.value" dense autofocus @keyup.enter="scope.set" />
            </q-popup-edit>
          </q-td>
        </q-tr>
      </template>
    </q-table>
  </div>
</template>

QDataTable with QPopupEdit
DessertComment (editable)CaloriesFat (g)
Frozen Yogurt

It's cold but great and tastes different than normal ice cream, but it's great too!

Have a taste!

159
6
Ice cream sandwich

It's also cold but great!

Have a taste!

237
9
Eclair

It's not cold and also great!

Have a taste!

262
16
Cupcake

It could be warm and it's great!

Have a taste!

305
3.7
Gingerbread

It's spicy and great!

Have a taste!

356
16
1-5 / 10

验证

QPopupEdit 还允许对输入进行简单的验证。要使用它,您需要以箭头函数的形式为其提供回调函数,并且该函数应返回布尔值。 (value) => Boolean。在下面的 “Calories” 列中演示。

提示 1

请注意,我们需要使用 hide 事件来重新验证输入。如果我们不这样做,QInput 的 error 属性将以无效状态 “挂起”。

提示 2

在本例中,我们使用 QInput 的外部错误处理。我们还可以使用 QInput 的验证属性并将值发送到 QPopupEdit 的验证属性。同样的概念也可以在使用 Vuelidate 时实现。换句话说,给 QPopupEdit 的 validate 函数的值可以来自任何地方。



<template>
  <div class="q-pa-md">
   <q-table
      :rows="rows"
      :columns="columns"
      title="QDataTable with QPopupEdit"
      :rows-per-page-options="[]"
      row-key="name"
    >
      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td key="desc" :props="props">
            {{ props.row.name }}
          </q-td>
          <q-td key="calories" :props="props">
            {{ props.row.calories }}
            <q-popup-edit
              v-model.number="props.row.calories"
              buttons
              label-set="Save"
              label-cancel="Close"
              :validate="caloriesRangeValidation"
              @hide="caloriesRangeValidation"
              v-slot="scope"
            >
              <q-input
                type="number"
                v-model.number="scope.value"
                hint="Enter a number between 4 and 7"
                :error="errorCalories"
                :error-message="errorMessageCalories"
                dense
                autofocus
                @keyup.enter="scope.set"
              />
            </q-popup-edit>
          </q-td>
          <q-td key="fat" :props="props">
            <div class="text-pre-wrap">{{ props.row.fat }}</div>
          </q-td>
          <q-td key="carbs" :props="props">
            {{ props.row.carbs }}
          </q-td>
          <q-td key="protein" :props="props">
            {{ props.row.protein }}
          </q-td>
        </q-tr>
      </template>
    </q-table>
  </div>
</template>

QDataTable with QPopupEdit
DessertCalories (editable)FatCarbsProtein
Frozen Yogurt159
6
244
Ice cream sandwich237
9
374.3
Eclair262
16
236
Cupcake305
3.7
674.3
Gingerbread356
16
493.9
1-5 / 10