Memahami Mixins Pada Vue JS - CRUDPRO

Memahami Mixins Pada Vue JS

Memahami Mixins Pada Vue JS

Mixin di Vue.JS menempati sedikit area abu-abu dari fungsionalitas menengah hingga lanjutan. Sedikit seperti komponen, dipisahkan dari iterasinya sendiri, berguna untuk mempertahankan kode KERING (jangan ulangi-sendiri); tetapi tidak cukup perbedaan kasus penggunaan yang tersedia dari manajemen negara, atau bahkan hanya filter yang tepat, dan dengan gotcha yang cukup untuk membuat banyak pengembang berpikir dua kali untuk menggunakannya.

Perhatikan bahwa saya merujuk, di sini, untuk mixin secara khusus di mixin Vue/React, mixin untuk sintaks kelas ES6, dll., merupakan binatang yang berbeda sama sekali.

Untuk menjelaskan utilitas dan keterbatasan mixin Vue, kami akan membuat demo kecil. Harapan saya demo ini akan melukiskan gambaran yang cukup jelas, dengan garis demarkasi yang cukup jelas tersirat antara kapan Anda harus (atau dapat) atau tidak boleh menggunakan mixin Vue, sementara juga memberikan beberapa latihan untuk keluar dari gerbang dengan cepat alur kerja proyek vue-cli.

Tanpa basa-basi,

Untuk proyek ini, Anda memerlukan yang berikut ini:

  • NodeJS — pastikan untuk mengunduh versi berlabel “Direkomendasikan untuk sebagian besar pengguna”
  • npm — manajer paket node akan menginstal dengan instalasi NodeJS di atas; jangan ragu untuk menggunakan manajer paket alternatif jika Anda ingin

Dan kami akan menggunakan (setelah kami menginstalnya dengan npm):

  • VueJS — kami akan menggunakan sejumlah teknik dan sintaks khusus vue yang akan saya lakukan sebaik mungkin untuk mengklarifikasinya saat kami melanjutkan (meskipun ini bukan pelajaran di Vue, per se); jika Anda tidak terbiasa dengan Vue, saya sangat menganjurkan Anda untuk memeriksa dokumen luar biasa mereka
  • Vue-cli — Antarmuka baris perintah Vue yang akan memungkinkan kita untuk dengan cepat menyusun proyek Vue boilerplate

Dan itu saja!

Untuk memulai, unduh dan instal NodeJS dari tautan di atas. Kemudian, buka jendela terminal favorit Anda dan arahkan ke direktori tempat Anda ingin folder proyek Anda dibuat.

Gunakan perintah berikut untuk menginstal vue-cli:

npm install -g @vue/cli

npm mendeklarasikan perintah manajer paket node, install adalah perintah khusus konteks yang kita jalankan, -g adalah pengubah yang akan menyebabkan instalasi kita menjadi global (di seluruh mesin kita, bukan direktori saat ini), dan @ vue-cli adalah paket yang sedang diinstal.

Ini akan memungkinkan Anda untuk memulai perintah yang dimulai dengan vue. Sekarang untuk membangun folder proyek kami, di jendela terminal yang sama, masukkan:

vue create vue-mixins-demo

Ini mengeksekusi perintah vue, create, yang akan membuat folder proyek boilerplate untuk proyek berjudul "vue-mixins-demo." Cukup tekan "enter" untuk memilih semua default saat diminta dengan satu atau dua pertanyaan selama proses pembuatan. Anda sekarang seharusnya dapat melihat folder proyek “vue-mixins-demo” di direktori Anda saat ini, dan dapat membukanya di editor teks atau IDE pilihan Anda.

Masih di jendela terminal yang sama (jangan panik jika Anda menutupnya, cukup buka yang baru dan navigasikan ke direktori yang sama yang berisi folder proyek Anda lagi), kami menavigasi ke folder proyek kami dengan:

cd vue-mixins-demo

dan ikuti perintah itu dengan:

npm run serve

yang akan mengkompilasi build pengembangan hot-reload untuk kita. Dengan kata lain, ketika proses ini selesai, Anda akan melihat sesuatu seperti ini di terminal Anda:

Memahami Mixins Pada Vue JS

Saya sekarang dapat membuka jendela browser dan mengetikkan alamat lokal itu, localhost:8080, untuk melihat aplikasi Vue saya beraksi. Selain itu, setiap perubahan yang kami buat dalam kode kami akan tercermin dalam aplikasi langsung ini segera setelah disimpan.

Sekarang kita siap untuk mulai menulis beberapa kode.

Apa yang akan kita bangun adalah aplikasi web kecil yang menampilkan daftar semua pengguna yang dapat diurutkan sepenuhnya, serta daftar pengguna aktif dan daftar pengguna tidak aktif (tentu saja menggunakan data dummy). Data pengguna yang dimaksud:

users: [
{
name: "Nurdan Çağıran",
age: 23,
status: 0,
created: "2018-09-22",
image: "https://randomuser.me/api/portraits/thumb/women/31.jpg"
},
{
name: "Julien Morin",
age: 27,
status: 1,
created: "2018-10-18",
image: "https://randomuser.me/api/portraits/thumb/men/67.jpg"
},
{
name: "Herma Rabe",
age: 33,
status: 1,
created: "2018-04-20",
image: "https://randomuser.me/api/portraits/thumb/women/82.jpg"
},
{
name: "Eva Flores",
age: 28,
status: 0,
created: "2018-11-21",
image: "https://randomuser.me/api/portraits/thumb/women/4.jpg"
},
{
name: "Benedikte Urdal",
age: 32,
status: 0,
created: "2018-09-24",
image: "https://randomuser.me/api/portraits/thumb/women/63.jpg"
},
{
name: "Toby Taylor",
age: 25,
status: 1,
created: "2018-08-27",
image: "https://randomuser.me/api/portraits/thumb/men/58.jpg"
},
{
name: "حامد کوتی",
age: 27,
status: 1,
created: "2018-04-17",
image: "https://randomuser.me/api/portraits/thumb/men/91.jpg"
},
{
name: "Tammy Mendoza",
age: 31,
status: 0,
created: "2018-05-13",
image: "https://randomuser.me/api/portraits/thumb/women/72.jpg"
},
{
name: "Kathy Gordon",
age: 31,
status: 1,
created: "2018-04-23",
image: "https://randomuser.me/api/portraits/thumb/women/44.jpg"
},
{
name: "Tristan Nielsen",
age: 30,
status: 1,
created: "2018-01-18",
image: "https://randomuser.me/api/portraits/thumb/men/2.jpg"
},
{
name: "Lilja Wallo",
age: 30,
status: 1,
created: "2018-01-21",
image: "https://randomuser.me/api/portraits/thumb/women/79.jpg"
},
{
name: "Russell Grant",
age: 33,
status: 0,
created: "2018-09-26",
image: "https://randomuser.me/api/portraits/thumb/men/55.jpg"
}
]

Semua data telah dihasilkan secara acak dari Random User API (lebih lanjut tentang itu, dan menukar data statis untuk data yang diambil dari API, menjelang akhir).

Sebagai permulaan, hapus komponen HelloWorld dari kode boilerplate, dan hapus semua referensi dari file App.vue Anda. Bahkan, ganti semua konten file App.vue Anda dengan yang berikut ini:

<template>
  <div id="app">
    <div class="users">
      <AllUsers />
      <Active />
      <Inactive />
    </div>
  </div>
</template>

<script>
  import AllUsers from "./components/AllUsers.vue";
  import Active from "./components/Active.vue";
  import Inactive from "./components/Inactive.vue";
  export default {
    name: "app",
    components: {
      AllUsers,
      Active,
      Inactive
    }
  };
</script>

<style>
  * {
    box-sizing: border-box;
  }
  .users > * {
    float: left;
    width: 46%;
    padding: 1rem 3rem;
    margin: 0 2%;
    text-align: left;
    border: 0.5px solid #ccc;
  }
  #app {
    font-family: "Avenir", Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>

Seperti yang Anda lihat, kami akan merender tiga komponen baru di tampilan Aplikasi kami. Mari kita buat file untuk semua komponen kita sekarang, jadi aplikasi kita tidak crash saat kita membuat perubahan. Buat file AllUsers.vue, Active.vue, Inactive.vue, dan User.vue di folder komponen proyek Anda.

Komponen Pengguna

Kode untuk komponen Pengguna adalah sebagai berikut:

<template>
    <li>
        <img 
            :src="user.image" 
            :alt="user.name">
        <h4>{{user.name}}</h4>
        <div :class="{ 'active': user.status == 1, 'inactive': user.status == 0 }"></div>
        <span>Age: {{user.age}}</span>
        <span>Created: {{ user.created }}</span>
    </li> 
</template>

<script>
  export default {
    props: ["user"]
  };
</script>

<style scoped>
  li {
    padding: 1rem;
    border: 0.5px solid #ccc;
  }
  li img {
    border-radius: 50%;
    width: 3rem;
    float: left;
    margin-right: 1rem;
  }
  li h4 {
    margin: 0 0 0.5rem 0;
  }
  li p {
    margin: 0;
  }
  li span {
    display: inline-block;
    width: 40%;
  }
  div.active,
  div.inactive {
    width: 1rem;
    height: 1rem;
    float: right;
    border-radius: 50%;
  }
  div.active {
    background-color: green;
  }
  div.inactive {
    background-color: red;
  }
</style>

Saat ini, demi kenyamanan, saya telah menyertakan gaya (ini bukan pelajaran CSS). Perhatikan properti "alat peraga" di blok skrip. Ini menyiapkan komponen Pengguna ini untuk menerima semacam prop data yang disebut "pengguna" dari induknya saat dirender. Karena kita sudah tahu seperti apa objek "pengguna", kita dapat dengan aman memperkirakan informasi apa yang akan kita ekstrak dari objek itu dan bagaimana caranya.

Inilah yang menginformasikan pengikatan data di markup template ("nama pengguna", "pengguna.status", dll.). Perhatikan bahwa v-bind adalah satu-satunya direktif vue yang ditampilkan di sini saat ini.

Dalam kasus div pada baris 7, atribut kelasnya telah diikat sedemikian rupa sehingga div akan menerima kelas "aktif" atau "tidak aktif" berdasarkan nilai properti "status" dari "penggunanya". ” objek (jika statusnya 1, pengguna aktif; jika statusnya 0, pengguna tidak aktif).

Komponen Pengguna ini akan menampilkan informasi untuk satu pengguna, dan akan direplikasi untuk menampilkan beberapa pengguna.

Komponen Semua Pengguna

Sekarang, mari kita siapkan komponen induknya, AllUsers:

<template>
  <div>
    <h2>All Users</h2>
    <ul>
        <User 
            v-for="(user, index) in users"
            :key="index"
            :user="user" />
    </ul>
  </div>
</template>

<script>
  import User from "./User.vue";
  export default {
    data() {
      return {
        users: [
          {
            name: "Nurdan Çağıran",
            age: 23,
            status: 0,
            created: "2018-09-22",
            image: "https://randomuser.me/api/portraits/thumb/women/31.jpg"
          }, 
          {...}, 
          {...}
        ]
      };
    },
    components: {
      User
    }
  };
</script>

<style scoped>
  h3 {
    margin: 40px 0 0;
  }
  ul {
    list-style-type: none;
    padding: 0;
  }
  ul li {
    display: block;
  }
  li {
    display: inline-block;
    margin: 0 10px;
  }
  .radio-btns {
    padding-bottom: 1rem;
  }
  .radio-btn-filter {
    display: inline-block;
    padding-right: 0.5rem;
  }
</style>

Sekali lagi, penataan gaya telah disertakan untuk kenyamanan (dan pastikan untuk menempelkan larik pengguna dari atas sebagai pengganti larik tiruan ini di properti users dari objek data di komponen ini!).

Selain div yang berisi dan h2, semua yang kita miliki adalah unordered-list yang berisi satu template dari komponen User kita (yang akan membuat daftar-item dengan informasi pengguna tunggal, ingat), di mana kita telah menggunakan v- untuk direktif untuk menduplikasi komponen ini sebanyak ada objek "pengguna" di larik "pengguna" kami di data komponen ini. Jadi kita harus berakhir dengan 12 komponen Pengguna, satu untuk setiap pengguna.

Perhatikan baris 8, di mana atribut "pengguna" terikat dengan nilai "pengguna". Ini bisa membingungkan jika Anda tidak terbiasa dengan pengikatan data Vue. ":" menunjukkan direktif v-bind, dan "pengguna" yang segera mengikuti (nama atribut) berfungsi sebagai nama properti data yang diteruskan ke komponen ini. "Pengguna" di sisi berlawanan dari tanda sama dengan adalah objek pengguna individu yang ditarik dari larik "pengguna". Dengan cara ini, kami melewatkan satu objek pengguna yang berbeda sebagai penyangga "pengguna" ke setiap komponen Pengguna (wah). Ini adalah bagaimana komponen Pengguna memahami objek mana untuk menarik nama pengguna, usia, status, dan informasi yang dibuat.

Menyortir Pengguna

Sekarang Anda harus memiliki aplikasi fungsional yang menunjukkan sesuatu seperti ini:

Memahami Mixins Pada Vue JS

Sejauh ini bagus, tapi mari tambahkan beberapa fungsi penyortiran. Untuk ini, kita memerlukan beberapa markup baru, metode, dan beberapa properti yang dihitung.

<template>
  <div>
    <h2>All Users</h2>
    <div class="radio-btns">
        <p>Sort by:</p>
        <div 
            class="radio-btn-filter"
            v-for="(prop, index) in userProperties"
            v-if="prop != 'image'"
            :key="index">
            <input 
                type="radio"
                :id="prop"
                :value="prop"
                v-model="sortCriteria">
            <label 
                :for="prop">{{ prop }}</label>
        </div>
    </div>
    <ul>
        <User 
            v-for="(user, index) in sortedUsers"
            :key="index"
            :user="user" />
    </ul>
  </div>
</template>

<script>
  import User from "./User.vue";
  export default {
    data() {
      return {
        sortCriteria: '',
        users: [
          {
            name: "Nurdan Çağıran",
            age: 23,
            status: 0,
            created: "2018-09-22",
            image: "https://randomuser.me/api/portraits/thumb/women/31.jpg"
          }, 
          {...}, 
          {...}
        ]
      };
    },
    components: {
      User
    },
    methods: {
      sort_by(users, sortProp) {
        return users.sort(function(a, b) {
          if (a[sortProp] > b[sortProp]) return 1;
          if (a[sortProp] < b[sortProp]) return -1;
          return 0;
        });
      }
    },
    computed: {
      sortedUsers() {
        if (!this.sortCriteria) {
          this.sortCriteria = "created_at";
        }
        return this.sort_by(this.users, this.sortCriteria);
      },
      userProperties() {
        let arr = [];
        for (let prop in this.users[0]) {
          arr.push(prop);
        }
        return arr;
      }
    }
  };
</script>

Kami telah menambahkan tombol radio yang dapat diklik yang nilainya terikat pada properti yang dibagikan oleh objek pengguna kami (nama, usia, status, dibuat, gambar). Properti yang dihitung, userProperties, mengekstrak semua properti dari objek pengguna, dan loop v-for merender tombol radio dan label sebanyak properti ekstrak userProperties (dengan satu v-if untuk memastikan kita tidak merender tombol radio berlabel “ image”, karena tidak masuk akal untuk mencoba mengurutkan pengguna berdasarkan URL gambar mereka). Nilai tombol radio kami juga terikat ke kunci data baru, sortCriteria. Jika pengguna mengklik tombol radio "usia", nilai sortCriteria akan disetel ke "usia", dll.

Kami juga telah menambahkan metode sort_by dasar yang mengurutkan array berdasarkan properti tertentu (misalnya menurut abjad berdasarkan nama, atau secara numerik menurut tanggal).

Lalu ada properti komputer sortCriteria, yang mengembalikan array pengguna kami yang diurutkan menurut titik data sortCriteria baru (yang dibiarkan kosong jika tidak ada tombol radio yang dicentang), dengan memanggil metode sort_by dan memasukkan data pengguna dan sortCriteria sebagai argumen.

Yang terpenting, kami telah memperbarui loop v-for yang membuat komponen Pengguna kami menarik dari data yang diurutkan Pengguna daripada larik pengguna awal. Dengan cara ini, urutan komponen Pengguna yang dirender pada halaman akan bereaksi terhadap perubahan apa pun pada properti sortUsers, yang akan berubah secara reaktif setiap kali ada data yang dipantaunya mengalami perubahan (seperti sortCriteria, saat pengguna mengklik tombol radio ).

Dan seperti itu, kami memiliki daftar pengguna yang dapat diurutkan yang akan terlihat seperti ini:

Memahami Mixins Pada Vue JS
Komponen Aktif dan Tidak Aktif

Sekarang mari kita buat dua komponen baru, Active.vue dan Inactive.vue, yang akan membuat daftar pengguna aktif versus tidak aktif (pengguna dengan status 1 akan dianggap aktif, dan pengguna dengan status 0 akan dianggap tidak aktif).

Namun, karena kami ingin daftar pengguna aktif dan tidak aktif terpotong, kami tidak akan merender komponen Pengguna di dalam daftar ini. Mereka akan lebih referensial dibandingkan dengan daftar AllUsers yang lebih komprehensif.

Komponen-komponen ini akan terlihat seperti ini:

<template>
  <div>
    <h2>Active Users</h2>
    <ul>
      <li>
        <span><strong>NAME</strong></span>
        <span><strong>CREATED</strong></span>
        </li>
      <li 
        v-for="(user, index) in sortedUsers"
        :key="index">
        <span>{{user.name}}</span>
        <span>{{user.created}}</span>
      </li> 
    </ul>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        status: 1,
        users: [
          {
            name: "Nurdan Çağıran",
            age: 23,
            status: 0,
            created: "2018-09-22",
            image: "https://randomuser.me/api/portraits/thumb/women/31.jpg"
          }, 
          {...}, 
          {...}
        ]
      };
    },
    methods: {
      filter_active_inactive() {
        if (this.status != null) {
          var status = this.status;
          return this.users.filter(function(users) {
            return users.status == status;
          });
        } else {
          return this.users;
        }
      },
      sort_by(users, sortProp) {
        return users.sort(function(a, b) {
          if (a[sortProp] > b[sortProp]) return 1;
          if (a[sortProp] < b[sortProp]) return -1;
          return 0;
        });
      }
    },
    computed: {
      sortedUsers() {
        if (!this.sortCriteria) {
          this.sortCriteria = "created_at";
        }
        return this.sort_by(this.filter_active_inactive(), this.sortCriteria);
      }
    }
  };
</script>

<style scoped>
  div {
    margin-bottom: 2rem;
    border: 0.5px solid #ccc;
  }
  ul {
    list-style-type: none;
    padding: 0;
  }
  ul li {
    display: block;
    margin: 0 10px;
  }
  ul li:first-child {
    margin-bottom: 0.5rem;
  }
  ul li span {
    display: inline-block;
    width: 50%;
    padding: 0.1rem 0;
  }
</style>

Selain membawa data pengguna yang sama, metode sort_by, dan properti komputer yang diurutkan Pengguna ke dalam komponen ini, kami telah membuat kunci data baru yang disebut "status" yang akan digunakan untuk menunjukkan apakah pengguna yang akan ditampilkan dalam komponen ini aktif atau tidak aktif, dan kami telah membuat metode baru, filter_active_inactive yang menggunakan kunci "status" sebagai mekanisme filter untuk memisahkan larik pengguna ke HANYA pengguna aktif dan kami menggunakan larik pengguna kembali yang difilter sebagai argumen dalam metode sort_by di properti sortUsers komponen ini.

Anda dapat menduplikasi komponen ini seluruhnya, sambil mengalihkan properti status ke 0 dan judul dari "Pengguna Aktif" menjadi "Pengguna Tidak Aktif" untuk tiba dengan aman di komponen Aktif dan Tidak Aktif.

Memahami Mixins Pada Vue JS

Jadi ada beberapa hal baru di sini; pada saat yang sama, dibandingkan dengan AllUsers.vue, ada BANYAK barang lama. Ada banyak kode berulang dan bahkan fungsi berulang. Di sinilah keuntungan mixin akhirnya berperan.

Mixin, pada akhirnya

Apa yang dapat kita lakukan dengan mixin adalah mengurangi kode yang berulang dan berlebihan, dan secara dramatis membersihkan beberapa komponen kita dalam prosesnya. Intinya, kita akan memisahkan data dan fungsionalitas yang berulang, meskipun akan ada beberapa gotcha yang harus diperhatikan yang akan saya bahas nanti.

Di folder "src" proyek Anda, buat folder baru bernama "mixins," dan di dalam folder ini buat file bernama "filterUsers.js." Dalam file ini, kami hanya akan mengumpulkan semua kode redundan yang diulang antara komponen AllUsers, Active, dan Inactive kami:

export const filterUsers = {
  data() {
    return {
      sortCriteria: "",
      users: [
          {
            name: "Nurdan Çağıran",
            age: 23,
            status: 0,
            created: "2018-09-22",
            image: "https://randomuser.me/api/portraits/thumb/women/31.jpg"
          }, 
          {...}, 
          {...}
        ]
    };
  },
  methods: {
    filter_active_inactive() {
      if (this.status != null) {
        var status = this.status;
        return this.users.filter(function(users) {
          return users.status == status;
        });
      } else {
        return this.users;
      }
    },
    sort_by(users, sortProp) {
      return users.sort(function(a, b) {
        if (a[sortProp] > b[sortProp]) return 1;
        if (a[sortProp] < b[sortProp]) return -1;
        return 0;
      });
    }
  },
  computed: {
    sortedUsers() {
      if (!this.sortCriteria) {
        this.sortCriteria = "created_at";
      }
      return this.sort_by(this.filter_active_inactive(), this.sortCriteria);
    },
    userProperties() {
      let arr = [];
      for (let prop in this.users[0]) {
        arr.push(prop);
      }
      return arr;
    }
  }
};

(sekali lagi, jangan lupa untuk mengganti data pengguna dummy yang dipersingkat dengan array pengguna lengkap dari atas)

Kami telah menggabungkan semua kode yang berlebihan menjadi satu konstanta yang kami ekspor. Kami dapat mengimpor ini ke file komponen kami dan menggabungkan semua data ini dengan data komponen kami tanpa konflik apa pun.

Sekarang mari kita KERING kode komponen kita yang lain:

<template>
  <div>
    <h2>Inactive Users</h2>
    <ul>
      <li>
        <span><strong>NAME</strong></span>
        <span><strong>CREATED</strong></span>
        </li>
      <li 
        v-for="(user, index) in sortedUsers"
        :key="index">
        <span>{{user.name}}</span>
        <span>{{user.created}}</span>
      </li> 
    </ul>
  </div>
</template>

<script>
  import { filterUsers } from "./../mixins/filterUsers.js";

  export default {
    mixins: [filterUsers],
    data() {
      return {
        status: 0
      };
    }
  };
</script>
<template>
  <div>
    <h2>All Users</h2>
    <div class="radio-btns">
        <p>Sort by:</p>
        <div 
            class="radio-btn-filter"
            v-for="(prop, index) in userProperties"
            v-if="prop != 'image'"
            :key="index">
            <input 
                type="radio"
                :id="prop"
                :value="prop"
                v-model="sortCriteria">
            <label 
                :for="prop">{{ prop }}</label>
        </div>
    </div>
    <hr>
    <ul>
        <User 
            v-for="(user, index) in sortedUsers"
            :key="index"
            :user="user" />
    </ul>
  </div>
</template>

<script>
  import User from "./User.vue";
  import { filterUsers } from "./../mixins/filterUsers.js";

  export default {
    mixins: [filterUsers],
    data() {
      return {
        status: null
      };
    },
    components: {
      User
    }
  };
</script>

Seperti yang Anda lihat, semua data pengguna yang berulang, metode yang berulang, dan properti komputer, telah sepenuhnya dihapus (saya bahkan memindahkan properti komputer properti pengguna ke dalam file mixin, meskipun itu hanya digunakan oleh satu komponen; secara fungsional, itu hanya membuat akal bagi saya).

Kami kemudian mengimpor { filterUsers } ke setiap komponen yang memerlukan fungsionalitas yang terkandung di dalamnya (AllUsers, Active, dan Inactive), dan cukup mendeklarasikannya di dalam objek Vue yang diekspor oleh komponen kami masing-masing dengan baris 23 atau 35 dalam file di atas (catatan , properti "mixin" dari komponen Vue akan selalu berisi array!).

Metode dan properti terkomputasi kami dalam file mixin berisi pernyataan if yang akan memastikan aplikasi tidak menimbulkan kesalahan jika bagian tertentu dari teka-teki tidak ada di sisi komponen (AllUsers tidak berisi properti status, dan Aktif dan Tidak Aktif tidak berisi properti sortCriteria; lihat baris 20 dan 39 di file filterUsers.js. Dengan cara ini kami telah membuat kode mixin kami yang jauh lebih tahan terhadap bug yang tidak terduga dan jauh lebih mudah beradaptasi untuk digunakan dalam berbagai kasus penggunaan komponen.

Ketiga komponen yang menggunakan mixin ini merender konten berdasarkan data pengguna yang sama, dan ketiganya memiliki akses ke metode dan properti terkomputasi yang sama yang akan diulang di seluruh aplikasi kita dan secara dramatis mengacaukan file komponen itu sendiri. Dan aplikasi kami terus bekerja seperti yang diharapkan tanpa henti!

Lihat kode lengkapnya di sini.

Gotcha

Seperti yang saya sebutkan, ada beberapa gotcha yang perlu diingat dengan mixin Vue.

Yang pertama, dan paling mudah diakses, adalah, saat menggunakan mixin di komponen Anda, komponen Anda akan selalu memiliki keputusan akhir. Yang saya maksud adalah, arsitektur internal komponen Anda sendiri akan memuat SETELAH konten mixin, yang berarti komponen Anda akan dilengkapi untuk menulis ulang data, metode, properti, atau lainnya yang terkandung di dalam file mixin. Ini masuk akal dari hampir semua perspektif, tetapi saya tidak ingin ada yang membuat kesalahan dengan berpikir bahwa menggabungkan mixin untuk menulis ulang data komponen dalam kasus penggunaan ini dan itu akan berhasil. Ini tidak akan terjadi.

Yang kedua membutuhkan pemahaman yang jelas bahwa, untuk setiap komponen yang digabungkan dengan mixin tertentu, duplikat kode mixin itu dibuat. Meskipun mixin memungkinkan kami sebagai pengembang untuk menulis lebih sedikit kode, atau untuk membersihkan beberapa file komponen kami, mixin tidak berfungsi sebagai sumber data terpadu untuk setiap komponen yang digunakan. Kode di dalam file mixin itu diduplikasi di mana pun Anda memilih untuk memasukkannya ke dalam aplikasi Anda.

Ini bukan masalah tersendiri, tentu saja, tetapi tentu saja sesuatu yang penting untuk dipahami.

Untuk membuatnya lebih jelas dalam hal aplikasi yang baru saja kita buat, katakanlah Anda ingin membangun fitur untuk mengubah status pengguna dari aktif menjadi tidak aktif di dalam daftar AllUsers. Itu akan cukup mudah dilakukan dengan metode yang dapat Anda sertakan di komponen AllUsers atau di dalam mixin filterUsers. Metode ini mungkin akan mengubah status pengguna tertentu di dalam array pengguna dalam data, yang akan menyebabkan properti yang dikomputasi sortUsers diperbarui untuk mencerminkan data baru. Namun, data yang diperbarui ini hanya akan tercermin di dalam komponen tempat metode dieksekusi. Kami hanya akan melihat perubahan status pengguna di dalam komponen AllUsers. Kami tidak akan melihat pengguna melompat dari daftar Tidak Aktif ke daftar Aktif seperti yang Anda harapkan.

Alasannya adalah karena data pengguna telah diduplikasi di mana-mana mixin dimasukkan. Data pengguna di komponen Aktif dan Tidak Aktif tidak akan mencerminkan perubahan yang dijalankan di AllUsers.

Ini sangat penting. Untuk mencerminkan perubahan di tempat lain, beberapa bahkan masih perlu dipancarkan atau beberapa keadaan diubah.

Ini bahkan lebih penting ketika mempertimbangkan untuk mengambil data pengguna itu dari API, daripada mengkodekannya secara keras. Itu pendekatan yang sangat layak (dan bahkan direkomendasikan), tetapi saya harus mengingatkan Anda bahwa data pengguna ini diambil dari Random User API. Jika kami menjalankan pengambilan ke API Pengguna Acak untuk mengambil dua belas pengguna di mana pun kode mixin ini dijalankan, itu akan membentuk tiga panggilan API yang berbeda.

Kami akan memuat tiga daftar pengguna yang sama sekali berbeda. Satu untuk AllUsers, satu untuk Aktif, dan satu untuk Tidak Aktif.

Pada kenyataannya, Anda biasanya tidak akan mengandalkan data pengguna yang diacak, jadi itu tidak selalu menjadi masalah; tetapi Anda masih akan melakukan tiga panggilan API untuk menerima informasi identik yang sama.

Namun, ini adalah masalah yang cukup mudah untuk dipecahkan. Hapus pengguna dari mixin sama sekali, dan lipat mereka (atau satu panggilan API untuk mengambilnya), ke tampilan induk, App.vue, dan cukup berikan mereka ke tiga komponen anak sebagai penyangga. Pasang kembali tombol radio di AllUsers.vue untuk memancarkan peristiwa yang didengarkan di induknya, dan menjalankan pembaruan ke daftar pengguna. Perubahan itu akan mengalir ke bawah melalui anak-anak yang menerima data itu sebagai penyangga.

Tapi itu akan membutuhkan retooling yang signifikan dari mixin kami, atau bahkan membuatnya hampir seluruhnya berlebihan.

Mengapa Anda tidak mencobanya dan melihatnya?

Jadi, bisakah mixin Vue bermanfaat? Tentu saja, tetapi mereka membutuhkan perencanaan dan pemahaman tentang keterbatasan mereka. Apakah ini adalah akhir dari semua, menjadi semua fitur Vue yang keren? Sama sekali tidak, tetapi selalu membantu untuk mengetahui cara MENGERINGKAN kode Anda dalam keadaan darurat.

Namun saya akan bertaruh bahwa lebih sering daripada tidak, kebutuhan akan mixin menunjukkan bahwa mungkin ada solusi yang lebih elegan atau lebih kuat di luar sana.