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,一经查实,立即删除!

相关文章

【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; 目录 前置说…

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

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

【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…

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

第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…

STM32学习之一:什么是STM32

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

【驱动篇】龙芯LS2K0300之按键驱动

实验过程 实验目的&#xff1a; 在龙芯开发板上面验证GPIO按键的输入过程 ① 根据原理图连接按键板 ② 将4个i2c引脚的功能复用为GPIO ③ 注册input设备驱动&#xff0c;绑定中断处理函数&#xff0c;使用定时器消抖 原理图 4个按键引脚&#xff1a;CPU_I2C0_SCL -> G…

艺体培训机构管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;教师管理&#xff0c;学员管理&#xff0c;活动管理&#xff0c;课程管理&#xff0c;选课信息管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;论…

【会议征稿,ACM出版】2024年图像处理、智能控制与计算机工程国际学术会议(IPICE 2024,8月9-11)

2024年图像处理、智能控制与计算机工程国际学术会议&#xff08;IPICE 2024&#xff09;将于2024年8月9-11日在中国福州举行。本届会议由阳光学院、福建省空间信息感知与智能处理重点实验室、空间数据挖掘与应用福建省高校工程研究中心联合主办。 会议主要围绕图像处理、智能控…

分布式定时任务系列10:XXL-job源码分析之路由策略

传送门 分布式定时任务系列1&#xff1a;XXL-job安装 分布式定时任务系列2&#xff1a;XXL-job使用 分布式定时任务系列3&#xff1a;任务执行引擎设计 分布式定时任务系列4&#xff1a;任务执行引擎设计续 分布式定时任务系列5&#xff1a;XXL-job中blockingQueue的应用 …

Go语言的诞生背景

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

Linux操作系统处理器调度基本准则和实现

1&#xff0c;基本概念 在多道程序系统中&#xff0c;进程的数量往往多于处理机的个数&#xff0c;进程争用处理机的情况就在所难免。处理机调度是对处理机进行分配&#xff0c;就是从就绪队列中&#xff0c;按照一定的算法&#xff08;公平、低效&#xff09;选择一个进程并将…

mysql学习——SQL中的DDL和DML

SQL中的DDL和DML DDL数据库操作&#xff1a;表操作 DML添加数据修改数据删除数据 学习黑马MySQL课程&#xff0c;记录笔记&#xff0c;用于复习。 DDL DDL&#xff1a;Data Definition Language&#xff0c;数据定义语言&#xff0c;用来定义数据库对象(数据库&#xff0c;表&…

C语言入门课程学习笔记8:变量的作用域递归函数宏定义交换变量

C语言入门课程学习笔记8 第36课 - 变量的作用域与生命期&#xff08;上&#xff09;第37课 - 变量的作用域与生命期&#xff08;下&#xff09;实验—局部变量的作用域实验-变量的生命期 第38课 - 函数专题练习第39课 - 递归函数简介实验小结 第40课 - C 语言中的宏定义实验小结…