vscode用vue框架2,续写登陆页面逻辑,以及首页框架的搭建

目录

前言:

一、实现登录页信息验证逻辑

1.实现登录数据双向绑定

2.验证用户输入数据是否和默认数据相同

补充知识1:

知识点补充2:

二、首页和登录页之间的逻辑(1)

1. 修改路由,使得程序被访问先访问首页

知识点补充3:

 三、搭建基本首页框架

(1)在element-plus官网上找到对应的结构,

(2)解决!白色背景未填充完全,

 四、首页和登录页之间的逻辑(2)

(1)在index.vue页面做如下修改

(2)登录页实现数据的传递,以及跳转到首页,

(3)编写退出登录功能

(4)实现登陆后显示当前账户的用户名,做如下修改即可:

(5)修改一下导航栏的边距

(6) 解决多用户登陆的时候登陆验证问题

 补充知识5:

 五、完善首页顶部导航栏

 补充知识6:

六、文章主要代码

1.login.vue代码

2.index.vue文件代码

3.util.js代码

4.最后效果:


前言:

写在前面,还是一样,最后会给出主要页面代码,本文章记录了写代码中遇到的问题,以及解决过程和解决方法,相信小伙伴们看后能收获颇多~

一、实现登录页信息验证逻辑

1.实现登录数据双向绑定

下面添加的代码分析:
        在script块中定义默认用户信息的变量user,这个变量有两个属性,一个为username和pwd,再定义接受用户的信息的变量loginform,注意这次两个属性初始值为空字符串。同时在上方template块中的 <el-input> 组件的标签中,添加 v-model="loginform.username",以实现与 Vue 实例中 loginform 对象中 username 属性的双向数据绑定。并在登录button中添加点击事件,实现点击按钮时触发 Vue 实例中名为 commit 的表达式

2.验证用户输入数据是否和默认数据相同

(1)导入element样式”消息提示ELMessage“,并定义一个函数表达式,它将一个匿名函数赋值给变量 commit,在该函数中判断,如果账号密码相同,则弹出登录成功!否则,则弹出失败,代码如下:

补充知识1:

我们都知道,在 JavaScript 中,函数可以通过两种主要方式定义:函数表达式和函数声明。

function conmmit(){  }   //这个是函数声明

var  commit=function(){ }  //这个是函数表达式

上面两行代码中都定义了一个名为commit的函数,他们有什么区别呢?如下:

①函数声明:用这种方式定义的函数,我们既可以在 声明前调用函数,也可以在 声明后调用该函数。是由于在代码执行之前,解释器会先读取函数的声明,所以声明前调用函数并不会产生语法错误,这个特征叫做函数声明提升

下面举一个在函数声明前调用该函数的例子

// 调用函数声明前调用函数
console.log(add(2, 3)); // 输出: 5// 函数声明
function add(a, b) {return a + b;
}// 在函数声明后调用函数
console.log(add(5, 7)); // 输出: 12

②函数表达式:是指将一个匿名函数赋值给一个变量。这种方式不会被提升,因此必须在定义之后调用,即在使用匿名函数之前,必须先进行赋值操作,否则将会引起错误。

// 尝试在定义前调用函数表达式
console.log(subtract(2, 3)); // TypeError: subtract is not a function// 函数表达式
var subtract = function(a, b) {return a - b;
};// 在函数表达式定义后调用函数
console.log(subtract(5, 7)); // 输出: -2

为什么会引起错误?当你尝试在赋值之前调用一个函数表达式时,JavaScript 会认为你在调用一个未定义的函数。这是因为变量声明被提升,但初始化仍然在原来的位置。因此,在函数表达式赋值之前,变量 subtract 的值是 undedefined 作为fined,调用 un函数会导致错误。

 (2)发现输入不了字,用户输入不了数据,因为输入那一直默认是空字符串,我们引入ref来定义响应式变量,实现数据的修改与访问。引入 ref,为变量都用上ref,使其变成响应式数据,下面函数访问也对应的添加上.value来访问该属性的值

发现能输入数据了,但是是明文,所以修改一下密码那的type为password

               

 知识点补充2:

Vue3中Ref与Reactive详解

ref是Vue3提供的一个基础响应式API,用于创建一个包装过的响应式对象。通过ref,我们可以轻松地将一个普通值变成一个可响应的对象。

reactive是Vue3提供的另一个响应式API,与ref相比,reactive更适用于包裹复杂的对象,使得对象内部的各个属性都变成响应式的。

创建 Ref。在 Vue 3 中,可以使用 ref 函数来创建一个 Ref,如下所示:

import { ref } from 'vue';const count = ref(0); // 创建一个 Ref,初始值为 0

访问 Ref。通过 value 属性来访问和修改 Ref 的值:

console.log(count.value); // 访问 Ref 的值
count.value++; // 修改 Ref 的值

在模板中使用 Ref 。直接访问 Ref 对象即可,Vue 会自动处理 value 属性:

<template><p>{{ count }}</p><button @click="count++">Increment</button>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);return {count};}
};
</script>

Ref 的特性

  • Ref 对象本质上是一个包装器,通过 .value 访问和修改内部值。
  • 自动追踪其引用的变化,并在视图中进行响应更新。

创建 Reactive 对象。在 Vue 3 中,可以使用 reactive 函数来创建一个响应式代理对象:

import { reactive } from 'vue';const state = reactive({count: 0,message: 'Hello Vue'
});

访问 Reactive 对象。直接访问和修改 Reactive 对象的属性即可,无需额外的 .value 属性:

console.log(state.count); // 访问 Reactive 对象的属性
state.count++; // 修改 Reactive 对象的属性

在模板中使用 Reactive 对象,直接访问对象的属性即可:

<template><p>{{ state.count }}</p><button @click="state.count++">Increment</button>
</template><script>
import { reactive } from 'vue';export default {setup() {const state = reactive({count: 0});return {state};}
};
</script>

Reactive 的特性

  • Reactive 可以包含任意深度的嵌套对象,所有嵌套属性都将具有响应性。
  • Vue 3 使用 Proxy 实现响应式,可以捕获对象的读取、写入和删除等操作。

区别和适用场景

  • Ref 适合管理单个基本类型值,如数字、布尔值等,通过 .value 属性访问和修改。
  • Reactive 适合管理复杂的对象和数组结构,使整个对象及其属性具有响应性。

二、首页和登录页之间的逻辑(1)

1. 修改路由,使得程序被访问先访问首页

(1)新建文件,index.vue,这个就是首页的文件名,并为其添加三大块结构

(2)修改路由。在index.js文件做如下修改,使得访问该网页先访问首页 

知识点补充3

在 Vue.js 和 Vue Router 中,路由定义可以采用多种方式来引入组件,这里说一下我常用的两个

①静态引入组件:在应用启动时就会引入所有路由定义的组件。即使用户没有访问某个路由对应的页面,该页面的组件也会被提前加载。

import HomeView from '../views/HomeView.vue';
import AboutView from '../views/AboutView.vue';const routes = [{ path: '/', component: HomeView },{ path: '/about', component: AboutView }
];

②按需引入组件(懒加载):使用动态 import 语法,当用户访问特定路由时,才会加载相应的组件。这种方式通常称为懒加载

const routes = [{ path: '/', component: () => import('../views/HomeView.vue') },{ path: '/about', component: () => import('../views/AboutView.vue') }
];

③使用场景

  • 静态引入:适用于核心页面或非常小的应用,组件数量不多且需要快速加载。
  • 按需引入:适用于大型应用或有大量路由的应用,通过懒加载可以显著优化性能和用户体验。

 三、搭建基本首页框架

我们整体是上下结构,上面是顶部导航栏,下面左侧是菜单,右侧是展示的数据

(1)在element-plus官网上找到对应的结构,

        查看其对应源码,仿写,element-plus中如下图:

 代码编写如下:效果在第二张图,我们先编写的导航栏,发现导航栏左右两侧的白色背景并没有填充到头,怎么解决呢

(2)解决!白色背景未填充完全,

我们去查看element源码,发现没啥问题,又去写好的网页上右键-->检查-->选择元素工具(一个箭头),发现header的class样式中的el-header-padding属性导致两边有间隔,这个时element的全局样式,我们访问不了,所以我们在自己的代码中直接为header添加局部样式,强制修改这个属性为0,发现就没有空白了,解决!发现错误的方式在第一张图,修改的代码在第二张图,效果在第三张图

知识点补充:
paddingmargin 区别
①共同点:是 CSS 中用于设置元素间隔的两种不同属性 

②区别(定义):
padding 用于设置元素内容与元素边框之间的内边距。它增加了元素的可点击区域,但不会影响元素的外部间距。

margin 用于设置元素边框外部与其他元素或容器边界之间的外边距。它用于元素之间的间距,不会影响元素的内部内容。

 四、首页和登录页之间的逻辑(2)

        通过编写逻辑,实现访问首页的时候检查登陆状态,未登录则跳转登录

(1)在index.vue页面做如下修改

代码解析:在script块中写逻辑,在下面的代码中分为四部分:

序号①是引入所需的ref,onMounted函数,引入路由,并将获得路由实例赋值给router。

序号②部分先是打印了传过来的JSON对象,然后打印了传过来的JSON对象转换成JS对象,将他们都输出在console控制台上。

序号③部分是写了检查是否登录的函数,第一行用三目运算符来做了一个判断,如果从本地存储中得到键名为loginInfo(可以理解为关键字)的本地存储项,则为真,则把这个本地存储项从JSON对象转换为JS对象并赋值给loginUser,如果没有获取到,则返回null,赋值给loginUser,第三行做了一个判断,如果loginUser的为空,为真,再取反,则为假,则跳转到登陆页,否则则不跳转,实际实现了发现本地存储中没有登录的信息,则跳转去登陆,若有,则不跳转
注意在序号③中loginUser值的取反内部过程:
if (!loginUser) 中的 !loginUser 表达式会首先将 loginUser 的值转换为布尔类型。根据i的语句做判断时隐式转换规则得(紧后面补充知识点中有):
如果 loginUser 的值是 null 或者 undefined,它会被转换为 true,因为 null 和 undefined 是假值。
如果 loginUser 的值是一个对象或者其他非假值,它会被转换为 false,因为非假值被视为真值。

序号④这部分是通过onMounted 钩子确保在组件渲染完成后立即执行 checkLogin() 函数

(2)登录页实现数据的传递,以及跳转到首页,

        在login.vue中的script块中编写如下代码

(3)编写退出登录功能

        在template块中写下面的布局

在script块中编写这个函数,就是把存储的用户信息删除,调用checkLogin函数,再次检测是否登录,则实现了退出

下面这三块的写法好处:

  • 将初始化逻辑封装在 init 函数中,使得 onMounted 钩子函数的作用更加明确。
  • 如果在其他地方也需要初始化逻辑(例如在其他生命周期钩子或事件处理中),可以直接调用 init 函数,而不必重复写逻辑。

(4)实现登陆后显示当前账户的用户名,做如下修改即可:

有个问题:大家可以看一下,我明明传过来的是username,但是显示的时候却是得调用userName,在首页部分打印了一下传过来的值

 console.log(localStorage.getItem("loginInfo"));

 console.log(JSON.parse(localStorage.getItem('loginInfo')))

发现传过来是大写的userName

查了好多原因,原来传过来的时候是userName(就是我原来传过一次,后来为了格式相同,就改了),改了之后,但是浏览器的本地存储是存着原来的名(userName),所以名字并没有修改成功,只要清理一下本地内存即可,清理的方法如下:

接着修改下面代码即可

效果如下:

(5)修改一下导航栏的边距

效果如下: 

(6) 解决多用户登陆的时候登陆验证问题

定义了一个响应式的数组来存储用户登录信息对象,暂且定义了三个。,如下:

修改登陆按钮的点击事件函数

最后效果如下:

发现有多个用户后,显示登录成功和登陆失败,都显示,而且当前用户的username也不显示,检查了一下,发现当我输入username,pwd,会遍历所有的登录信息,来匹配,匹配不上就会显示登陆失败,所以会显示多个登陆成功,登陆失败

解决方法!:写一个存在测试,查看是否存在一个登录信息与匹配,不是要获得这个值,如果有的话才获得这个值,(这个值就是登陆信息),修改代码如下:

 发现解决了,右边登录账号名称也显示了

来解释一下这两段代码的逻辑区别
修改前的代码:在每次循环中如果当前用户不匹配就显示错误信息,这意味着如果正确用户在列表的最后一个位置,前面的每一次循环都会错误地显示错误信息。
修改后的代码︰只在所有用户检查完毕且未找到匹配用户时才显示错误信息。

补充知识5:

①LocalStorage(本地存储)常用函数

本地存储(Local Storage) 是一种更现代的客户端存储方式,提供了更大的存储空间,不会自动发送到服务器。

// 设置一个本地存储项
localStorage.setItem('username', 'John Doe');// 读取一个键名为username的本地存储项
console.log(localStorage.getItem('username'));// 删除一个本地存储项
localStorage.removeItem('username');// 清除所有本地存储项
localStorage.clear();

②本地存储和cookie的区别:

特性Cookie本地存储(Local Storage)
存储大小约 4KB约 5MB
生命周期可设置过期时间永久存储,除非手动删除
作用域特定域名和路径相同域名
数据传输每次请求时自动发送给服务器仅存储在客户端,不自动发送
使用场景会话管理、用户偏好、跟踪和分析持久化数据、大量数据、本地配置
③在 JavaScript 中, 条件语句(如 if 语句)在判断表达式时会进行隐式类型转换,将表达式的值转换为布尔类型。这种类型转换遵循以下规则:
隐式类型转换:表达式在条件语句中使用时,会自动转换为布尔类型。具体规则如下:
  • 假值:当表达式的值为假值时,条件为假(即 false)。JavaScript 中的假值包括 false、null、undefined、空字符串 ''、数字 0、NaN。
  • 真值:除了假值之外的所有值都被视为真值(即 true)。
JSON对象和JS对象互相转换方法
JavaScript 对象可以通过 JSON.stringify() 方法转换为 JSON 字符串,而 JSON 字符串可以通过 JSON.parse() 方法转换为 JavaScript 对象。

⑤JSON对象和JS对象实例

JS:
const person = {name: 'John',age: 30,hobbies: ['reading', 'swimming'],address: {city: 'New York',zip: 10001},greet: function() {return `Hello, my name is ${this.name}.`;}
};
JSON:
{"name": "John","age": 30,"hobbies": ["reading", "swimming"],"address": {"city": "New York","zip": 10001}
}

 五、完善首页顶部导航栏

给顶部导航栏添加一个时间,使它显示当前时间,新建文件夹common,在里面新建文件util.js,获取当前时间,并定义显示的格式,并导出,在index.vue中调用这个函数(先引入这个文件)

在script块中编写如下:

在template块中添加这个表达式

效果如下:

发现时间月份应该+1,因为现在是6月,其他时间应该显示两位数 ,年月日的日没有显示出来,再次修改:
①在util.js文件里添加判断,当少于两位数时,就补0,如下:

②在index.vue中的script块中做如下修改:就是把那个定时函数写道init()函数里,由init函数加载到onMounted函数里面。

效果实现后,就是,每秒都变数字,自动变,不用刷新页面。

补充知识6:

①解释util.js导出函数:
SimpleDateFormat: SimpleDateFormat 的具体含义:
在 export default { SimpleDateFormat: SimpleDateFormat } 中:
属性名: SimpleDateFormat 是对象的属性名。
属性值: SimpleDateFormat 是前面定义的函数。
在这种情况下,SimpleDateFormat 是一个函数,作为对象的属性值被导出。这样就可以,当你在其他文件中导入这个模块时,可以通过对象的属性名来访问和调用SimpleDateFormat 函数。

setInterval 函数解释:
这个函数是一个JavaScript 内置的函数,用于设置一个周期性调用函数的定时器。它会在指定的时间间隔(以毫秒为单位)重复执行一个函数。

@在路径中的使用
在 Vue 项目中,@ 通常是一个路径别名,指代项目的根目录(src 目录)。这种路径别名可以使导入模块的路径更加简洁和易读,而不必使用相对路径(如 ../../ )。

六、文章主要代码

1.login.vue代码

<template><div class="login-container dis-h"><div class="login-form  dis-h"><div class="dis-v left"><span> 欢迎~ </span><span> 智慧农业物联网 </span></div><div class="dis-v right"><div class="username dis-h"><el-input placeholder="请输入用户名" prefix-icon="User" v-model="loginform.username" /></div><div class="pwd dis-h"><el-input type="password" placeholder="请输入密码" prefix-icon="Lock" v-model="loginform.pwd" /></div><div class="btn dis-h"><el-button size="large" style= "width:220px; background-color:#626aef; color:#fff; font-weight:bold;" @click="commit" >登录</el-button></div></div>   </div></div>
</template>
<script setup>import { User,Lock } from '@element-plus/icons-vue'import { ElMessage } from 'element-plus'import {useRouter} from 'vue-router'import { ref } from 'vue'var router=useRouter();
//   定义默认的用户数据var userList =ref([{username:"111",pwd:"111"},{username:"222",pwd:"222"},{username:"333",pwd:"333"}])// 接收用户输入的数据var loginform=ref({username:"",pwd:"",})//   验证用户输入的用户名和密码是否和内部存储的数据一样var commit=function(){// 循环遍历数组的每一个元素,并将每个元素依次赋值给 item。在循环体内,for(var item of userList.value ){if(item.username==loginform.value.username&&item.pwd==loginform.value.pwd){var has_user=true;break;}}if(has_user){localStorage.setItem("loginInfo",JSON.stringify({username:loginform.value.username}));ElMessage.success("登陆成功!"); router.replace({path:"/"})}else{ElMessage.error("登陆失败!");}}</script>
<style >
.login-container{width: 100vw;height: 100vh;background-image: url('../assets/bg.png');background-size: 100%;align-items: center;justify-content: center;
}
.login-form{width: 600px;height: 300px;/* background-color: red; */}
.login-form .left{width: 50%;height: 100%;align-items: left;justify-content: center;font-size: 1.6rem;font-weight: bold;background:linear-gradient(to right bottom,rgba(136,209,234,0.80) 5%,rgba(215,193,187,0.80) 100% );color: #fff;text-indent:1rem;
}
.login-form .right{width: 50%;height: 100%;background-color: rgba(255, 255, 255, 0.90);align-items: center;justify-content: center;
}
.login-form .username,.pwd,.btn{padding: 0.5rem 0; }
</style>

2.index.vue文件代码

<template>
<div class="dis-h"><el-container  class="index-container" ><el-header class="index-header" ><div class="dis-h" style="width:100%; height:100%;"><div class="dis-h" style="width:200px;height:100%; align-items:center;justify-content: center;background-color:#fff;margin-right:5px;border-radius:3px">智慧农业物联网</div><div class="dis-h" style="background-color:#fff;height:100%;width:100%;border-radius:3px;align-items:center; justify-content: right;font-size: 0.65rem;"><div  class="dis-h " style="padding-right:15px; " ><span style="color:#000000; ">{{ dateTime }}</span></div><div  class="dis-h " style="padding-right:15px; " ><span style="color:#000000; ">{{ userInfo.username }}</span></div> <div  class="dis-h " style="padding-right:45px; " ><span style="color:#ff6666;" @click="lagout" >退出</span></div></div></div></el-header><el-container><el-aside >Aside</el-aside><el-main>Main</el-main></el-container></el-container></div>
</template>
<script setup>
import{ref,onMounted} from 'vue'
import {useRouter} from 'vue-router'
import util from '@/common/util'
var router =useRouter();var userInfo =ref({})
//定义时间变量,并用定时器定时执行获取时间函数
var dateTime = ref(util.SimpleDateFormat())//  console.log(localStorage.getItem("loginInfo"));
//  console.log(JSON.parse(localStorage.getItem('loginInfo')))
var checkLogin =function(){let loginUser = localStorage.getItem("loginInfo")?JSON.parse(localStorage.getItem('loginInfo')):null;if(!loginUser){router.replace({path:'/login'})}else{userInfo.value = loginUser;}
}var lagout=function(){localStorage.clear();checkLogin();
}var init=function(){
checkLogin();
setInterval(function(){dateTime.value= util.SimpleDateFormat()
},1000)
}onMounted(function(){init();})
</script>
<style >
.index-container{width:100vw;height: 100vh;background-color: #d8d8d8;
}
.index-header{--el-header-padding: 5px 5px !important;/* 上右下左 */--el-header-height: 50px !important;}</style>

3.util.js代码


function SimpleDateFormat(){var now =new Date();return now.getFullYear()+"-"+fill(now.getMonth()+1)+"-"+fill(now.getDate())+"-"+fill(now.getHours())+"-"+fill(now.getMinutes())+"-"+fill(now.getSeconds());
}function fill(str){if(str.toString().length<2){return "0"+str;}else{return str;}
}
export default{SimpleDateFormat:SimpleDateFormat
}

 4.最后效果:

这篇文章就到这里啦~ 下篇文章再见~ 


结束~

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

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

相关文章

numpy.ndarray数据计算及操作集锦

目录 1. numpy.ndarray各列求均值1.1 列1.2 行 1. numpy.ndarray各列求均值 1.1 列 要对 v_sec_trans 数组的每一列求均值&#xff0c;可以使用 numpy 库中的 mean 函数。以下是具体的代码示例&#xff1a; import numpy as np# 定义 v_sec_trans 数组 v_sec_trans np.array…

Qt 实战(5)布局管理器 | 5.1、DPI对布局的影响

文章目录 一、DPI对布局的影响1、什么是DPI&#xff1f;2、DPI对布局的影响3、优化布局以适应不同DPI4、总结 前言&#xff1a; 在开发跨平台桌面应用程序时&#xff0c;DPI&#xff08;Dots Per Inch&#xff0c;每英寸点数&#xff09;是一个不可忽视的因素。DPI决定了屏幕上…

【STM32】STM32通过I2C实现温湿度采集与显示

目录 一、I2C总线通信协议 1.I2C通信特征 2.I2C总线协议 3.软件I2C和硬件I2C 二、stm32通过I2C实现温湿度&#xff08;AHT20&#xff09;采集 1.stm32cube配置 RCC配置&#xff1a; SYS配置&#xff1a; I2C1配置&#xff1a; USART1配置&#xff1a; GPIO配置&#…

二叉树经典OJ练习

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 二叉树经典OJ练习 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 前置说…

python:psutil获取指定进程Cpu及Memory使用的GUI界面

1导入依赖库 import os import psutil import time from pyecharts import options as opts from pyecharts.charts import Line import PySimpleGUI as sg from datetime import datetime from concurrent.futures import ThreadPoolExecutor import ctypes import sys2主界面…

八、(正点原子)Linux内核定时器实验

定时器是我们最常用到的功能&#xff0c;一般用来完成定时功能&#xff0c;本章我们就来学习一下 Linux 内核提供的定时器 API 函数&#xff0c;通过这些定时器 API 函数我们可以完成很多要求定时的应用。 Linux内核也提供了短延时函数&#xff0c;比如微秒、纳秒、毫秒延时函数…

YOLO系列--Anchor Based Anchor Free

一、Anchor based 1.1 Anchor的定义 Anchor也被称为锚框&#xff0c;预先设置目标的大概位置&#xff0c;然后再在这些预设框的基础上进行精细化的调整。调整过程被包括分类 判断预设框是属于正样本 or 负样本-和回归调整预测框的位置。 1.2 Anchor的产生 Anchor box是指在…

长尾分布(Long-tailed Distribution)

长尾分布&#xff08; L o n g − t a i l e d D i s t r i b u t i o n Long-tailed\ Distribution Long−tailed Distribution&#xff09;是统计学和概率论中的一个重要概念&#xff0c;用于描述一组数据中尾部&#xff08;即远离均值的部分&#xff09;包含了相对较多极端值…

【Linux基础】SSH登录

SSH简介 安全外壳协议&#xff08;Secure Shell Protocol&#xff0c;简称SSH&#xff09;是一种加密的网络传输协议&#xff0c;可在不安全的网络中为网络服务提供安全的传输环境。 SSH通过在网络中建立安全隧道来实现SSH客户端与服务器之间的连接。 SSH最常见的用途是远程登…

LeetCode 算法:二叉树的最大深度 c++

原题链接&#x1f517;&#xff1a;二叉树的最大深度 难度&#xff1a;简单⭐️ 题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,…

【高考选专业 | 家长篇】2024,计算机何去何从?小P老师带你看

目录 2024年&#xff0c;计算机相关专业还值得选择吗&#xff1f;1.行业竞争现状2.专业前景分析 2024年&#xff0c;计算机相关专业还值得选择吗&#xff1f; 随着2024年高考落幕&#xff0c;数百万高三学生又将面临人生中的重要抉择&#xff1a;选择大学专业。有人欢喜&#x…

如何在Java中实现高效的缓存机制

如何在Java中实现高效的缓存机制 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 引言 在大多数软件系统中&#xff0c;缓存机制是提高性能和响应速度的关键技…

操作系统真象还原:用户进程

第11章-用户进程 这是一个网站有所有小节的代码实现&#xff0c;同时也包含了Bochs等文件 11.1 为什么要有任务状态TSS Linux 任务切换未采用 Intel 的做法&#xff0c;而是用了一套自己的方法&#xff0c;只是用了 TSS 的一小部分功能。 操作系统最直接控制的就是 CPU&…

ubuntu22.04笔记: 更换为阿里源

没有按照LTS 版本 会遇到下面问题&#xff1a; 参考&#xff1a;https://zhuanlan.zhihu.com/p/691625646 Ubuntu 22.04代号为&#xff1a;jammy Ubuntu 20.04代号为&#xff1a;focal Ubuntu 19.04代号为&#xff1a;disco Ubuntu 18.04代号为&#xff1a;bionic Ubuntu …

对于C++ 程序员来说,35岁魔咒是否存在?

大家常说程序员职业生涯会在35岁左右遇到所谓的“35岁魔咒”。这意味着在这个年龄段&#xff0c;程序员可能会面临就业不稳定或职业发展的挑战。对于C程序员来说&#xff0c;这个问题更加引人关注。 随着时间的推移&#xff0c;技术行业不断演进&#xff0c;新的编程语言层出不…

vue上传文件拿到File,下载文件到本地

vue中使用upload组件上传pdf文件&#xff0c;拿到File内容后&#xff0c;下载pdf文件到本地vue中根据url下载pdf文件到本地 File文件内容的格式 注意&#xff1a;如果使用iview的upload组件上&#xff0c;要获取File文件&#xff0c;需要在before-upload钩子上获取 async down…

Ubuntu iso 镜像下载 步骤截图说明

Ubuntu镜像下载&#xff0c;在这个网址&#xff1a; Enterprise Open Source and Linux | Ubuntu 步骤如下图所示&#xff1a; 1、登入网址 2、点击Get Ubuntu 3、点击Download Ubuntu Desktop 后续点击Downloadload 24.04 LTS直接下载就行 如果需要下载其它版本&#xf…

风速预测 | 基于MATLAB的无迹卡尔曼滤波算法UKF、SVR-UKF、ANN-Kalman等时间序列风速预测模型

基本描述 基于MATLAB的无迹卡尔曼滤波算法UKF、SVR-UKF、ANN-Kalman等时间序列风速预测模型 模型步骤 时间序列风速预测模型基于MATLAB的无迹卡尔曼滤波算法&#xff08;Unscented Kalman Filter, UKF&#xff09;、SVR-UKF&#xff08;Support Vector Regression - Unscent…

STM32学习之一:什么是STM32

目录 1.什么是STM32 2.STM32命名规则 3.STM32外设资源 4. STM32的系统架构 5. 从0到1搭建一个STM32工程 学习stm32已经很久了&#xff0c;因为种种原因&#xff0c;也有很久一段时间没接触过stm32了。等我捡起来的时候&#xff0c;发现很多都已经忘记了&#xff0c;重新捡…

【Java反射】getDeclaredField(String name) 和 getField(String name)区别

getDeclaredField(String name) 和 getField(String name) 都是Java反射API中用于获取类字段&#xff08;成员变量&#xff09;的方法&#xff0c;但它们之间存在一些关键的区别&#xff1a; getDeclaredField(String name) 功能&#xff1a;这个方法返回的是声明在该类中的指…