From 66f9a82ff81440f6837823b8e4d280281b0c1306 Mon Sep 17 00:00:00 2001 From: xxx Date: Sun, 19 May 2024 12:27:22 +0800 Subject: [PATCH 1/2] bj --- .../20240513-PiniaAPI.md" | 202 ++++++++++++++ .../20240514-API\345\222\214REST.md" | 30 ++ ...15\344\271\240\344\273\243\347\240\201.md" | 261 ++++++++++++++++++ 3 files changed, 493 insertions(+) create mode 100644 "\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" create mode 100644 "\347\274\252\346\242\223\344\272\250/20240514-API\345\222\214REST.md" create mode 100644 "\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" diff --git "a/\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" "b/\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" new file mode 100644 index 0000000..46a8f11 --- /dev/null +++ "b/\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" @@ -0,0 +1,202 @@ +### 一、什么是状态管理 +- 对于大项目来说,组件多,状态零散分布在许多组件和组件之间的交互操作中,这时候就需要状态管理,理论上来说,每一个 Vue 组件实例都已经在“管理”它自己的响应式状态了 +- 示例如下: + +```html + + + + + +``` + +- 上面代码中,当add方法不断被调用时,count的值就会不断增加显示在页面上,这样叫做“状态自管理”,由以下几个部分组成: + - 状态(state):驱动整个应用的数据源 + - 视图(view):对状态的一种声明式映射 + - 交互(actions):状态根据用户在视图中的输入而作出相应变更的可能方式 + + 但是以上只是一个单向数据流,即从view上出发action改变state,state的改变最终回到view上,然而,当我们有多个组件共享一个共同的状态时,就会出现以下问题: + - 多个组件依赖于同一状态 + - 来自不同视图的交互也可能需要更改同一份状态 + +### 二、使用Pinia实现状态管理 +#### 1.安装 + +```js +npm install pinia +``` + +#### 2.创建pinia实例 + +```js +// main.js +import {createPinia} from 'pinia'; +let app = createApp(App); +const pinia = createPinia(); +app.use(pinia); +``` + +#### 3.pinia的基本用法 +##### 1.创建store实例 + +```js +// stores/counter.js +import { defineStore } from 'pinia'; + +// Option对象写法 +export const useCountStore = defineStore('count',{ + state:()=>{ + return {count:0} + }, + // 也可以写为 + // state: () => ({ count: 0 }),这里用大括号是为了让他以对象的形式返回出来 + actions:{ + onClick(){ + this.count++ + } + } +}) + +// Setup函数写法 +export const useCountStore = defineStore('count',()=>{ + let count = ref(0); + function onClick(){ + count.value++; + }; + return{count,onClick} +}) +``` + +store的参数: + - 第一个参数要求不可重复 + - 第二个参数可以接受两种类型的值:Setup函数或Option对象 + - Setup: + - ref() 就是 state 属性,computed() 就是 getters,computed() 就是 getters + - 在 setup store 中返回 state 的所有属性 + - Option:state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods) +##### 2.在组件中使用store + +```html + + +``` + +从store解构 +为了从 store 中提取属性时保持其响应性,需要使用 storeToRefs(),但是可以直接从 store 中解构 action + +```js +import {storeToRefs} from 'pinia'; +const counter = useCountStore(); +// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性 +const {count} = storeToRefs(counter); +// 作为 action 的 onClick 可以直接解构 +const {onClick} = counter +``` + +### 三、State +#### 1.概念 +state是 store 的核心,被定义为一个返回初始状态的函数 +#### 2.访问 + +```js +const counter = useCountStore(); +// 访问的是state的初始状态 +// 也可以直接对其读写 +const data = counter.count; +``` +#### 3.重置 +通过调用 store 的 $reset() 方法将 state 重置为初始值 + +```js +// counter.js +export const useCountStore = defineStore('count',()=>{ + let count = ref(0); + function onClick(){ + count.value++; + }; + // 创建自己的 $reset() 方法 + function $reset(){ + count.value=0; + } + return{count,onClick,$reset} +}) +``` + +```html + + + + +``` +#### 4.变更 +用 store.count++ 直接改变 store,还可以调用 $patch 方法 +#### 5.替换 +不能完全替换掉 store 的 state,因为那样会破坏其响应性,还是使用patch + +### 四、Getter +Getter 完全等同于 store 的 state 的计算属性 + +```js +export const useCountStore = defineStore('count',{ + state:()=>{ + return {count:1} + }, + actions:{ + onClick(){ + this.count++ + } + }, + getters: { + doubleCount: (state) => state.count * 2, + }, +}) +``` +- 大多数时候,getter 仅依赖 state,不过,有时它们也可能会使用其他 getter,通过 this,你可以访问到其他任何 getter +- getter 只是幕后的计算属性,所以不可以向它们传递任何参数。不过,你可以从 getter 返回一个函数,该函数可以接受任意参数 + +```js +export const useUsersStore = defineStore('users', { + getters: { + getUserById: (state) => { + // 可以返回函数,这个返回的函数可以接受容易参数 + return (userId) => state.users.find((user) => user.id === userId) + }, + }, +}) + // 调用 +``` + +### 五、Action +Action 相当于组件中的方法,也可通过 this 访问整个 store 实例,而且是可以异步的 \ No newline at end of file diff --git "a/\347\274\252\346\242\223\344\272\250/20240514-API\345\222\214REST.md" "b/\347\274\252\346\242\223\344\272\250/20240514-API\345\222\214REST.md" new file mode 100644 index 0000000..fff961c --- /dev/null +++ "b/\347\274\252\346\242\223\344\272\250/20240514-API\345\222\214REST.md" @@ -0,0 +1,30 @@ +## API和REST + +### API + +Application Programming Interface(应用程序接口)是它的全称。简单的理解就是,API是一个接口 + +### REST + +HTTP总共包含八种方法: + +``` +GET +POST +PUT +DELETE +OPTIONS +HEAD +TRACE +CONNECT +``` + +● 2xx = Success(成功) + +● 3xx = Redirect(重定向) + +● 4xx = User error(客户端错误) + +● 5xx = Server error(服务器端错误) + +我们常见的是200(请求成功)、404(未找到)、401(未授权)、500(服务器错误)... \ No newline at end of file diff --git "a/\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" "b/\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" new file mode 100644 index 0000000..87ece2d --- /dev/null +++ "b/\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" @@ -0,0 +1,261 @@ +## app.vue + +```vue + + + + + + +``` + +## app.js + +```js +import Koa from 'koa' +import bodyparser from 'koa-bodyparser' +import Router from 'koa-router' +import cors from 'koa2-cors' +import { Sequelize, DataTypes, Op, where } from 'sequelize' + +let app = new Koa(); +let router = new Router(); + +let sequelize = new Sequelize('userDB', 'sa', '123456', { + dialect: "mssql", + host: "localhost" +}) + +let User = sequelize.define('users', { + name: { type: DataTypes.STRING }, + age: { type: DataTypes.INTEGER } +}) + +User.sync() + +router.get('/user/:id?', async (ctx) => { + let id = ctx.params.id * 1 + let keyword = ctx.query.keyword + let data + if (keyword) { + data = await User.findAll({ + where: { + [Sequelize.Op.or]: [ + { id: { [Sequelize.Op.like]: "%" + keyword + "%" } }, + { name: { [Sequelize.Op.like]: "%" + keyword + "%" } }, + { age: { [Sequelize.Op.like]: "%" + keyword + "%" } }, + ] + } + }) + } else if (id) { + data = await User.findByPk(id) + } else { + data = await User.findAll() + } + ctx.body = { + msg: "查询成功", + code: 3000, + data: data + } +}) + +router.del('/user/:id', async (ctx) => { + let id = ctx.params.id * 1 + let data = await User.destroy({ + where: { id: id } + }) + ctx.body = { + msg: "删除成功", + code: 3000, + data: data + } +}) + +router.put('/user/:id', async (ctx) => { + let id = ctx.params.id * 1; + let obj = ctx.request.body; + let item = await User.findByPk(id) + let data + if (item) { + data = await User.update(obj, { + where: { id: id } + }) + ctx.body = { + msg: "修改成功", + code: 3000, + data: data + } + } else { + ctx.body = { + msg: "修改失败", + code: 4000, + data: data + } + } +}) + +router.post('/user',async(ctx)=>{ + let obj = ctx.request.body + let data + if(obj){ + data = await User.create(obj) + ctx.body = { + msg:"新增成功", + code:3000, + data:data + } + }else{ + ctx.body = { + msg:"新增失败", + code:4000, + data:data + } + } +}) + +app.use(bodyparser()) +app.use(cors()) +app.use(router.routes()) + +app.listen(3000,()=>{ + console.log(`服务已打开于:http://localhost:3000`); +}) +``` \ No newline at end of file -- Gitee From 0f1a6b18162a33d441186923c3213055a2d9d69f Mon Sep 17 00:00:00 2001 From: xxx Date: Sun, 19 May 2024 23:09:19 +0800 Subject: [PATCH 2/2] bj --- .../20240513-PiniaAPI.md" | 202 -------------- ...15\344\271\240\344\273\243\347\240\201.md" | 261 ------------------ 2 files changed, 463 deletions(-) delete mode 100644 "\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" delete mode 100644 "\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" diff --git "a/\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" "b/\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" deleted file mode 100644 index 46a8f11..0000000 --- "a/\347\274\252\346\242\223\344\272\250/20240513-PiniaAPI.md" +++ /dev/null @@ -1,202 +0,0 @@ -### 一、什么是状态管理 -- 对于大项目来说,组件多,状态零散分布在许多组件和组件之间的交互操作中,这时候就需要状态管理,理论上来说,每一个 Vue 组件实例都已经在“管理”它自己的响应式状态了 -- 示例如下: - -```html - - - - - -``` - -- 上面代码中,当add方法不断被调用时,count的值就会不断增加显示在页面上,这样叫做“状态自管理”,由以下几个部分组成: - - 状态(state):驱动整个应用的数据源 - - 视图(view):对状态的一种声明式映射 - - 交互(actions):状态根据用户在视图中的输入而作出相应变更的可能方式 - - 但是以上只是一个单向数据流,即从view上出发action改变state,state的改变最终回到view上,然而,当我们有多个组件共享一个共同的状态时,就会出现以下问题: - - 多个组件依赖于同一状态 - - 来自不同视图的交互也可能需要更改同一份状态 - -### 二、使用Pinia实现状态管理 -#### 1.安装 - -```js -npm install pinia -``` - -#### 2.创建pinia实例 - -```js -// main.js -import {createPinia} from 'pinia'; -let app = createApp(App); -const pinia = createPinia(); -app.use(pinia); -``` - -#### 3.pinia的基本用法 -##### 1.创建store实例 - -```js -// stores/counter.js -import { defineStore } from 'pinia'; - -// Option对象写法 -export const useCountStore = defineStore('count',{ - state:()=>{ - return {count:0} - }, - // 也可以写为 - // state: () => ({ count: 0 }),这里用大括号是为了让他以对象的形式返回出来 - actions:{ - onClick(){ - this.count++ - } - } -}) - -// Setup函数写法 -export const useCountStore = defineStore('count',()=>{ - let count = ref(0); - function onClick(){ - count.value++; - }; - return{count,onClick} -}) -``` - -store的参数: - - 第一个参数要求不可重复 - - 第二个参数可以接受两种类型的值:Setup函数或Option对象 - - Setup: - - ref() 就是 state 属性,computed() 就是 getters,computed() 就是 getters - - 在 setup store 中返回 state 的所有属性 - - Option:state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods) -##### 2.在组件中使用store - -```html - - -``` - -从store解构 -为了从 store 中提取属性时保持其响应性,需要使用 storeToRefs(),但是可以直接从 store 中解构 action - -```js -import {storeToRefs} from 'pinia'; -const counter = useCountStore(); -// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性 -const {count} = storeToRefs(counter); -// 作为 action 的 onClick 可以直接解构 -const {onClick} = counter -``` - -### 三、State -#### 1.概念 -state是 store 的核心,被定义为一个返回初始状态的函数 -#### 2.访问 - -```js -const counter = useCountStore(); -// 访问的是state的初始状态 -// 也可以直接对其读写 -const data = counter.count; -``` -#### 3.重置 -通过调用 store 的 $reset() 方法将 state 重置为初始值 - -```js -// counter.js -export const useCountStore = defineStore('count',()=>{ - let count = ref(0); - function onClick(){ - count.value++; - }; - // 创建自己的 $reset() 方法 - function $reset(){ - count.value=0; - } - return{count,onClick,$reset} -}) -``` - -```html - - - - -``` -#### 4.变更 -用 store.count++ 直接改变 store,还可以调用 $patch 方法 -#### 5.替换 -不能完全替换掉 store 的 state,因为那样会破坏其响应性,还是使用patch - -### 四、Getter -Getter 完全等同于 store 的 state 的计算属性 - -```js -export const useCountStore = defineStore('count',{ - state:()=>{ - return {count:1} - }, - actions:{ - onClick(){ - this.count++ - } - }, - getters: { - doubleCount: (state) => state.count * 2, - }, -}) -``` -- 大多数时候,getter 仅依赖 state,不过,有时它们也可能会使用其他 getter,通过 this,你可以访问到其他任何 getter -- getter 只是幕后的计算属性,所以不可以向它们传递任何参数。不过,你可以从 getter 返回一个函数,该函数可以接受任意参数 - -```js -export const useUsersStore = defineStore('users', { - getters: { - getUserById: (state) => { - // 可以返回函数,这个返回的函数可以接受容易参数 - return (userId) => state.users.find((user) => user.id === userId) - }, - }, -}) - // 调用 -``` - -### 五、Action -Action 相当于组件中的方法,也可通过 this 访问整个 store 实例,而且是可以异步的 \ No newline at end of file diff --git "a/\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" "b/\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" deleted file mode 100644 index 87ece2d..0000000 --- "a/\347\274\252\346\242\223\344\272\250/20240516-\345\244\215\344\271\240\344\273\243\347\240\201.md" +++ /dev/null @@ -1,261 +0,0 @@ -## app.vue - -```vue - - - - - - -``` - -## app.js - -```js -import Koa from 'koa' -import bodyparser from 'koa-bodyparser' -import Router from 'koa-router' -import cors from 'koa2-cors' -import { Sequelize, DataTypes, Op, where } from 'sequelize' - -let app = new Koa(); -let router = new Router(); - -let sequelize = new Sequelize('userDB', 'sa', '123456', { - dialect: "mssql", - host: "localhost" -}) - -let User = sequelize.define('users', { - name: { type: DataTypes.STRING }, - age: { type: DataTypes.INTEGER } -}) - -User.sync() - -router.get('/user/:id?', async (ctx) => { - let id = ctx.params.id * 1 - let keyword = ctx.query.keyword - let data - if (keyword) { - data = await User.findAll({ - where: { - [Sequelize.Op.or]: [ - { id: { [Sequelize.Op.like]: "%" + keyword + "%" } }, - { name: { [Sequelize.Op.like]: "%" + keyword + "%" } }, - { age: { [Sequelize.Op.like]: "%" + keyword + "%" } }, - ] - } - }) - } else if (id) { - data = await User.findByPk(id) - } else { - data = await User.findAll() - } - ctx.body = { - msg: "查询成功", - code: 3000, - data: data - } -}) - -router.del('/user/:id', async (ctx) => { - let id = ctx.params.id * 1 - let data = await User.destroy({ - where: { id: id } - }) - ctx.body = { - msg: "删除成功", - code: 3000, - data: data - } -}) - -router.put('/user/:id', async (ctx) => { - let id = ctx.params.id * 1; - let obj = ctx.request.body; - let item = await User.findByPk(id) - let data - if (item) { - data = await User.update(obj, { - where: { id: id } - }) - ctx.body = { - msg: "修改成功", - code: 3000, - data: data - } - } else { - ctx.body = { - msg: "修改失败", - code: 4000, - data: data - } - } -}) - -router.post('/user',async(ctx)=>{ - let obj = ctx.request.body - let data - if(obj){ - data = await User.create(obj) - ctx.body = { - msg:"新增成功", - code:3000, - data:data - } - }else{ - ctx.body = { - msg:"新增失败", - code:4000, - data:data - } - } -}) - -app.use(bodyparser()) -app.use(cors()) -app.use(router.routes()) - -app.listen(3000,()=>{ - console.log(`服务已打开于:http://localhost:3000`); -}) -``` \ No newline at end of file -- Gitee