返回

Vue.js 和 Flask强强联合,打造单页应用

前端

前言

随着网络技术的发展,单页应用(SPA)已成为现代Web开发的潮流之一。SPA将整个应用放在一个页面中,通过JavaScript动态地更新内容,从而提供更加流畅和响应迅速的用户体验。而Vue.js和Flask分别是JavaScript和Python两种语言中备受推崇的前端和后端框架。将两者结合,可以轻松构建出功能强大、易于维护的单页应用。

项目设置

首先,我们需要为我们的项目创建一个文件夹,并安装必要的依赖项。使用以下命令即可:

mkdir vue-flask-app
cd vue-flask-app
npm init -y
npm install vue
pip install flask

应用结构

接下来,我们需要为我们的应用设置一个基本的文件结构。我们将使用以下目录结构:

vue-flask-app/
  ├── app.py
  ├── frontend/
  │   ├── src/
  │   │   ├── App.vue
  │   │   ├── main.js
  │   │   └── router.js
  │   └── index.html
  └── requirements.txt

其中,app.py是Flask应用的入口文件,frontend/目录是Vue.js应用的根目录,requirements.txt是Python依赖项列表。

Flask后端

现在,我们可以开始编写Flask后端代码了。在app.py中,我们将创建一个简单的RESTful API,用于管理我们的数据。代码如下:

from flask import Flask, request, jsonify

app = Flask(__name__)

# 定义数据模型
class Todo:
    def __init__(self, id, title, description):
        self.id = id
        self.title = title
        self.description = description

# 创建一个空列表来存储待办事项
todos = []

# 添加待办事项
@app.route('/todos', methods=['POST'])
def add_todo():
    data = request.get_json()
    new_todo = Todo(len(todos) + 1, data['title'], data['description'])
    todos.append(new_todo)
    return jsonify({'success': True, 'todo': new_todo})

# 获取所有待办事项
@app.route('/todos', methods=['GET'])
def get_todos():
    return jsonify({'success': True, 'todos': todos})

# 获取单个待办事项
@app.route('/todos/<int:todo_id>', methods=['GET'])
def get_todo(todo_id):
    todo = next((todo for todo in todos if todo.id == todo_id), None)
    if todo:
        return jsonify({'success': True, 'todo': todo})
    else:
        return jsonify({'success': False, 'error': 'Todo not found'})

# 更新待办事项
@app.route('/todos/<int:todo_id>', methods=['PUT'])
def update_todo(todo_id):
    todo = next((todo for todo in todos if todo.id == todo_id), None)
    if todo:
        data = request.get_json()
        todo.title = data['title']
        todo.description = data['description']
        return jsonify({'success': True, 'todo': todo})
    else:
        return jsonify({'success': False, 'error': 'Todo not found'})

# 删除待办事项
@app.route('/todos/<int:todo_id>', methods=['DELETE'])
def delete_todo(todo_id):
    todo = next((todo for todo in todos if todo.id == todo_id), None)
    if todo:
        todos.remove(todo)
        return jsonify({'success': True})
    else:
        return jsonify({'success': False, 'error': 'Todo not found'})

if __name__ == '__main__':
    app.run()

Vue.js前端

接下来,我们可以编写Vue.js前端代码了。在frontend/src/App.vue中,我们将创建一个简单的Vue组件,用于显示和管理待办事项。代码如下:

<template>
  <div id="app">
    <h1>待办事项列表</h1>
    <ul>
      <li v-for="todo in todos" :key="todo.id">
        {{ todo.title }} - {{ todo.description }}
        <button @click="deleteTodo(todo.id)">删除</button>
        <button @click="editTodo(todo.id)">编辑</button>
      </li>
    </ul>
    <form @submit.prevent="addTodo">
      <input type="text" v-model="newTodo.title" placeholder="标题">
      <input type="text" v-model="newTodo.description" placeholder="">
      <button type="submit">添加</button>
    </form>
    <div v-if="editing">
      <input type="text" v-model="editingTodo.title" placeholder="标题">
      <input type="text" v-model="editingTodo.description" placeholder="">
      <button @click="updateTodo">更新</button>
      <button @click="cancelEdit">取消</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      todos: [],
      newTodo: {
        title: '',
        description: ''
      },
      editing: false,
      editingTodo: {}
    }
  },
  mounted() {
    this.fetchTodos()
  },
  methods: {
    fetchTodos() {
      fetch('/todos')
        .then(res => res.json())
        .then(data => {
          this.todos = data.todos
        })
    },
    addTodo() {
      fetch('/todos', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(this.newTodo)
      })
        .then(res => res.json())
        .then(data => {
          this.todos.push(data.todo)
          this.newTodo = {
            title: '',
            description: ''
          }
        })
    },
    deleteTodo(id) {
      fetch(`/todos/${id}`, {
        method: 'DELETE'
      })
        .then(res => res.json())
        .then(data => {
          if (data.success) {
            this.todos = this.todos.filter(todo => todo.id !== id)
          }
        })
    },
    editTodo(id) {
      this.editing = true
      this.editingTodo = this.todos.find(todo => todo.id === id)
    },
    updateTodo() {
      fetch(`/todos/${this.editingTodo.id}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(this.editingTodo)
      })
        .then(res => res.json())
        .then(data => {
          if (data.success) {
            this.editing = false
            this.editingTodo = {}
            this.fetchTodos()
          }
        })
    },
    cancelEdit() {
      this.editing = false
      this.editingTodo = {}
    }
  }
}
</script>

运行应用

现在,我们可以运行我们的应用了。在终端中执行以下命令:

cd frontend
npm run serve

在另一个终端中执行以下命令:

cd ..
flask run

总结

通过本教程,我们已经成功地将Vue.js和Flask结合起来,构建了一个完整的单页应用。您现在可以根据自己的需要对其进行修改和扩展,以构建更复杂的应用。