Поэтому на прошлой неделе я опубликовал свой захватывающий пост на создании приложения Todo в Vue.js ( «Другое приложение Damn Todo в Vue.js» ). Как и обещал, я следую на этом посте с «расширенной» версией приложения. Предыдущая версия была довольно проста. Он использовал Vue в качестве тега скрипта, а не полное приложение Vue и сохраняет TODOS в памяти. Это означало на каждой перезагрузке данные были потеряны.
В этой версии я сделал три основных изменения:
- Сначала я переключился на полное приложение Vue.
- Я добавил vuex как способ поставить мою код доступа к данным в одном месте.
- Я использовал indexeddb, чтобы сохранить тодос по всей нагрузке. Это все еще только на устройство Поэтому, если вы откроете приложение на другой машине или в другом браузере, у него не будет тех же данных.
Позвольте мне объяснить каждый шаг этого.
Переключение на приложение
Эта часть должна быть относительно прямой. Оригинальная версия моего приложения (которую вы можете увидеть здесь ) был построен только с тегом сценария и некоторым кодом, без процесса сборки. В этом нет ничего плохого! Но с идеей, что я усиливающую это приложение, чтобы сделать его более мощным, для меня именем смысл переместить это в приложение.
Я просто использовал Vue CLI, чтобы подкрепить новое приложение, используя -b
Возможность держать его в чистоте вещи, мне не нужно.
С новым приложением я скопировал через HTML, CSS и JavaScript с первой версии и обеспечил все еще работать. Совет, который мне нравится разделяться время от времени, – взять детские шаги, когда вы разрабатываете.
Добавление Vuex.
Затем я добавил vuex в приложение. Идея заключается в том, что мои компоненты приложений будут задать свои данные от Vuex и Vuex, будут обрабатывать получение, обновление и т. Д. Это необходимые изменения в переднем углу компонента, так что давайте посмотрим. Во-первых, HTML, как изменение здесь, является супер второстепенным.
ToDos
{{todo.text}}
Таким образом, буквально единственное изменение здесь находится в индексе в моей петле. Ранее мои Todos не имели первичного ключа Поэтому мне пришлось использовать индекс цикла в качестве ключа. Теперь мой Тодос сделать Имеется Так что я использую это вместо этого. Вот и все. JavaScript изменился совсем немного больше.
import { mapGetters } from 'vuex'; export default { data() { return { todoText:'' } }, created() { this.$store.dispatch('loadToDos'); }, computed: { ...mapGetters(['sortedToDos']) }, methods: { saveToDo() { if(this.todoText === '') return; this.$store.dispatch('saveToDo', { text:this.todoText, done:false} ); this.todoText = ''; }, toggleDone(todo) { this.$store.dispatch('toggleToDo', todo); } } }
Во-первых, я импортирую MapGetters
Отказ Эта утилита Vuex облегчает использование GetTers от Vuex, которая действует как вычисленные свойства. Мой Создано
Метод вызывает действие в магазине, который будет получать наши данные. Оба Savetodo
и TOGGLEDONE
Теперь позвоните в магазин, чтобы обработать свою логику.
Реализация IndexedDB.
По большей части я скопировал работу, которую я сделал в октябре прошлого года, когда я впервые обсудил эту тему, Использование IndexedDB в Vue.js Отказ Мой магазин обрабатывает данные, но настойчивость обрабатывается другим скриптом, idb.js
Отказ (Это не лучшее имя, но Whatevs …) Вот мой магазин:
import Vue from 'vue' import Vuex from 'vuex' import idb from '@/api/idb'; Vue.use(Vuex) export default new Vuex.Store({ state: { todos: [] }, getters: { sortedToDos(state) { return state.todos.slice().sort((a,b) => { if(!a.done && b.done) return -1; if(a.done && b.done) return 0; if(a.done && !b.done) return 1; }); } }, mutations: { addToDo(state, todo) { state.todos.unshift(todo); }, clearToDos(state) { state.todos = []; }, toggleToDo(state, id) { state.todos = state.todos.map(t => { if(t.id === id) t.done = !t.done; return t; }); } }, actions: { async loadToDos(context) { context.commit('clearToDos'); context.state.todos = []; let todos = await idb.getToDos(); todos.forEach(t => { context.commit('addToDo', t); }); }, async saveToDo(context, todo) { await idb.saveToDo(todo); context.dispatch('loadToDos'); }, async toggleToDo(context, todo) { todo.done = !todo.done; await idb.saveToDo(todo); context.dispatch('loadToDos'); } } })
Обратите внимание, что я импортирую тот второй новый сценарий, и я на самом деле не оставляю значения состояния. Я загружаю их от логики в сценарии. Я манипулирую копией в моем добыте. Но чтение и письмо сделано в idb.js
Отказ Этот код почти точно такой же, как сообщение в блоге, упомянутое выше, но вот оно:
const DB_NAME = 'tododb'; const DB_VERSION = 1; let DB; export default { async getDb() { return new Promise((resolve, reject) => { if(DB) { return resolve(DB); } console.log('OPENING DB', DB); let request = window.indexedDB.open(DB_NAME, DB_VERSION); request.onerror = e => { console.log('Error opening db', e); reject('Error'); }; request.onsuccess = e => { DB = e.target.result; resolve(DB); }; request.onupgradeneeded = e => { console.log('onupgradeneeded'); let db = e.target.result; db.createObjectStore('todos', { autoIncrement: true, keyPath:'id' }); }; }); }, async getToDos() { let db = await this.getDb(); return new Promise(resolve => { let trans = db.transaction(['todos'],'readonly'); trans.oncomplete = () => { resolve(todos); }; let store = trans.objectStore('todos'); let todos = []; store.openCursor().onsuccess = e => { let cursor = e.target.result; if (cursor) { todos.push(cursor.value) cursor.continue(); } }; }); }, async saveToDo(todo) { let db = await this.getDb(); return new Promise(resolve => { let trans = db.transaction(['todos'],'readwrite'); trans.oncomplete = () => { resolve(); }; let store = trans.objectStore('todos'); store.put(todo); }); } }
Опять же, если вы хотите больше деталей о том, как это работает, проверьте мой ранее пост (И не стесняйтесь спрашивать меня в комментарии ниже).
И это в значительной степени это. Вы можете увидеть полный исходный код приложения здесь: https://github.com/cfjedimaster/vue-demos/tree/master/todos2. . У меня также есть живая версия, которую вы можете бежать здесь: https://todos2.raymondcamden.now.sh/
Фото заголовка Гленн Карстенс-Петерс на бессплашне
Оригинал: “https://dev.to/raymondcamden/yet-another-damn-todo-app-in-vue-js-18b3”