6

背景

后端选型:
项目所用到的语言是python, 需要选一个框架作为后端。调研了一番,比较多人使用的 Django,和 Flask。 相比之下,Flask 比 Django 更轻量,最后选用了 Falsk 作为后端

前端选型:
前期实现的时候想着项目没那么大,或许就几个echarts图,所以就纯html + js + 网上找的css模板 做了一个页面。 后面要拓展的时候发现这么写下去实在太麻烦了,得找个框架和组件库用用。由于项目也不大,最后选了vue3。

Flask

Flask github

一番体验下来,Flask 还是十分好入手的, 有点像 Express, 仅需一些代码就可以创建一个WEB应用。

安装Flask

# 安装最新版本
pip3 install flask
# 指定安装版本
pip3 install flask==2.0.2

创建文件

创建一个 main.py文件。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, World!"

此时 python ./main.py, flask 应用就会运行在 127.0.0.1:5000 上

Vue3

安装

在以前Vue2中,往往会通过安装cli来安装。
npm install -g @vue/cli

在官方推荐使用 create-vue 来创建基于 Vite 的新项目

官方安装地址

需要Node.js version 18.0及以上

$ npm create vue@latest

根据需要选择组件或风格

✔ Project name: … <your-project-name>
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit testing? … No / Yes
✔ Add an End-to-End Testing Solution? … No / Cypress / Playwright
✔ Add ESLint for code quality? … No / Yes
✔ Add Prettier for code formatting? … No / Yes

Scaffolding project in ./<your-project-name>...
Done.

执行install, 并运行项目

$ cd <your-project-name>
$ npm install
$ npm run dev

之后访问 http://localhost:5173就可以了
image.png

vue3 生命周期

image.png

开发中遇到的问题

vue3语法问题

由于第一次使用vue, 有很多代码都不知如何写。

比如,搜索某一个组件的初始化,有两种不同的写法。

有的文章这么写:

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return {
      count
    }
  },

  mounted() {
    console.log(this.count)
  }
}
</script>
<template>
  <button @click="count++">{{ count }}</button>
</template>

有的文章这么写

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>

后来看官方教程知道: <script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。

总之还是推荐看 官方教程 来学习。

学基础的用法不算太难,结合对之前学另一门框架的了解可以很快上手。

比如之前学过angular。

angular 中 ngOnInit 对应的就是 vue 中的 onMount()

ngDestrory 对应的就是 unMount()

再查看如何新建组件, 如何引入路由, 如何页面跳转,再引入一个组件库,一个简单的前端就搭建完了。

响应式

Vue响应式

如果学习过angular的话就会知道:Angular 的变更检测机制是基于 Zone.js 的,它会监控 JavaScript 执行上下文,并在异步操作完成后执行变更检测。

Angular 采用了自动全局变更检测的策略,所以视图的状态可以定义在任何地方,可以通过可变的方式在任何地方进行修改,状态是普通的 js 对象,没有包装器或者 getter setter 访问器。

由于没学过vue3, 使用过程中发现下面的代码,并不能检测实际count的变化, 页面始终显示的是初始化的值

<script setup>
let count = 0;
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>

于是简单学习了一下。

Vue 3 的响应式系统主要依赖于 Proxy 对象来实现数据变化的监听

所以,我们要把基础变量用代理进行包装。

官方文档:响应式基础 中提到,推荐使用 ref() 函数来声明响应式状态:

把 count 包装成响应式:

import { ref } from 'vue'

const count = ref(0)

并且,在script中使用的时候,需要用 .value 的方式获取, 而在html模板中不需要,因为会自动解包。

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {{ count }}
  </button>
</template>

Vue的自动检测就是这么实现的:

  1. 组件首次渲染,Vue 会追踪在渲染过程中使用的每一个 ref。
  2. 一个 ref 被修改
  3. 触发追踪它的组件的一次重新渲染。

我们知道在标准的 JavaScript 中,检测普通变量的访问或修改是行不通的。

所以Vue提供了ref()函数作为代理对象包装基础变量

其实这个函数就是简单的代理模式实现:

// 伪代码,不是真正的实现
const myRef = {
  _value: 0,
  get value() {
    track()
    return this._value
  },
  set value(newValue) {
    this._value = newValue
    trigger()
  }
}

Angular响应式

值得一提的是,新版的Angular V16的时候推出了下一代响应式语言: Signals,在V17正式作为主打功能之一。

似乎看来Angular 正在把大部分Change Detection 概念换成Signal,要把Zone代替掉, 也就是说: 将改变 Angular 底层的变更检测系统。

简单看起来,Signals是与Vue中的 ref 类似的响应性基础类型

const count = signal(0)

count() // 访问值
count.set(1) // 设置值
count.update((v) => v + 1) // 通过前值更新

与 Vue 的 ref 相比,Angular 中 Signals

  • () 比 .value 略微省事,但更新值却更冗长;
  • 没有 ref 解包:总是需要通过 () 来访问值。这使得值的访问在任何地方都是一致的

在angualr V17 中, 提供了signals: true,表示在 Signals 组件中只能使用 Signal 绑定。

@Component({
  selector: 'my-signal-based-component',
  signals: true,
})
export class MySignalBasedComponent {

基于 Signal 的组件会采用本地变更检测,ZoneJS 检测到的事件不会触发 Signal 组件的变更检测,只有组件视图绑定的 Signal 变更了才会触发变更检测

更多可以查看 官方文档: angular signals


weiweiyi
1k 声望123 粉丝