Рубрики
Без рубрики

Все же Еще одно приложение Damn Todo в Vue.js

Итак, на прошлой неделе я опубликовал свой захватывающий пост на создании приложения Todo в Vue.js («Другое приложение Thamn Todo I … Tagged с Vue, JavaScript, WebDev.

Поэтому на прошлой неделе я опубликовал свой захватывающий пост на создании приложения 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 не имели первичного ключа Поэтому мне пришлось использовать индекс цикла в качестве ключа. Теперь мой Тодос сделать Имеется Так что я использую это вместо этого. Вот и все. 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”