React 基本使用

create-react-app

创建 react 项目的脚手架。

React 基本用法

jsx 语法

变量、表达式

import React from 'react';class JSXBaseDemo extends React.Component {constructor(props) {super(props);this.state = {name: '章三'};}render() {// 获取变量 插值const pElem = <p>{this.state.name}</p>;return pElem;// // 表达式// const exprElem = <p>{this.state.flag ? 'yes' : 'no'}</p>;// return exprElem;}
}export default JSXBaseDemo;

class、style

/* style.css */
.title {font-size: 30px;color: red;
}
import React from 'react';
import './style.css';class JSXBaseDemo extends React.Component {constructor(props) {super(props);this.state = {};}render() {// classconst classElem = <p className="title">设置 css class</p>;return classElem;// // style// const styleData = { fontSize: '30px',  color: 'blue' };// const styleElem = <p style={styleData}>设置 style</p>;// // 内联写法,注意 {{ 和 }}// // const styleElem = <p style={{ fontSize: '30px',  color: 'blue' }}>设置 style</p>;// return styleElem;}
}export default JSXBaseDemo;

子元素和组件

import React from 'react';
import List from '../List';class JSXBaseDemo extends React.Component {constructor(props) {super(props);this.state = {imgUrl: 'https://img1.mukewang.com/5a9fc8070001a82402060220-140-140.jpg'};}render() {// 子元素const imgElem = <div><p>我的头像</p><img src="xxxx.png"/><img src={this.state.imgUrl}/></div>;return imgElem';// // 加载组件// const componentElem = <div>//     <p>JSX 中加载一个组件</p>//     <hr />//     <List />// </div>;// return componentElem;}
}export default JSXBaseDemo;

原生 html

import React from 'react';class JSXBaseDemo extends React.Component {constructor(props) {super(props);this.state = {};}render() {// 原生 htmlconst rawHtml = '<span>富文本内容<i>斜体</i><b>加粗</b></span>';const rawHtmlData = {__html: rawHtml // 注意,必须是这种格式};const rawHtmlElem = <div><p dangerouslySetInnerHTML={rawHtmlData}></p><p>{rawHtml}</p></div>;return rawHtmlElem;}
}export default JSXBaseDemo;

条件

  • if else
  • 三元表达式
  • 逻辑运算符:&&||
.btn-white {color: #333;
}
.btn-black {background-color: #666;color: #fff;;
}
import React from 'react';
import './style.css';class ConditionDemo extends React.Component {constructor(props) {super(props);this.state = {theme: 'black'};}render() {const blackBtn = <button className="btn-black">black btn</button>;const whiteBtn = <button className="btn-white">white btn</button>;// // if else// if (this.state.theme === 'black') {//     return blackBtn;// } else {//     return whiteBtn;// }// // 三元运算符// return <div>//     { this.state.theme === 'black' ? blackBtn : whiteBtn }// </div>;// &&return <div>{ this.state.theme === 'black' && blackBtn }</div>;}
}export default ConditionDemo;

列表渲染

  • map
  • key
import React from 'react';class ListDemo extends React.Component {constructor(props) {super(props);this.state = {list: [{id: 'id-1',title: '标题1'},{id: 'id-2',title: '标题2'},{id: 'id-3',title: '标题3'}]};}render() {return <ul>{this.state.list.map((item, index) => {// 这里的 key 和 Vue 的 key 类似,必填,不能是 index 或 randomreturn <li key={item.id}>index {index}; id {item.id}; title {item.title}</li>;})}</ul>;}
}export default ListDemo;

事件

bind this

  • 非严格模式下,dom 事件中的 this 都是运行时的,就是浏览器执行的,指向的是 window
  • 严格模式下,这里的 this 指向 undefined

箭头函数为什么能解决 bind this

  • 箭头函数的 this 永远指向上级作用域。
  • 箭头函数的 this 是在定义函数时绑定的,不是在执行过程中绑定的。
  • 也就是说,函数在定义时,this 就继承了定义函数的对象。
import React from 'react';class EventDemo extends React.Component {constructor(props) {super(props);this.state = {name: 'zhangsan'};// 修改方法的 this 指向this.clickHandler1 = this.clickHandler1.bind(this);}render() {// this - 使用 bindreturn <p onClick={this.clickHandler1}>{this.state.name}</p>;// // this - 使用静态方法// return <p onClick={this.clickHandler2}>//     clickHandler2 {this.state.name}// </p>;}clickHandler1() {// console.log('this....', this) // this 默认是 undefinedthis.setState({name: 'lisi'});}// 静态方法,this 指向当前实例clickHandler2 = () => {this.setState({name: 'lisi'});}
}export default EventDemo;

关于 event 参数

import React from 'react';class EventDemo extends React.Component {constructor(props) {super(props);this.state = {};}render() {// eventreturn <a href="https://imooc.com/" onClick={this.clickHandler3}>click me</a>;}// 获取 eventclickHandler3 = (event) => {// 阻止默认行为event.preventDefault(); // 阻止冒泡event.stopPropagation(); // 指向当前元素,即当前元素触发console.log('target', event.target); // 指向当前元素,假象!!!console.log('current target', event.currentTarget); // 注意,event 其实是 React 封装的。// 可以看 __proto__.constructor 是 SyntheticEvent 组合事件// 不是原生的 Event ,原生的 MouseEventconsole.log('event', event); console.log('event.__proto__.constructor', event.__proto__.constructor);// 原生 event 如下。其 __proto__.constructor 是 MouseEventconsole.log('nativeEvent', event.nativeEvent);// 指向当前元素,即当前元素触发console.log('nativeEvent target', event.nativeEvent.target); // 指向 document !!!console.log('nativeEvent current target', event.nativeEvent.currentTarget;); // 1. event 是 SyntheticEvent ,模拟出来 DOM 事件所有能力// 2. event.nativeEvent 是原生事件对象// 3. 所有的事件,都被挂载到 document 上 (React17 事件绑定到 root 上)// 4. 和 DOM 事件不一样,和 Vue 事件也不一样}
}export default EventDemo;

传递自定义参数

import React from 'react';class EventDemo extends React.Component {constructor(props) {super(props);this.state = {list: [{id: 'id-1',title: '标题1'},{id: 'id-2',title: '标题2'},{id: 'id-3',title: '标题3'}]};}render() {// 传递参数 - 用 bind(this, a, b)return <ul>{this.state.list.map((item, index) => {return <li key={item.id} onClick={this.clickHandler4.bind(this, item.id, item.title)}>index {index}; title {item.title}</li>;})}</ul>;}// 传递参数// 最后追加一个参数,即可接收 eventclickHandler4(id, title, event) {console.log(id, title);console.log('event', event); }
}export default EventDemo;

组件和 props (类型检查)

受控组件

  • 表单的值受 state 控制。
  • value 指向 stateonChange 事件监听,使用 setState 修改值。
import React from 'react';class FormDemo extends React.Component {constructor(props) {super(props);this.state = {name: 'zhangsan'};}render() {// 受控组件return <div><p>{this.state.name}</p><label htmlFor="inputName">姓名:</label> {/* 用 htmlFor 代替 for */}<input id="inputName" value={this.state.name} onChange={this.onInputChange} /></div>;}onInputChange = (e) => {this.setState({name: e.target.value});}
}export default FormDemo;

表单的使用

import React from 'react';class FormDemo extends React.Component {constructor(props) {super(props);this.state = {name: 'zhangsan',info: '个人信息',city: 'beijing',flag: true,gender: 'male'};}render() {// // 受控组件// return <div>//     <p>{this.state.name}</p>//     <label htmlFor="inputName">姓名:</label> {/* 用 htmlFor 代替 for */}//     <input id="inputName" value={this.state.name} onChange={this.onInputChange}/>// </div>;// textarea - 使用 valuereturn <div><textarea value={this.state.info} onChange={this.onTextareaChange}/><p>{this.state.info}</p></div>;// // select - 使用 value// return <div>//     <select value={this.state.city} onChange={this.onSelectChange}>//         <option value="beijing">北京</option>//         <option value="shanghai">上海</option>//         <option value="shenzhen">深圳</option>//     </select>//     <p>{this.state.city}</p>// </div>;// // checkbox// return <div>//     <input type="checkbox" checked={this.state.flag} onChange={this.onCheckboxChange}/>//     <p>{this.state.flag.toString()}</p>// </div>;// // radio// return <div>//     male <input type="radio" name="gender" value="male" checked={this.state.gender === 'male'} onChange={this.onRadioChange}/>//     female <input type="radio" name="gender" value="female" checked={this.state.gender === 'female'} onChange={this.onRadioChange}/>//     <p>{this.state.gender}</p>// </div>;}onInputChange = (e) => {this.setState({name: e.target.value});}onTextareaChange = (e) => {this.setState({info: e.target.value});}onSelectChange = (e) => {this.setState({city: e.target.value});}onCheckboxChange = () => {this.setState({flag: !this.state.flag});}onRadioChange = (e) => {this.setState({gender: e.target.value});}
}export default FormDemo;

组件使用

  • props 传递数据
  • props 传递函数
  • props 类型检查
import React from 'react';
import PropTypes from 'prop-types';class Input extends React.Component {constructor(props) {super(props);this.state = {title: ''};}render() {return <div><input value={this.state.title} onChange={this.onTitleChange}/><button onClick={this.onSubmit}>提交</button></div>;}onTitleChange = (e) => {this.setState({title: e.target.value});}onSubmit = () => {const { submitTitle } = this.props;submitTitle(this.state.title); // 'abc'this.setState({title: ''});}
}// props 类型检查
Input.propTypes = {submitTitle: PropTypes.func.isRequired
};class List extends React.Component {constructor(props) {super(props);}render() {const { list } = this.props;return <ul>{list.map((item, index) => {return <li key={item.id}><span>{item.title}</span></li>;})}</ul>;}
}
// props 类型检查
List.propTypes = {list: PropTypes.arrayOf(PropTypes.object).isRequired
};class Footer extends React.Component {constructor(props) {super(props);}render() {return <p>{this.props.text}{this.props.length}</p>;}
}class TodoListDemo extends React.Component {constructor(props) {super(props);// 状态(数据)提升this.state = {list: [{id: 'id-1',title: '标题1'},{id: 'id-2',title: '标题2'},{id: 'id-3',title: '标题3'}],footerInfo: '底部文字'};}render() {return <div><Input submitTitle={this.onSubmitTitle}/><List list={this.state.list}/><Footer text={this.state.footerInfo} length={this.state.list.length}/></div>;}onSubmitTitle = (title) => {this.setState({list: this.state.list.concat({id: `id-${Date.now()}`,title})});}
}export default TodoListDemo;

state 和 setState

setState

  • 不可变值
  • 可能是异步更新 (针对 React <= 17)
    • 直接使用是异步更新,在第二个参数的回调函数中可以拿到最新的 state
    • setTimeout 中使用是同步
    • 自定义的 dom 事件,是同步的
  • 可能会被合并 (针对 React <= 17)
    • 异步更新,setState 传入的参数是对象,那么在更新前会被合并
    • 异步更新,setState 传入的参数是函数,不会被合并
import React from 'react';class StateDemo extends React.Component {constructor(props) {super(props);// 第一,state 要在构造函数中定义this.state = {count: 0};}render() {return <div><p>{this.state.count}</p><button onClick={this.increase}>累加</button></div>;}increase = () => {// // 第二,不要直接修改 state ,要使用不可变值 -----------------------// // this.state.count++; // 错误// this.setState({//     count: this.state.count + 1 // SCU// });// 操作数组、对象的的常用形式// 第三,setState 可能是异步更新(有可能是同步更新) ------------------// this.setState({//     count: this.state.count + 1// }, () => {//     // 联想 Vue $nextTick - DOM//     // 回调函数中可以拿到最新的 state//     console.log('count by callback', this.state.count); // });// console.log('count', this.state.count); // 异步的,拿不到最新值// // setTimeout 中 setState 是同步的// setTimeout(() => {//     this.setState({//         count: this.state.count + 1//     });//     console.log('count in setTimeout', this.state.count);// }, 0);// 自己定义的 DOM 事件,setState 是同步的。// 第四,state 异步更新的话,更新前会被合并 --------------------------// // 传入对象,会被合并(类似 Object.assign )。执行结果只一次 +1// this.setState({//     count: this.state.count + 1// });// this.setState({//     count: this.state.count + 1// });// this.setState({//     count: this.state.count + 1// });// 传入函数,不会被合并。执行结果是 +3this.setState((prevState, props) => {return {count: prevState.count + 1};});this.setState((prevState, props) => {return {count: prevState.count + 1};});this.setState((prevState, props) => {return {count: prevState.count + 1};});}// bodyClickHandler = () => {//     this.setState({//         count: this.state.count + 1//     });//     console.log('count in body event', this.state.count);// }// componentDidMount() {//     // 自己定义的 DOM 事件,setState 是同步的//     document.body.addEventListener('click', this.bodyClickHandler);// }// componentWillUnmount() {//     // 及时销毁自定义 DOM 事件//     document.body.removeEventListener('click', this.bodyClickHandler);//     // clearTimeout// }
}export default StateDemo;// -------------------------- 我是分割线 -----------------------------// // 不可变值(函数式编程,纯函数) - 数组
// const list5Copy = this.state.list5.slice();
// list5Copy.splice(2, 0, 'a'); // 中间插入/删除
// this.setState({
//     list1: this.state.list1.concat(100), // 追加
//     list2: [...this.state.list2, 100], // 追加
//     list3: this.state.list3.slice(0, 3), // 截取
//     list4: this.state.list4.filter(item => item > 100), // 筛选
//     list5: list5Copy // 其他操作
// });
// // 注意,不能直接对 this.state.list 进行 push pop shift unshift splice 等,这样违反不可变值// // 不可变值 - 对象
// this.setState({
//     obj1: Object.assign({}, this.state.obj1, {a: 100}),
//     obj2: {...this.state.obj2, a: 100}
// })
// // 注意,不能直接对 this.state.obj 进行属性设置,这样违反不可变值

React18 中的 setState

  • React 组件事件:异步更新 + 合并 state
  • DOM 事件、setTimeout:异步更新 + 合并 state
  • Automatic Batching 自动批处理
import { useState, useEffect } from 'react';function useStateDemo() { const [value, setValue]= useState(100);function clickHandler() { // // 合并后 +1// setValue(value + 1); // setValue(value + 1); // setValue(value + 1); // console.log(value); // 100 异步更新 setTimeout(() => {// 合并后 +1setValue(value + 1); setValue(value + 1); setValue(value + 1); console.log(value); // 100 异步更新 });} useEffect(() =>{ // 自绑定 DOM 事件 document.getElementById('btn2').addEventListener('click', () => { // 合并后 +1setValue(value + 1); setValue(value + 1); setValue(value + 1); console.log(value); // 100 异步更新 });});return <div> <span>{value}</span> <button onClick={clickHandler}>increase1</button> <button id="btn2">increase2</button> </div>;
}
  • React <= 17:只有 React 组件事件才批处理(合并 + 异步)
  • React18:所有事件都自动批处理 Automatic Batching

组件生命周期

react 生命周期图示

在这里插入图片描述

  • 初始化阶段:constructor
  • 挂载阶段:componentDidMount
  • 更新阶段:componentDidUpdate
  • 卸载阶段:componentWillUnmount

展示不常用的生命周期图示

在这里插入图片描述

  • shouldComponentUpdate:可以控制是否更新

父子组件生命周期

  • 父组件先 constructor,然后子组件才 constructor
  • 子组件先 componentDidMount,然后父组件 componentDidMount
  • 子组件先 componentDidUpdate,然后父组件 componentDidUpdate
  • 父组件先触发 componentWillUnmout,然后子组件触发 componentWillUnmount

FQA

  1. React 事件为何 bind this
    • 非严格模式下,dom 事件中的 this 都是运行时的,就是浏览器执行的,指向的是 window
    • 严格模式下,这里的 this 指向 undefined
  2. 箭头函数为什么能解决 bind this
    • 箭头函数的 this 永远指向上级作用域:箭头函数的 this 是在定义函数时绑定的,不是在执行过程中绑定的。也就是说,函数在定义时,this 就继承了定义函数的对象。
  3. react 的事件和 vue 的区别。
    • vue 的事件是原生 eventMouseEvent),事件是绑定在当前元素上的
    • react 的事件是 SyntheticEventReact16 事件是绑定在 document 上的,React17 后是绑定在 root 上的;react 获取原生事件是通过 event.nativeEvent 获取。
  4. react 为什么对事件对象进行二次封装?
    • 兼容各个平台,不仅仅是 DOM ,如 react native
  5. React17 为什么将事件绑定到 root 上?
    • 有利于多个 React 版本并存(document 只有一个,而 root 可以有多个),例如微前端。
      在这里插入图片描述
  6. 描述 react 组件的生命周期。
  • 初始化阶段:constructor
  • 挂载阶段:componentDidMount
  • 更阶段:componentDidUpdate
  • 卸载阶段:componentWillUnmount
  • 在更新阶段 componentDidUpdate 之前还有一个 shouldComponentUpdate:可以控制是否更新
  1. react 组件如何通讯?
    • 父子组件通过 props 传递数据
    • 可通过 context 从顶层组件向子孙组件进行下发数据
    • 使用 redux 可以全局组件共享状态

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/612550.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何用 Python 实现一个 “系统声音” 的实时律动挂件

前言 应该是三年前&#xff0c;我用 Esp8266 和 ws2812 实现了一个音乐律动灯带。就是电脑播放音乐时&#xff0c;灯带会随着系统内部音乐播放的频率而闪动不同色彩的灯珠。而当时用来监听系统声音的工具是一个博主提供的&#xff0c;除了实时采集声音外还通过 UDP 传递数据到…

玉米浸泡液植酸吸附树脂

植酸为环己六醇六磷酸&#xff0c;分子量为660&#xff0c;植酸钠为环己六醇六磷酸钠&#xff08;Na12C6H6O24P6&#xff09;分子量为924。 植酸用途&#xff1a;在食品工业中植酸钠可用作食品添设剂&#xff0c;菲丁&#xff08;植酸钙&#xff09;可用于生产肌醇&#xff0c…

vscode+markdown+plantuml+html

markdown-preview-enhanced plantuml配置 生成html侧边栏 --- html:toc: truetoc_depth: 6toc_float: truecollapsed: falsesmooth_scroll: true ---

多测师肖sir___接口自动化测试框架(python+request+unittest+ddt)讲解版

pythonrequestunittestddt 一、接口自动化测试框架&#xff08;pythonrequestunittestddtj 7个包&#xff09;讲解 首先我们新建一个新项目:名称zdh 二、在一个项目中&#xff1a;新建7个包 第一个包conf包用来填写配置参数、地址等 第二个包data 包用来存放测试用例的表格 第…

视频转gif的在线转换怎么操作?告别繁琐,轻松搞定

视频转gif的在线转换怎么操作&#xff1f;在当今社交媒体盛行的时代&#xff0c;GIF动图已经成为了我们表达自我、分享生活的重要方式。但是&#xff0c;很多小伙伴可能还在为如何将心爱的视频片段转为GIF而烦恼。今天&#xff0c;我们就来一起学习如何将视频轻松转换为GIF的在…

数据库编程大赛冠军:郑凌云:0.67秒通过百万级数据评测!SQL代码惊现神之一手!

12月27日&#xff0c;NineData和云数据库技术社区主办&#xff0c;华为云、火山引擎、开源中国、云和恩墨、TDengine、云猿生数据、DORIS、ITPUB等协办单位和媒体&#xff0c;共同举办了本次《数据库编程大赛》。大赛题目「用一条SQL给出扑克牌24点的计算表达式」。 以下冠军选…

JS 高频面试题

JS 的数据类型有哪些&#xff0c;有什么区别 基本数据类型&#xff08;Undefined、Null、Boolean、Number、String、Symbol&#xff09; 引用数据类型&#xff08;对象、数组和函数&#xff09; 区别&#xff1a; 原始数据类型直接存储在栈&#xff08;stack&#xff09;中的简…

【亲测有效】Win11 卸载MySQL5.7以及安装MySQL8.0.35

目录 一、卸载原来本地的mysql5.7 1.mysql服务部分 1.1停止mysql服务 1.2删除mysql服务 2.卸载 MySQL程序 3.残余文件的清理 3.1删除mysql安装的目录 3.2删除mysql数据存放的目录 3.3删除mysql自定义目录 4.清理注册表 5.删除环境变量配置 二、安装mysql8.0.35 1.…

【Spring Boot】SpringMVC入门

1.什么是springMVC MVC就是把一个项目分成了三部分&#xff1a; MVC是一种思想。Spring进行了实现,称为Spring MVC。SpringBoot是创建SpringMVC项目的一种方式而已。springMVC对于MVC做出了一些改变&#xff1a; 当前阶段,MVC的概念又发生了一些变化,后端开发人员不涉及前端页…

众和策略股市行情分析:了解散户的典型特征

散户特色如下&#xff1a; 1、出资规模小&#xff1a;散户的出资规模一般比较小&#xff0c;资金量有限&#xff0c;无法对商场发生显著的影响。资金量较小的一起&#xff0c;其对危险的承受能力也相对较弱。 2、缺少危险意识&#xff1a;散户往往缺少危险意识&#xff0c;没…

2024年网络工程师10大必备软件,最新安装包分享

功夫再高&#xff0c;也怕菜刀。作为网络工程师&#xff0c;我们手中的菜刀是什么&#xff1f; 以下10大网工必备软件都已整理好安装包&#xff0c;需要的朋友可以在文末获取。 1、Cisco Packet Tracer&#xff08;思科模拟器&#xff09; Cisco Packet Tracer 是由Cisco公司发…

详解JavaScript中的WeakMap和WeakSet

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ ✨ 前言 内存管理一直是JavaScript这门语言中的难点和痛点。由于其自动垃圾回收机制的限制,在某些场…

HTTPS详解及openssl简单使用

OpenSSL 中文手册 | OpenSSL 中文网 本文介绍https传输协议中涉及的概念&#xff0c;流程&#xff0c;算法&#xff0c;如何实现等相关内容。 HTTP传输过程 HTTP 之所以被 HTTPS 取代&#xff0c;最大的原因就是不安全&#xff0c;至于为什么不安全&#xff0c;看了下面这张图…

如何通过 Prompt 优化大模型 Text2SQL 的效果

前言 在上篇文章中「大模型LLM在Text2SQL上的应用实践」介绍了基于SQLDatabaseChain的Text2SQL实践&#xff0c;但对于逻辑复杂的查询在稳定性、可靠性、安全性方面可能无法达到预期&#xff0c;比如输出幻觉、数据安全、用户输入错误等问题。 本文将从以下4个方面探讨通过Pr…

Python办公自动化 – 操作NoSQL数据库和自动化图像识别

Python办公自动化 – 操作NoSQL数据库和自动化图像识别 以下是往期的文章目录&#xff0c;需要可以查看哦。 Python办公自动化 – Excel和Word的操作运用 Python办公自动化 – Python发送电子邮件和Outlook的集成 Python办公自动化 – 对PDF文档和PPT文档的处理 Python办公自动…

前端-基础 表格标签 - 相关属性详解

目录 相关属性 &#xff1a; align 属性 &#xff1a; border 属性 &#xff1a; cellpadding 属性 &#xff1a; cellspacing 属性 &#xff1a; width 属性 &#xff1a; height 属性 &#xff1a; 首先&#xff0c;需要声明的是 表格标签这部分属性&…

Hive基础题-1

别看我&#xff0c;不看答案我也不会写 正因为不会写&#xff0c;所以才要每天一练 本地hive练习题 SET hive.exec.mode.local.autotrue; -- 默认 false SET hive.exec.mode.local.auto.inputbytes.max50000000; SET hive.exec.mode.local.auto.input.files.max5; -- 默认 4# …

Hotspot源码解析-第十七章-虚拟机万物创建(三)

17.4 Java堆空间内存分配 分配Java堆内存前&#xff0c;我们先通过两图来了解下C堆、Java堆、内核空间、native本地空间的关系。 1、从图17-1来看&#xff0c;Java堆的分配其实就是从Java进程运行时堆中选中一块内存区域来映射 2、从图17-2&#xff0c;可以看中各内存空间的…

thinkphp学习07-数据库的数据查询

单数据查询 单条数据查询&#xff0c;一般是一维数组 Db::table()中 table 必须指定完整数据表&#xff08;包括前缀&#xff09;&#xff0c;如果配置了表前缀&#xff0c;Db::name()中可以忽略 如果希望只查询一条数据&#xff0c;可以使用 find()方法&#xff0c;需指定 wh…

Django 框架添加管理员,完成对普通用户信息管理

前情回顾&#xff1a;Django框架 完成用户登录注册 文章目录 1.创建管理员2.完善管理员功能2.1增加管理员登录功能2.2完善展示用户信息功能2.3完善修改用户信息功能2.4完善删除用户信息功能 1.创建管理员 一般管理员都是直接指定&#xff0c;不开放页面注册&#xff0c;可以直…