{"id":29440010,"url":"https://github.com/fadiladz/lab11web-vuejs","last_synced_at":"2026-05-02T18:33:22.944Z","repository":{"id":303422015,"uuid":"1014702616","full_name":"FadilAdz/Lab11Web-VueJS","owner":"FadilAdz","description":"Lab11Web adalah aplikasi web lengkap berbasis CodeIgniter 4 untuk mengelola data Artikel (CRUD, paging, pencarian, upload gambar) dengan autentikasi (login/logout, session, filter akses). ","archived":false,"fork":false,"pushed_at":"2025-07-07T14:03:32.000Z","size":5564,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-07T15:22:36.818Z","etag":null,"topics":["api-rest","axios-vue","codeigniter","mysql","vuejs"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FadilAdz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-06T08:40:49.000Z","updated_at":"2025-07-07T14:03:36.000Z","dependencies_parsed_at":"2025-07-07T15:33:48.455Z","dependency_job_id":null,"html_url":"https://github.com/FadilAdz/Lab11Web-VueJS","commit_stats":null,"previous_names":["fadiladz/lab11web-vuejs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/FadilAdz/Lab11Web-VueJS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FadilAdz%2FLab11Web-VueJS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FadilAdz%2FLab11Web-VueJS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FadilAdz%2FLab11Web-VueJS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FadilAdz%2FLab11Web-VueJS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FadilAdz","download_url":"https://codeload.github.com/FadilAdz/Lab11Web-VueJS/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FadilAdz%2FLab11Web-VueJS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279058286,"owners_count":26094844,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-rest","axios-vue","codeigniter","mysql","vuejs"],"created_at":"2025-07-13T10:01:51.846Z","updated_at":"2025-10-15T06:24:54.831Z","avatar_url":"https://github.com/FadilAdz.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lab11Web \u0026 VueJS\nLab11Web adalah aplikasi web lengkap berbasis CodeIgniter 4 untuk mengelola data Artikel (CRUD, paging, pencarian, upload gambar) dengan autentikasi (login/logout, session, filter akses). Front‑end-nya dibangun sebagai SPA sederhana menggunakan Vue.js file index.html memuat struktur tampilan dan modal form, app.js mengurus pengambilan (axios.get), penambahan (axios.post), pengubahan (axios.put) dan penghapusan (axios.delete) data Artikel secara dinamis serta style.css untuk styling responsif dan modal yang menarik.\n\n\u003cbr\u003e\n\n# $${\\color{lightblue}Teknologi Yang Digunakan}$$\n![Code-Igniter](https://img.shields.io/badge/CodeIgniter-%23EF4223.svg?style=for-the-badge\u0026logo=codeIgniter\u0026logoColor=white) ![Vue.js](https://img.shields.io/badge/vuejs-%2335495e.svg?style=for-the-badge\u0026logo=vuedotjs\u0026logoColor=%234FC08D) ![Postman](https://img.shields.io/badge/Postman-FF6C37?style=for-the-badge\u0026logo=postman\u0026logoColor=white) ![MySQL](https://img.shields.io/badge/mysql-4479A1.svg?style=for-the-badge\u0026logo=mysql\u0026logoColor=white) ![PHP](https://img.shields.io/badge/php-%23777BB4.svg?style=for-the-badge\u0026logo=php\u0026logoColor=white) ![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge\u0026logo=html5\u0026logoColor=white) ![CSS3](https://img.shields.io/badge/css3-%231572B6.svg?style=for-the-badge\u0026logo=css3\u0026logoColor=white) ![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge\u0026logo=javascript\u0026logoColor=%23F7DF1E)\n\nPostman digunakan untuk menguji dan mendokumentasikan setiap endpoint RESTful pada back‑end CodeIgniter (GET, POST, PUT, DELETE), memastikan format JSON dan status kode HTTP sudah benar sebelum diintegrasikan ke front‑end. Sementara Vue.js berperan sebagai lapisan presentasi interaktif:\n\nMenampilkan daftar Artikel dengan v-for dan two‑way binding (v-model), Memunculkan form tambah/ubah dalam modal via v-if, Menghasilkan UI real‑time saat data diubah tanpa reload halaman.\n\u003cbr\u003e \u003cbr\u003e\n\n\n| Mata Kuliah     | Dosen Pengampu                     |\n| --------- | ----------------------------- |\n| **Pemrograman Web 2** | Agung Nugroho S.kom., M.Kom.      |\n\n\u003cbr\u003e\n\n| NIM           | Nama Mahasiswa                |\n| --------------|------------------------------ |\n| **312310617** | Fadil Aditya Adzima           |\n\n\u003c!-- |Link Video Demo Aplikasi Web| [Klik Disini!]() |\n| -------------------------- | --------------------- | --\u003e\n\n\u003cbr\u003e \n\n## Cara kerja REST API menggunakan prinsip REST Server dan REST Client.\n\u003cp\u003eREST (Representational State Transfer) adalah sebuah arsitektur desain untuk Application Programming Interface (API). API sendiri berfungsi sebagai antarmuka yang menjembatani komunikasi antar-aplikasi. Pada ekosistem REST, server bertindak sebagai penyedia data atau sumber daya (resources), sementara client melakukan permintaan (HTTP request) kepada server dengan menggunakan URI (Uniform Resource Identifier) sebagai identifikasi global. Server kemudian merespons permintaan tersebut dengan mengirimkan data kembali dalam format HTTP response. Umumnya, format data yang dipertukarkan adalah JSON, sehingga REST API dapat dengan mudah diintegrasikan ke berbagai platform, bahasa pemrograman, maupun framework.\u003c/p\u003e\n\n\u003cp\u003eSebagai contoh, Anda dapat membangun proyek backend menggunakan REST API berbasis PHP, lalu menghubungkannya dengan antarmuka frontend yang dikembangkan menggunakan Vue.js. Dengan demikian, komponen frontend dan backend dapat saling berinteraksi secara lancar dan terstandarisasi.\u003c/p\u003e\n\n## Langkah-langkah Praktikum dan Persiapan\nPeriapan awal adalah mengunduh aplikasi REST Client, ada banyak aplikasi yang dapat digunakan untuk keperluan tersebut. Salah satunya adalah Postman. [Postman](https://www.postman.com/) merupakan aplikasi yang berfungsi sebagai REST Client, digunakan untuk testing REST API. Unduh apliasi Postman [Disini.](https://www.postman.com/downloads/)\n\n## Membuat Model\nPada modul sebelumnya sudah dibuat ArtikelModel, pada modul ini kita akan memanfaatkan model tersebut agar dapat diakses melalui API.\n\n## Membuat REST Controller\nPada tahap ini, kita akan membuat file REST Controller yang berisi fungsi untuk menampilkan, menambah, mengubah dan menghapus data. Masuklah ke direktori app\\Controllers dan buatlah file baru bernama Post.php. Kemudian, salin kode di bawah ini ke dalam file tersebut:\n\n```php\n\u003c?php\n\nnamespace App\\Controllers;\n\nuse CodeIgniter\\RESTful\\ResourceController;\nuse CodeIgniter\\API\\ResponseTrait;\nuse App\\Models\\ArtikelModel;\n\nclass Post extends ResourceController\n{\n    use ResponseTrait;\n    // all users\n    public function index()\n    {\n        $model = new ArtikelModel();\n        $data['artikel'] = $model-\u003eorderBy('id', 'DESC')-\u003efindAll();\n        return $this-\u003erespond($data);\n    }\n    // create\n    public function create()\n    {\n        $model = new ArtikelModel();\n        $data = [\n            'judul' =\u003e $this-\u003erequest-\u003egetVar('judul'),\n            'isi' =\u003e $this-\u003erequest-\u003egetVar('isi'),\n        ];\n        $model-\u003einsert($data);\n        $response = [\n            'status' =\u003e 201,\n            'error' =\u003e null,\n            'messages' =\u003e [\n                'success' =\u003e 'Data artikel berhasil ditambahkan.'\n            ]\n        ];\n        return $this-\u003erespondCreated($response);\n    }\n    // single user\n    public function show($id = null)\n    {\n        $model = new ArtikelModel();\n        $data = $model-\u003ewhere('id', $id)-\u003efirst();\n        if ($data) {\n            return $this-\u003erespond($data);\n        } else {\n            return $this-\u003efailNotFound('Data tidak ditemukan.');\n        }\n    }\n    // update\n    public function update($id = null)\n    {\n        $model = new ArtikelModel();\n        $id = $this-\u003erequest-\u003egetVar('id');\n        $data = [\n            'judul' =\u003e $this-\u003erequest-\u003egetVar('judul'),\n            'isi' =\u003e $this-\u003erequest-\u003egetVar('isi'),\n        ];\n        $model-\u003eupdate($id, $data);\n        $response = [\n            'status' =\u003e 200,\n            'error' =\u003e null,\n            'messages' =\u003e [\n                'success' =\u003e 'Data artikel berhasil diubah.'\n            ]\n        ];\n        return $this-\u003erespond($response);\n    }\n    // delete\n    public function delete($id = null)\n    {\n        $model = new ArtikelModel();\n        $data = $model-\u003ewhere('id', $id)-\u003edelete($id);\n        if ($data) {\n            $model-\u003edelete($id);\n            $response = [\n                'status' =\u003e 200,\n                'error' =\u003e null,\n                'messages' =\u003e [\n                    'success' =\u003e 'Data artikel berhasil dihapus.'\n                ]\n            ];\n            return $this-\u003erespondDeleted($response);\n        } else {\n            return $this-\u003efailNotFound('Data tidak ditemukan.');\n        }\n    }\n}\n```\n\nSeperti pada gambar berikut ini!\n\n![Post](img/post.png)\n\n\u003cp\u003eKode diatas berisi 5 method, yaitu:\u003c/p\u003e\n\n```php\nindex() = Berfungsi untuk menampilkan seluruh data pada database.\ncreate() = Berfungsi untuk menambahkan data baru ke database.\nshow() = Berfungsi untuk menampilkan suatu data spesifik dari database.\nupdate() = Berfungsi untuk mengubah suatu data pada database.\ndelete() = Berfungsi untuk menghapus data dari database.\n```\n\n## Membuat Routing REST API\nUntuk mengakses REST API CodeIgniter, kita perlu mendefinisikan route-nya terlebih dulu.\nCaranya, masuklah ke direktori app/Config dan bukalah file Routes.php. Tambahkan kode\ndi bawah ini:\u003c/p\u003e\n\n```php\n$routes-\u003eresource('post');\n```\n\nSeperti pada gambar berikut!\n\n![Routes_Post](img/routes_post.png)\n\nUntuk mengecek route nya jalankan perintah berikut:\n\n```bash\nphp spark routes\n```\n\nSelanjutnya akan muncul daftar route yang telah dibuat.\n\n![Routes](img/routes.png)\n\nSeperti yang terlihat, satu baris kode routes yang di tambahkan akan menghasilkan banyak\nEndpoint. Selanjutnya melakukan uji coba terhadap REST API CodeIgniter.\n\n## Testing REST API CodeIgniter\nBuka aplikasi postman dan pilih create new → HTTP Request\n\n![Postman](img/postman.png)\n\n### Menampilkan Semua Data \nPilih method GET dan masukkan URL berikut: http://localhost:8080/post \u003cbr\u003e\nLalu, klik Send. Jika hasil test menampilkan semua data artikel dari database, maka pengujian\nberhasil.\n\n![Menampilkan Semua Data di Postman](img/menampilkan_semua_data_postman.png)\n\n\n\n### Menampilkan Data Spesifik\nMasih menggunakan method GET, hanya perlu menambahkan ID artikel di belakang URL seperti ini: http://localhost:8080/post/29 \u003cbr\u003e\n\nSelanjutnya, klik Send. Request tersebut akan menampilkan data artikel yang memiliki ID nomor 29 di database.\n\n![Menampilkan Data Spesifik di Postman](img/menampilkan_data_spesifik_postman.png)\n\n\n\n ### Mengubah Data \u003c!-- Ini Belum Ada Gambar Dokumentasi --\u003e\nUntuk mengubah data, silakan ganti method menjadi PUT. Kemudian, masukkan URL artikel yang ingin diubah. Misalnya, ingin mengubah data artikel dengan ID nomor 29, maka masukkan URL berikut: http://localhost:8080/post/29 \u003cbr\u003e\n\nSelanjutnya, Masukkan nama atribut tabel pada kolom KEY dan nilai data yang baru pada kolom VALUE. Kalau sudah,\nklik Send.\n\n![Mengubah Data di Postman](img/mengubah_data_postman.png)\n\n\n\n### Menambahkan Data\nPilih method POST untuk menambahkan data baru ke database. Kemudian, masukkan URL berikut: http://localhost:8080/post/ \u003cbr\u003e\n\nLangsung saja klik Send, maka akan mendapatkan pesan bahwa data telah berhasil ditambahkan ke dalam database.\n\n![Menambahkan Data di Postman](img/menambahkan_data_postman.png)\n\n\n\n### Menghapus Data\nPilih method DELETE untuk menghapus data. Lalu, masukkan URL spesifik data mana yang ingin di hapus. Misalnya, ingin menghapus data nomor 29, maka URL-nya seperti ini: http://localhost:8080/post/29 \u003cbr\u003e\n\nLangsung saja klik Send, maka akan mendapatkan pesan bahwa data telah berhasil dihapus dari\ndatabase.\n\n![Menghapus Data di Postman](img/menghapus_data_postman.png)\n\n\u003cbr\u003e\n\n## Selanjutnya Kita Masuk Ke Dalam Praktikum VueJS\nVuesJS merupakan sebuah framework JavaScript untuk membangun aplikasi web atau tampilan interface website agar lebih interaktif. VueJS dapat digunakan untuk membangun aplikasi berbasis user interface, seperti halaman web, aplikasi mobile, dan aplikasi desktop. \u003cbr\u003e\n\nFramework ini juga menawarkan berbagai fitur, seperti reactive data binding, component based architecture, dan tools untuk membangun aplikasi skalabel. Fitur utamanya adalah rendering dan komposisi elemen, sehingga bila pengguna hendak membuat aplikasi yang lebih kompleks akan membutuhkan routing, state management, template, build-tool, dan lain sebagainya.Adapun library VueJS berfokus pada view layer sehingga framework ini mudah untuk diimplementasikan dan diintegrasikan dengan library lain. Selain itu, VueJS juga terkenal mudah digunakan karena memiliki sintaksis yang sederhana dan intuitif, memungkinkan pengembang untuk membangun aplikasi web dengan mudah. Untuk lebih lengkapnya dapat dipelajari pada dokumentasinya pada websitenya https://vuejs.org/guide/introduction\n\n## Langkah-langkah Untuk Memulainya\nUntuk memulai penggunaan framework Vuejs, dapat dialkukan dengan menggunakan npm, atau bisa juga dengan cara manual Untuk praktikum kali ini kita akan gunakan cara manual. Yang diperlukan adalah library Vuejs, Axios untuk melakukan call API REST. Menggunakan CDN.\n\n### Library VueJS\n```javascript\n\u003cscript src=\"https://unpkg.com/vue@3/dist/vue.global.js\"\u003e\u003c/script\u003e\n```\n\n### Library Axios\n```javascript\n\u003cscript src=\"https://unpkg.com/axios/dist/axios.min.js\"\u003e\u003c/script\u003e\n```\n\n## 📁 Struktur Folder\n```\nlab11_vuejs/\n├── index.html\n├── assets/\n│   ├── css/\n│   │   └── style.css\n│   └── js/\n│       └── app.js\n```\n\n### Menampilkan Data\n#### File index.html\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"id\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eFrontend Artikel VueJS\u003c/title\u003e\n    \u003c!-- CDN untuk VueJS 3 --\u003e\n    \u003cscript src=\"https://unpkg.com/vue@3/dist/vue.global.js\"\u003e\u003c/script\u003e\n    \u003c!-- CDN untuk Axios --\u003e\n    \u003cscript src=\"https://unpkg.com/axios/dist/axios.min.js\"\u003e\u003c/script\u003e\n    \u003c!-- Link ke CSS kustom --\u003e\n    \u003clink rel=\"stylesheet\" href=\"assets/css/style.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cdiv id=\"app\"\u003e\n        \u003ch1\u003eDaftar Artikel\u003c/h1\u003e\n\n        \u003c!-- Tombol Tambah Data --\u003e\n        \u003cbutton id=\"btn-tambah\" @click=\"tambah\"\u003eTambah Data\u003c/button\u003e\n\n        \u003c!-- Modal Form Tambah dan Ubah Data --\u003e\n        \u003cdiv class=\"modal\" v-if=\"showForm\"\u003e\n            \u003cdiv class=\"modal-content\"\u003e\n                \u003cspan class=\"close\" @click=\"showForm = false\"\u003e\u0026times;\u003c/span\u003e\n                \u003cform id=\"form-data\" @submit.prevent=\"saveData\"\u003e\n                    \u003ch3 id=\"form-title\"\u003e{{ formTitle }}\u003c/h3\u003e\n                    \u003cdiv\u003e\n                        \u003clabel for=\"judul\" class=\"form-label\"\u003eJudul Artikel\u003c/label\u003e \u003c!-- Label untuk Judul --\u003e\n                        \u003cinput type=\"text\" name=\"judul\" id=\"judul\" v-model=\"formData.judul\" placeholder=\"Judul\" required\u003e\n                    \u003c/div\u003e\n                    \u003cdiv\u003e\n                        \u003clabel for=\"isi\" class=\"form-label\"\u003eIsi Artikel\u003c/label\u003e \u003c!-- Label untuk Isi --\u003e\n                        \u003ctextarea name=\"isi\" id=\"isi\" rows=\"10\" v-model=\"formData.isi\" placeholder=\"Isi Artikel\"\u003e\u003c/textarea\u003e\n                    \u003c/div\u003e\n                    \u003cdiv\u003e\n                        \u003clabel for=\"status\" class=\"form-label\"\u003eStatus\u003c/label\u003e \u003c!-- Label untuk Status --\u003e\n                        \u003cselect name=\"status\" id=\"status\" v-model=\"formData.status\"\u003e\n                            \u003coption v-for=\"option in statusOptions\" :value=\"option.value\" :key=\"option.value\"\u003e\n                                {{ option.text }}\n                            \u003c/option\u003e\n                        \u003c/select\u003e\n                    \u003c/div\u003e\n                    \u003c!-- Hidden input untuk ID artikel saat edit --\u003e\n                    \u003cinput type=\"hidden\" id=\"id\" v-model=\"formData.id\"\u003e\n                    \u003cbutton type=\"submit\" id=\"btnSimpan\"\u003eSimpan\u003c/button\u003e\n                    \u003cbutton type=\"button\" @click=\"showForm = false\"\u003eBatal\u003c/button\u003e\n                \u003c/form\u003e\n            \u003c/div\u003e\n        \u003c/div\u003e\n\n        \u003c!-- Tabel untuk menampilkan data artikel --\u003e\n        \u003ctable\u003e\n            \u003cthead\u003e\n                \u003ctr\u003e\n                    \u003cth\u003eID\u003c/th\u003e\n                    \u003cth\u003eJudul\u003c/th\u003e\n                    \u003cth\u003eStatus\u003c/th\u003e\n                    \u003cth\u003eAksi\u003c/th\u003e\n                \u003c/tr\u003e\n            \u003c/thead\u003e\n            \u003ctbody\u003e\n                \u003c!-- Loop melalui array artikel --\u003e\n                \u003ctr v-for=\"(row, index) in artikel\" :key=\"row.id\"\u003e\n                    \u003ctd class=\"center-text\"\u003e{{ row.id }}\u003c/td\u003e\n                    \u003ctd\u003e{{ row.judul }}\u003c/td\u003e\n                    \u003ctd\u003e{{ statusText(row.status) }}\u003c/td\u003e\n                    \u003ctd class=\"center-text\"\u003e\n                        \u003ca href=\"#\" @click.prevent=\"edit(row)\"\u003eEdit\u003c/a\u003e\n                        \u003ca href=\"#\" @click.prevent=\"hapus(index, row.id)\"\u003eHapus\u003c/a\u003e\n                    \u003c/td\u003e\n                \u003c/tr\u003e\n                \u003ctr v-if=\"artikel.length === 0\"\u003e\n                    \u003ctd colspan=\"4\" class=\"center-text\"\u003eTidak ada artikel tersedia.\u003c/td\u003e\n                \u003c/tr\u003e\n            \u003c/tbody\u003e\n        \u003c/table\u003e\n    \u003c/div\u003e\n\n    \u003c!-- Link ke JavaScript aplikasi VueJS kita --\u003e\n    \u003cscript src=\"assets/js/app.js\"\u003e\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n\u003cbr\u003e\n\n#### File app.js\n```javascript\nconst { createApp } = Vue;\n\n// Tentukan lokasi API REST End Point Anda\n// Contoh: 'http://localhost:8080/post' jika Anda mengaksesnya langsung\n// atau 'http://localhost/labci4/public/post' jika public bukan root\nconst apiUrl = 'http://localhost/Lab11_ci/ci4/public/post'; // Sesuaikan ini dengan URL API Anda!\n\ncreateApp({\n    data() {\n        return {\n            artikel: [], // Array untuk menyimpan data artikel\n            \n            // Objek untuk data form (digunakan untuk tambah dan ubah)\n            formData: {\n                id: null,\n                judul: '',\n                isi: '',\n                status: 0 // Default status (misal: 0 untuk Draft)\n            },\n            \n            showForm: false, // Kontrol tampilan modal form\n            formTitle: 'Tambah Data', // Judul modal form\n            \n            // Opsi untuk dropdown status\n            statusOptions: [\n                {text: 'Draft', value: 0}, // Sesuaikan value dengan kolom status di DB (0/1 atau 'Draft'/'published')\n                {text: 'Publish', value: 1} // Jika status di DB Anda adalah string 'Draft'/'published', gunakan itu sebagai value\n            ],\n        };\n    },\n    \n    // Dipanggil saat instance Vue selesai di-mount\n    mounted() {\n        this.loadData();\n    },\n    \n    methods: {\n        // Fungsi untuk memuat data artikel dari API\n        loadData() {\n            axios.get(apiUrl)\n                .then(response =\u003e {\n                    // Jika API mengembalikan { artikel: [...] }, akses response.data.artikel\n                    // Jika API hanya mengembalikan [...], akses response.data\n                    this.artikel = response.data.artikel || response.data; \n                    console.log(\"Data artikel dimuat:\", this.artikel);\n                })\n                .catch(error =\u003e {\n                    console.error(\"Error memuat data:\", error);\n                    alert(\"Gagal memuat data artikel. Cek konsol untuk detail.\");\n                });\n        },\n        \n        // Fungsi untuk mengubah tampilan status (dari angka/boolean ke teks)\n        statusText(status) {\n            // Sesuaikan logika ini dengan bagaimana status disimpan di database Anda\n            // Jika di DB adalah '0' atau '1' (string/number)\n            if (status == 1 || status == '1' || status === 'published') {\n                return 'Publish';\n            } else if (status == 0 || status == '0' || status === 'Draft') {\n                return 'Draft';\n            }\n            return ''; // Default jika status tidak dikenali\n        },\n        \n        // Fungsi untuk menampilkan form tambah data\n        tambah() {\n            this.showForm = true;\n            this.formTitle = 'Tambah Data';\n            // Reset formData agar kosong untuk entri baru\n            this.formData = {\n                id: null,\n                judul: '',\n                isi: '',\n                status: 0 // Default status untuk form tambah\n            };\n        },\n        \n        // Fungsi untuk menghapus artikel\n        hapus(index, id) {\n            if (confirm('Yakin ingin menghapus data ini?')) {\n                axios.delete(apiUrl + '/' + id)\n                    .then(response =\u003e {\n                        alert(response.data.messages.success); // Tampilkan pesan sukses dari API\n                        this.artikel.splice(index, 1); // Hapus item dari array di frontend\n                        // Alternatif: this.loadData(); // Memuat ulang semua data dari server\n                    })\n                    .catch(error =\u003e {\n                        console.error(\"Error menghapus data:\", error.response || error);\n                        alert(\"Gagal menghapus artikel: \" + (error.response?.data?.messages?.error || error.message || \"Terjadi kesalahan.\"));\n                    });\n            }\n        },\n        \n        // Fungsi untuk mengisi form dengan data artikel yang akan diubah\n        edit(data) {\n            this.showForm = true;\n            this.formTitle = 'Ubah Data';\n            // Isi formData dengan data dari baris yang dipilih\n            this.formData = {\n                id: data.id,\n                judul: data.judul,\n                isi: data.isi,\n                // Pastikan status sesuai dengan value di statusOptions (misal: 0 atau 1)\n                status: data.status == 'published' ? 1 : (data.status == 'Draft' ? 0 : data.status)\n            };\n            console.log(\"Mengedit item:\", this.formData);\n        },\n        \n        // Fungsi untuk menyimpan atau mengubah data (dipanggil saat form disubmit)\n        saveData() {\n            // Jika formData.id ada, berarti ini adalah operasi ubah (PUT)\n            if (this.formData.id) {\n                axios.put(apiUrl + '/' + this.formData.id, this.formData)\n                    .then(response =\u003e {\n                        alert(response.data.messages.success || \"Artikel berhasil diubah!\");\n                        this.loadData(); // Muat ulang data setelah perubahan\n                        this.showForm = false; // Sembunyikan form\n                        console.log('Item diperbarui:', response.data);\n                    })\n                    .catch(error =\u003e {\n                        console.error(\"Error memperbarui item:\", error.response || error);\n                        alert(\"Gagal mengubah artikel: \" + (error.response?.data?.messages?.error || error.message || \"Terjadi kesalahan.\"));\n                    });\n            } else {\n                // Jika formData.id null, berarti ini adalah operasi tambah (POST)\n                axios.post(apiUrl, this.formData)\n                    .then(response =\u003e {\n                        alert(response.data.messages.success || \"Artikel berhasil ditambahkan!\");\n                        this.loadData(); // Muat ulang data setelah penambahan\n                        this.showForm = false; // Sembunyikan form\n                        console.log('Item ditambahkan:', response.data);\n                    })\n                    .catch(error =\u003e {\n                        console.error(\"Error menambahkan item:\", error.response || error);\n                        alert(\"Gagal menambahkan artikel: \" + (error.response?.data?.messages?.error || error.message || \"Terjadi kesalahan.\"));\n                    });\n            }\n            \n            // Reset form data setelah operasi selesai (atau di dalam then/catch block)\n            this.formData = {\n                id: null,\n                judul: '',\n                isi: '',\n                status: 0\n            };\n        },\n    },\n}).mount('#app'); // Mount aplikasi Vue ke elemen dengan id \"app\"\n```\n\n\u003cbr\u003e\n\n#### File style.css\n```css\n/* Styling dasar untuk aplikasi VueJS */\n#app {\n    margin: 0 auto;\n    width: 900px;\n    padding: 20px; /* Tambahkan padding agar tidak terlalu mepet */\n    font-family: sans-serif; /* Atur font-family */\n}\n\nh1 {\n    text-align: center;\n    color: #3152d6;\n    margin-bottom: 20px;\n}\n\ntable {\n    min-width: 700px;\n    width: 100%;\n    border-collapse: collapse; /* Hilangkan jarak antar border cell */\n    margin-top: 20px;\n    box-shadow: 0 2px 8px rgba(0,0,0,0.1); /* Tambahkan sedikit bayangan */\n    border-radius: 8px; /* Sudut membulat */\n    overflow: hidden; /* Pastikan sudut membulat diterapkan */\n}\n\nth {\n    padding: 12px 10px;\n    background: #5778ff !important;\n    color: #ffffff;\n    text-align: left; /* Atur teks ke kiri */\n}\n\ntr td {\n    border-bottom: 1px solid #eff1ff;\n    padding: 10px;\n}\n\ntr:nth-child(odd) {\n    background-color: #eff1ff;\n}\n\ntd {\n    padding: 10px;\n}\n\n.center-text {\n    text-align: center;\n}\n\ntd a {\n    margin: 0 5px; /* Sesuaikan margin untuk link aksi */\n    text-decoration: none; /* Hilangkan underline */\n    color: #3152d6; /* Warna link */\n}\n\ntd a:hover {\n    text-decoration: underline; /* Munculkan underline saat hover */\n}\n\n/* Styling untuk form */\n#form-data {\n    width: 100%; /* Lebar form menyesuaikan modal-content */\n}\n\nform input,\nform select,\nform textarea {\n    width: 100%;\n    margin-bottom: 10px; /* Tambahkan margin-bottom */\n    padding: 10px;\n    box-sizing: border-box;\n    border: 1px solid #ccc;\n    border-radius: 4px; /* Sudut membulat */\n}\n\nform div {\n    margin-bottom: 10px; /* Sesuaikan margin-bottom untuk setiap div form */\n    position: relative;\n}\n\nform button {\n    padding: 10px 20px;\n    margin-top: 10px;\n    margin-right: 10px;\n    cursor: pointer;\n    border: none;\n    border-radius: 5px; /* Sudut membulat */\n    font-weight: bold;\n    transition: background-color 0.3s ease; /* Transisi halus */\n}\n\n#btn-tambah {\n    margin-bottom: 15px;\n    padding: 12px 25px;\n    cursor: pointer;\n    background-color: #28a745; /* Warna hijau untuk tambah */\n    color: #ffffff;\n    border: 1px solid #28a745;\n    border-radius: 5px;\n    font-weight: bold;\n    transition: background-color 0.3s ease;\n}\n\n#btn-tambah:hover {\n    background-color: #218838;\n}\n\n#btnSimpan {\n    background-color: #3152d6;\n    color: #ffffff;\n    border: 1px solid #3152d6;\n}\n\n#btnSimpan:hover {\n    background-color: #2640aa;\n}\n\nform button[type=\"button\"] { /* Untuk tombol Batal */\n    background-color: #6c757d;\n    color: #ffffff;\n}\n\nform button[type=\"button\"]:hover {\n    background-color: #5a6268;\n}\n\n/* Styling Modal */\n.modal {\n    display: block; /* Default to block for v-if to toggle */\n    position: fixed;\n    z-index: 1000; /* Pastikan modal di atas konten lain */\n    left: 0;\n    top: 0;\n    width: 100%;\n    height: 100%;\n    overflow: auto;\n    background-color: rgba(0,0,0,0.6); /* Lebih gelap sedikit dari modul */\n    display: flex; /* Gunakan flexbox untuk centering */\n    justify-content: center;\n    align-items: center;\n}\n\n.modal-content {\n    background-color: #fefefe;\n    padding: 30px; /* Tambah padding */\n    border: 1px solid #888;\n    width: 90%; /* Responsif */\n    max-width: 600px; /* Batasi lebar maksimum */\n    border-radius: 8px; /* Sudut membulat */\n    box-shadow: 0 5px 15px rgba(0,0,0,0.3); /* Bayangan lebih kuat */\n    position: relative; /* Untuk posisi tombol close */\n}\n\n.close {\n    color: #aaa;\n    float: right; /* Atur float untuk tombol close */\n    font-size: 28px;\n    font-weight: bold;\n    cursor: pointer;\n    position: absolute; /* Posisi absolut di dalam modal-content */\n    top: 10px;\n    right: 15px;\n}\n\n.close:hover,\n.close:focus {\n    color: #000;\n    text-decoration: none;\n    cursor: pointer;\n}\n\nh3#form-title {\n    text-align: center;\n    color: #3152d6;\n    margin-bottom: 20px;\n}\n\n/* Responsive adjustments */\n@media (max-width: 768px) {\n    #app {\n        width: 100%;\n        padding: 10px;\n    }\n    table {\n        font-size: 0.9em;\n    }\n    th, td {\n        padding: 8px;\n    }\n}\n```\n\n\u003cbr\u003e \u003cbr\u003e\n\n## Hasil Dokumentasi Lab11_vuejs\n![vuejs](img/vuejs.gif)\n\u003cp\u003eGIF ini mendemonstrasikan hasil akhir dari web \u003cb\u003eLab11Web\u003c/b\u003e, sebuah platform manajemen artikel berbasis \u003cb\u003eVue.js\u003c/b\u003e yang terintegrasi dengan RESTful API. Tampilan utama menampilkan tabel daftar artikel dengan informasi ID, judul, status publikasi, serta aksi yang dapat dilakukan seperti \u003cb\u003eEdit\u003c/b\u003e dan \u003cb\u003eHapus\u003c/b\u003e. Di bagian atas tersedia tombol “Tambah Data” yang memicu kemunculan modal form untuk input artikel baru secara dinamis. Seluruh interaksi termasuk pengambilan, penyimpanan, dan penghapusan data dilakukan secara real-time tanpa perlu memuat ulang halaman, menunjukkan implementasi arsitektur \u003cb\u003eSingle Page Application (SPA)\u003c/b\u003e yang efisien, interaktif, dan responsif.\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffadiladz%2Flab11web-vuejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffadiladz%2Flab11web-vuejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffadiladz%2Flab11web-vuejs/lists"}