Electron+vue+sqlite3

来自泡泡学习笔记
BrainBs讨论 | 贡献2024年1月2日 (二) 09:53的版本 (创建页面,内容为“ == 安装sqlite3 == <pre>npm install better-sqlite3</pre> <br> <span id="创建-sqlite-数据库"></span> == 创建 SQLite 数据库 == 在项目根目录下创建一个名为 database.js 的文件 <pre>const sqlite = require('better-sqlite3') const path = require('path') const dbPath = './database.sqlite' const db = new sqlite(dbPath) const initDb = () => { db.prepare(` CREATE TABLE IF NOT EXISTS todos ( id INTEGER PRIMARY KEY AUTOINCREMENT,…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

安装sqlite3

npm install better-sqlite3


创建 SQLite 数据库

在项目根目录下创建一个名为 database.js 的文件

const sqlite = require('better-sqlite3')
const path = require('path')

const dbPath = './database.sqlite'
const db = new sqlite(dbPath)

const initDb = () => {
db.prepare(`
    CREATE TABLE IF NOT EXISTS todos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    text TEXT NOT NULL,
    completed INTEGER NOT NULL DEFAULT 0
    );
`).run()
}

module.exports = {
db,
initDb,
}
export {
db,
initDb,
}


创建界面

在项目根目录下创建一个名为 TodoList.vue 的文件

<template>
<div>
    <h1>Todo List</h1>
    <form @submit.prevent="addTodo"> 
    <input v-model="newTodoText" type="text" placeholder="Add a new todo">
    <button type="submit">Add</button>
    </form>
    <ul>
    <li v-for="todo in todos" :key="todo.id">
        <input type="checkbox" v-model="todo.completed" @change="updateTodo(todo)">
        <span :class="{ completed: todo.completed }">{{ todo.text }}</span>
        <button @click="deleteTodo(todo)">Delete</button>
    </li>
    </ul>
</div>
</template>

<script>
import {db, initDb} from './database.js'

initDb();

class Todo {
constructor(text, completed = false) {
    this.text = text
    this.completed = completed
}

save() {
    const stmt = db.prepare(`
    INSERT INTO todos (text, completed)
    VALUES (?, ?)
    `)
    stmt.run(this.text, this.completed ? 1 : 0)
}

static findAll() {
    const stmt = db.prepare(`
    SELECT *
    FROM todos
    `)
    const rows = stmt.all()
    return rows.map(row => new Todo(row.text, row.completed))
}

static findById(id) {
    const stmt = db.prepare(`
    SELECT *
    FROM todos
    WHERE id = ?
    `)
    const row = stmt.get(id)
    return row ? new Todo(row.text, row.completed) : null
}

update() {
    const stmt = db.prepare(`
    UPDATE todos
    SET text = ?, completed = ?
    WHERE id = ?
    `)
    stmt.run(this.text, this.completed ? 1 : 0, this.id)
}

delete() {
    const stmt = db.prepare(`
    DELETE FROM todos
    WHERE id = ?
    `)
    stmt.run(this.id)
}
}

export default {
data() {
    return {
    newTodoText: '',
    todos: [],
    }
},
async mounted() {
    const rows = await Todo.findAll()
    this.todos = rows
},
methods: {
    async addTodo() {
    const todo = new Todo(this.newTodoText)
    todo.save()
    this.todos.push(todo)
    this.newTodoText = ''
    },
    async updateTodo(todo) {
    todo.update()
    },
    async deleteTodo(todo) {
    todo.delete()
    this.todos = this.todos.filter(t => t.id !== todo.id)
    },
},
}
</script>

<style>
.completed {
text-decoration: line-through;
}
</style>


集成 SQLite

<script setup>
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
import TodoList from './TodoList.vue'
</script>

<template>
<header>
    <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

    <div class="wrapper">
    <HelloWorld msg="You did it!" />

    <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
    </nav>
    </div>
    <TodoList></TodoList>
</header>

<RouterView />
</template>

<style scoped>
header {
line-height: 1.5;
max-height: 100vh;
}

.logo {
display: block;
margin: 0 auto 2rem;
}

nav {
width: 100%;
font-size: 12px;
text-align: center;
margin-top: 2rem;
}

nav a.router-link-exact-active {
color: var(--color-text);
}

nav a.router-link-exact-active:hover {
background-color: transparent;
}

nav a {
display: inline-block;
padding: 0 1rem;
border-left: 1px solid var(--color-border);
}

nav a:first-of-type {
border: 0;
}

@media (min-width: 1024px) {
header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
}

.logo {
    margin: 0 2rem 0 0;
}

header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
}

nav {
    text-align: left;
    margin-left: -1rem;
    font-size: 1rem;

    padding: 1rem 0;
    margin-top: 1rem;
}
}
</style>