Vue: Tambahkan pengubah model v khusus

Dibuat pada 13 Sep 2016  ·  52Komentar  ·  Sumber: vuejs/vue

Kami memiliki .lazy , .number , .trim dan .undef sedang dalam perjalanan.

Terlepas dari .lazy mereka semua bekerja seperti filter dua arah.

Karena 2.0 tidak mendukung filter 2 arah, mungkin harus ada api baru untuk menambahkan pengubah model v khusus untuk memenuhi kebutuhan yang sama.

feature request

Komentar yang paling membantu

Adakah kemungkinan kita bisa membuka kembali masalah ini? Kasus penggunaan yang umum bagi saya adalah kebutuhan untuk secara otomatis memformat data dalam bidang saat sedang diketik. Sesuatu seperti mengambil '101216' dan mengubahnya menjadi '10/12/16'. Mampu membuat modifier v-model kustom akan sangat menyederhanakan kode saya karena saya bisa menulis v-model.date daripada harus membangun komponen input kustom dengan props dan event.

Semua 52 komentar

@posva properti yang dihitung tidak dapat digunakan kembali.

Hampir semuanya dapat digunakan kembali melalui mixin.
Anda dapat menggunakan fungsi yang menghasilkan mixin. Dengan cara ini Anda dapat mengikat
properti yang dihitung secara dinamis. Saya tidak bisa menempatkan contoh itu di biola sekarang
tapi saya akan melakukannya secepatnya.
Namun, saya setuju ini adalah kasus penggunaan yang sangat umum untuk input
transformasi diterapkan. Api yang tepat atau setidaknya penjelasan tentang
panduan diperlukan

Pada Sel, 13 Sep 2016, 18:48 Francisco Lourenço, [email protected]
menulis:

@posva https://github.com/posva properti yang dihitung tidak dapat digunakan kembali.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/vuejs/vue/issues/3666#issuecomment -246746524, atau bisukan
benang
https://github.com/notifications/unsubscribe-auth/AAoicf33lCvETQc9LBQ5GGZ93ExPcLS_ks5qptPegaJpZM4J7vQ0
.

Hampir semuanya dapat digunakan kembali melalui mixin.
Anda dapat menggunakan fungsi yang menghasilkan mixin. Dengan cara ini Anda dapat mengikat
properti yang dihitung secara dinamis. Saya tidak bisa menempatkan contoh itu di biola sekarang
tapi saya akan melakukannya secepatnya.
Namun, saya setuju ini adalah kasus penggunaan yang sangat umum untuk input
transformasi diterapkan. Api yang tepat atau setidaknya penjelasan tentang
panduan diperlukan

Dengan kata lain, properti yang dihitung tidak dapat digunakan kembali. Anda dapat menggunakan fungsi pabrik + mixin sebagai solusi , tetapi kegunaan dan keterbacaan tidak sebanding.

Untuk proyek saya, saya sangat membutuhkan fitur ini, jadi saya menggunakan pendekatan input khusus yang disarankan:

MasukanCustom.js

define(function () {
  return Vue.extend({
    data: function () {
      return {
        focused: false
      };
    },
    template: '<input @focus="onFocus" @blur="onBlur" @input="onInput" @change="setDisplayValue">',
    props: ['value'],
    watch: {
      value: function () {
        if (!this.focused) {
          this.setDisplayValue();
        }
      }
    },
    mounted: function () {
      this.setDisplayValue();
    },
    methods: {
      onInput: function () {
        this.$emit('input', this.parse(this.$el.value));
      },
      onFocus: function () {
        this.focused = true;
      },
      onBlur: function () {
        this.focused = false;
        this.setDisplayValue();
      },
      setDisplayValue: function () {
        this.$el.value = this.format(this.value);
      }
    }
  });
});

InputText.js

define(['js/InputCustom'], function (InputCustom) {
  return InputCustom.extend({
    methods: {
      parse: function (val) {
        val = val.trim();
        return val === '' ? null : val;
      },
      format: function (val) {
        return val === null ? '' : val;
      }
    }
  });
});

Menurut pendapat saya, pendekatan ini sangat nyaman dan saya memutuskan untuk tidak menggunakan pengubah v-model sama sekali termasuk .lazy .

Untuk kasus penggunaan yang lebih disesuaikan yang tidak dapat didukung oleh pengubah bawaan, apa yang disebutkan @ecmel adalah pendekatan yang disarankan. Kami akan mendokumentasikannya secara lebih rinci dalam panduan resmi.

Ide proposal fitur ini adalah untuk memanfaatkan direktif v-model yang ada, yang sudah bekerja dengan setiap elemen input . Untuk menyimpan pekerjaan menulis _InputCustom.js_ di setiap proyek, karena itu sudah dilakukan di v-model , hanya perlu menulis yang setara dengan _InputText.js_ di pengubah khusus, yang berisi semua logika yang perlu dimodifikasi sebagian besar kali. Fakta bahwa v-model sudah dikirimkan dengan pengubah membuktikan bahwa itu adalah pola yang intuitif dan diinginkan. Wajar untuk memfasilitasi pembuatan pengubah khusus, untuk menghemat pekerjaan membuat elemen khusus dan harus menerapkan pengikatan dom/model secara manual.

Jika masuk akal dari perspektif API, akan menarik untuk mengetahui batasan teknis apa yang mendorong keputusan untuk tidak mengimplementasikan fitur ini.

Adakah kemungkinan kita bisa membuka kembali masalah ini? Kasus penggunaan yang umum bagi saya adalah kebutuhan untuk secara otomatis memformat data dalam bidang saat sedang diketik. Sesuatu seperti mengambil '101216' dan mengubahnya menjadi '10/12/16'. Mampu membuat modifier v-model kustom akan sangat menyederhanakan kode saya karena saya bisa menulis v-model.date daripada harus membangun komponen input kustom dengan props dan event.

Setelah menggunakan vue js untuk sementara waktu sekarang di proyek saya, saya pikir masalah ini memang harus dibuka kembali.

Setidaknya kita membutuhkan pengubah undef .

Saya setuju bahwa masalah ini harus dibuka kembali. Tidak yakin apa yang seharusnya dilakukan undef , tetapi saya ingin pengubah v-model yang menyetel variabel saya ke null jika nilai input yang dipangkas adalah string kosong.

Saya ingin bisa melakukannya sendiri dengan cara yang mudah.

Fungsionalitas yang lebih berlebihan dari ini telah ditambahkan misalnya dengan https://github.com/vuejs/vue/issues/5194 . Dari luar, Vue tampaknya perlahan mengkompromikan beberapa prinsipnya demi konvensi dan praktik yang dipromosikan oleh komunitas reaksi. Sedikit menyimpang dari kualitas yang membuatnya menonjol sejak awal. Akan menarik untuk mengetahui apakah ini adalah keputusan sadar dengan maksud untuk membuat migrasi dari reaksi lebih mudah, atau hanya kebetulan.

Menulis komponen khusus baik-baik saja tetapi jika Anda ingin menggunakan komponen khusus pihak ke-3 seperti https://github.com/text-mask/text-mask/tree/master/vue#readme tidak ada cara langsung untuk membersihkan yang bertopeng masukan ke nilai model kecuali menggunakan properti yang dihitung.

Jadi, saya hanya ingin menggunakan bidang input[type=date] standar HTML untuk mengedit tipe tanggal dalam model saya dan kerangka kerja yang sangat kuat dan dapat diperluas ini tidak dapat melakukannya di luar kotak? Tidak dapat membaca tanggal ke dalam bidang, timpa tanggal saya dengan string di data saya setelah saya memilih tanggal. Solusi ini dapat ditulis dalam dua baris dengan filter dua arah atau dengan pengubah.

Tetapi solusi terbaik adalah dengan hanya mendukungnya secara asli seperti yang mereka lakukan untuk kotak centang dan bidang input standar lainnya, mengapa "tanggal" merupakan hal yang istimewa?

+1 untuk pengubah khusus. Sepertinya tidak punya otak, kecuali ada alasan bagus untuk tidak melakukannya?

Menyembunyikan input dan mengurai nilai untuk penggunaan aplikasi adalah praktik yang sangat umum, dan membuat beberapa "gula sintaksis" seperti v-model.lazy.currency="jumlah" akan luar biasa!

1+ untuk pengubah khusus.
Saya memiliki input radio sederhana dengan nilai true|false yang mengevaluasi string - Tapi saya membutuhkannya sebagai boolean - properti yang dihitung tidak akan pintar dalam kasus ini karena saya perlu mengimplementasikan kembali properti yang dihitung untuk setiap input radio. Misalnya Memiliki 100 input radio akan menghasilkan 100 properti yang dihitung

+1 untuk pengubah khusus tetapi saya setuju dengan tobei -- input[type=date] harus bekerja secara otomatis.

+1 untuk pengubah khusus.

Saya berasal dari latar belakang Angular, dan baru saja mulai dengan vue, dan melihat utas ini.

Saya merasa akan sangat membantu memiliki sesuatu seperti pengurai dan pemformat Angular, di Vue juga. Jika saya bisa melakukan sesuatu seperti v-model.dateFormat dan menghasilkan sesuatu seperti mm/dd/yyyy, itu akan sangat keren.

EDIT: sepertinya mengulangi apa yang dikatakan @ restored18 . +1 untukmu juga

+1 untuk pengubah model v khusus.

Dalam kasus saya, saya mengulang beberapa objek bersarang yang diambil di JSON, dan menggunakan satu templat HTML (bukan templat per objek). Dalam hal ini saya percaya properti yang dihitung tidak berfungsi?

Saat ini saya sedang menerapkan metode konversi khusus antara format server dan format v-model saat mengambil dan mengirim data, tetapi akan menyukai sesuatu yang "bawaan" yang dapat saya lewati fungsinya.

+1 untuk ini. Dulu tersedia sebelum 2.2. Anda dapat mengakses properti melalui,

this.$vnode.data.directives

Itu dihapus dengan penambahan nilai input model khusus, tetapi merupakan fitur yang sangat berguna dan harus kembali ke kerangka kerja.

+1 untuk ini.

Pengubah model v khusus akan sangat bagus!

saya juga

+1 di 2018 juga ...

+1 Ini adalah fitur yang diperlukan untuk kode KERING menurut saya. Saat ini saya harus membuat 10 pengamat yang melakukan hal yang sama untuk formulir dengan banyak masukan. Pengubah kustom akan menyelesaikan segalanya.

+1 Saya baru saja memulai vue dan sudah membutuhkan jenis filter dua arah ini ...

+1 pasti dibutuhkan

+1

Anda dapat membuat pembantu seperti ini untuk sebagian besar kasus penggunaan IMO

@nickmessing yang tidak mencakup kasus penggunaan (sangat berguna) yang dijelaskan di sini, yang merupakan modifikasi di tempat dari teks input. Jika Anda memiliki kotak input yang ingin selalu diformat seperti telepon, Anda akan memiliki <input v-model.phone="some_data"> . Ketika pengguna memasukkan teks, itu akan secara otomatis memformatnya.

Ini sepertinya fitur dasar dan lebih sulit dari yang seharusnya sekarang. Perilaku sudah ada dalam kerangka kerja, tetapi untuk beberapa alasan itu terbatas pada kode kerangka saja. Kami ingin dapat menambahkan pengubah kustom yang akan melakukan ini, yang dapat digunakan kembali di seluruh komponen dan proyek, seperti filter dan arahan saat ini.

@bbugh setuju sekali, saya memiliki kasus serupa dengan memformat IBAN dan itu akan menjadi cara yang bagus dan dekleratif untuk hanya memasukkan v-model.iban="payment.iban" di sana...

@franciscolourenco mungkin seseorang bisa memberikan alasan mengapa ini tidak didukung oleh kerangka kerja sehingga menjadi lebih jelas.

+1 untuk pengubah khusus, ada banyak kasus penggunaan yang dapat diselesaikan dengan fitur ini

Dalam aplikasi kami ada beberapa input berbeda untuk memformat mata uang, kami selalu menyimpan jumlah sen dalam model, tetapi menampilkan jumlah dolar yang diformat dengan baik dalam input (jadi 123456 dalam model ditampilkan sebagai $1,234.56) <input v-model.dollars="cents" />

Kasus penggunaan lainnya adalah membersihkan dan melepaskan bidang html untuk mencegah serangan XSS (Model menyimpan " A &amp; B " sementara input menunjukkan " A & B ") <input v-model.html="text" />

+1

+1

+1 untuk pengubah khusus.
Saya sangat terkejut bahwa saya tidak dapat melakukan sesuatu seperti v-model.trim.uppercase=...

+1

+1

+1

+1
Pengubah input v-model asli akan menjadi fitur yang hebat. Seperti yang disebutkan orang di sini, ada banyak kasus penggunaan. Saya membutuhkan pengubah tanggal dan mata uang untuk semua proyek yang telah saya kerjakan.

haruskah kita membuka masalah di sini? https://github.com/vuejs/rfcs

saya sudah memberi ini +1, tetapi ingin memberikan catatan untuk orang-orang yang membutuhkan sesuatu "sekarang"

sementara pengubah jauh lebih efisien, saya dapat mencapai efek yang sama menggunakan input/komponen transparan dengan bidang pengambil/penyetel yang dihitung.

saya dapat membagikan contoh jika seseorang membutuhkannya

Kami tidak menerapkan ini karena ada banyak hal yang harus dipertimbangkan dalam fitur yang tampaknya mudah ini:

  • Pengubah bawaan sebenarnya adalah petunjuk waktu kompilasi yang menghasilkan kode kompilasi yang berbeda. Pengubah kustom mungkin perlu ditentukan menggunakan konfigurasi runtime, yang merupakan mekanisme yang berbeda.

  • Untuk konfigurasi runtime, jenis API apa yang harus kami paparkan untuk ini?

  • Kami memiliki filter dua arah di masa lalu. Transformasi nilai dua arah mengharuskan pengguna untuk menerapkan logika sempurna sehingga pengikatan dua arah dapat stabil. Jika tidak, Anda berisiko menempatkan seluruh aplikasi Anda dalam loop tak terbatas untuk kasus tepi.

    • Alasan kami memiliki .number dan .trim adalah karena sebenarnya keduanya adalah transformasi satu arah (hanya diterapkan saat menyinkronkan nilai DOM ke data komponen) dan dengan demikian dijamin stabil.
  • Bagaimana seharusnya pengubah kustom berperilaku ketika v-model digunakan pada komponen?

  • Bagaimana seharusnya pengubah kustom berperilaku pada jenis input non-teks, misalnya radio , checkbox dan yang paling penting, <select> ?

Semua pertanyaan ini tidak terjawab dan membuat permintaan lebih kompleks daripada yang terlihat. Inilah mengapa saya setuju itu akan menjadi kandidat yang baik untuk RFC yang tepat yang mencakup semua ini jika ada yang benar-benar menginginkan fitur ini. Sampai saat itu, lebih banyak +1 tidak memajukannya dengan cara apa pun.

@rkingon Sudah ada contoh di https://github.com/vuejs/vue/issues/3666#issuecomment -249583603, tetapi jika milik Anda berbeda/lebih baik, posting saja. Ini bisa berguna untuk pemula.

@Gotterbild saya memang melewatkan sampel itu, tetapi ini terlalu rumit di versi Vue yang lebih baru (yang bisa menjadi dukungan komponen pra-transparan)

di sini adalah yang sangat sederhana yang saya miliki yang hanya mengubah persen menjadi desimal (yaitu: 4,5 -> .045) & sebaliknya (nilai "tampilan" dan nilai "model")

<template>
    <input type="number" v-on="listeners" v-model="innerValue">
</template>

<script>

    export default {
        props: ['value'],
        computed: {
            listeners () {
                const { input, ...listeners } = this.$listeners
                return listeners
            },
            innerValue: {
                get () {
                    return (this.value) ? `${(this.value * 100)}` : ''
                },
                set (_val) {
                    const val = (_val) ? (_val / 100) : ''
                    this.$emit('input', val)
                }
            }
        }
    }

</script>

ini lebih sederhana dari yang di atas karena Anda tidak perlu menentukan ulang semua fokus/blur/dll

@yyx990803 terima kasih telah memberikan lebih banyak informasi latar belakang tentang topik ini.

untuk kasus penggunaan saya, saya tidak "membutuhkan" pengubah khusus. hanya saja dari perspektif konsumen, masuk akal jika vue memiliki cara untuk membangunnya sendiri. pada dasarnya memiliki itu untuk semuanya, kecuali pengubah

sementara saya dapat menemukan cara untuk membuat sesuatu yang merangkum logika transformasi saya dengan benar dan yang dapat saya gunakan kembali, saya pikir memiliki API yang tepat untuk kasus penggunaan semacam itu akan membuka cara yang lebih luas untuk berbagi kode umum melalui kumpulan "terbaik- berlatih pengubah".

Saya datang ke sini karena saya ingin membuat pengubah untuk mengubah string menjadi huruf besar
Saya ingin membuatnya seperti v-model.uppercase="username"

Saya akhirnya menggunakan arahan khusus

Vue.directive('uppercase', {
    update (el) {
        el.value = el.value.toUpperCase()
    },
})

<input type="text" v-model="username" v-uppercase>

Arahan khusus harus cukup untuk alternatif.
Atau adakah sesuatu yang hanya mungkin dilakukan dengan modifier v-model khusus?

@Christhofernatalius mempertimbangkan v-model hanyalah arahan, tidak bisakah Anda menghilangkan v-model demi arahan khusus? dengan cara ini Anda tidak memperbarui dua kali?

@Christhofernatalius mempertimbangkan v-model hanyalah arahan, tidak bisakah Anda menghilangkan v-model demi arahan khusus? dengan cara ini Anda tidak memperbarui dua kali?

@rkingon Apakah ini memperbarui dua kali?
Jadi, jika saya tidak menggunakan v-model, maka saya juga perlu menambahkan kait pengikat dan pelepasan ikatan untuk pendengar input, dan memperbarui nilai nama pengguna?

EDIT: Bukankah menggunakan computed dengan setter dan getter juga memperbarui dua kali?
EDIT 2: Saya mencoba konsol log pengamat dan arahan, masing-masing hanya mencetak satu kali untuk setiap penekanan tombol.

saya belum mencobanya, hanya spekulasi -- saya kira gagasan dua arahan untuk memperbarui satu nilai terasa agak lucu bagi saya, tetapi jika Anda sudah memeriksanya, saya tidak melihat ada yang salah dengan itu.

solusi komponen saya juga memiliki keterbatasan, itulah sebabnya saya masih mendukung pengubah -- yaitu: memerlukan elemen, lebih banyak waktu rendering, & hanya berfungsi sebagai komponen dalam cara komponen itu didefinisikan (yaitu: bidang input ) vs bahkan hanya dapat menggunakannya pada beberapa komponen/elemen arbitrer yang merupakan kekuatan arahan.

dua cara menguliti kucing, senang punya pilihan :)

Apakah ada RFC untuk ini?

saya tidak berpikir begitu

Saya bisa membuatnya tetapi apakah itu hanya berarti menambahkan masalah di repo RFC itu atau yang lainnya?

https://github.com/vuejs/rfcs#what -the-process-is apakah ini menjawab pertanyaan Anda?

Tolong ini bisa dibuka kembali? Arahan khusus dapat berfungsi dalam beberapa kasus tetapi perilakunya bisa lucu, contoh:

Vue.directive('number', {
  update: function(el, binding, vnode) {
    el.value = el.value.replace(/[^\d.]/g, '');
  },
});

Jika Anda menambahkan arahan ini (bersama dengan v-model) dan mengetik huruf dengan sangat cepat setiap penekanan tombol lainnya, v-model akan menjadi tidak sinkron dengan el.value . Dan karena Anda tidak dapat memodifikasi objek pengikatan yang Anda terima, tidak ada cara untuk "mengimplementasikan kembali" model-v di dalam arahan ini

@jeankvd Saya tahu rasanya berlebihan, tetapi komponen pembungkus akan menjadi yang paling dapat diandalkan (lihat contoh di atas).

komponen pembungkus akan memungkinkan Anda untuk "melakukan lebih banyak" juga. Dalam contoh "angka" Anda, idealnya, v-model sebenarnya menjadi Number . Dalam pendekatan Anda, ini masih String .

Bagaimana jika Anda ingin menyesuaikan nilai kosong? Tali Kosong? Batal? Tidak terdefinisi? -- Anda dapat memasukkan prop untuk emptyValue dan mengaturnya seperti itu.

Sementara pernah menjadi pendukung untuk ini, saya menyadari segera setelah pengubah memiliki terlalu banyak keterbatasan dan hanya memiliki komponen yang jauh lebih unggul (setidaknya imo).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

paulpflug picture paulpflug  ·  3Komentar

lmnsg picture lmnsg  ·  3Komentar

hiendv picture hiendv  ·  3Komentar

aviggngyv picture aviggngyv  ·  3Komentar

6pm picture 6pm  ·  3Komentar