VUE2及其生态查漏补缺

1、数据代理概括

数据代理过程相当于是进行了 vm 代理 vm_data中的属性,vm._data 是与 我们vue文件中写的 data是全等的

//创建Vue实例let data = { //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。name:'atguigu',address:'北京'}new Vue({el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。data})Object.defineProperty(vm, 'name', {get(){return vm._data.name},set(value){vm._data.name = value}})

2、v-on:事件 

只有data里面的东西才会做数据劫持,代理,方法其实也可以写在data,但是会使vue实例变得冗余,因为对方法做了数据代理及劫持,这是没意义的操作

事件的基本使用:

      1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;

      2.事件的回调需要配置在methods对象中,最终会在vm上;

      3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;

      4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;

       5.@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参;

 2.1、事件修饰符

Vue中的事件修饰符:

          1.prevent:阻止默认事件(常用);

          2.stop:阻止事件冒泡(常用);

          3.once:事件只触发一次(常用);

          4.capture:使用事件的捕获模式,让事件在捕获阶段执行(默认事件是在冒泡阶段执行的);

          5.self:只有event.target是当前操作的元素时才触发事件;

          6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

2.2、键盘事件

1.Vue中常用的按键别名:

          回车 => enter

          删除 => delete (捕获“删除”和“退格”键)

          退出 => esc

          空格 => space

          换行 => tab (特殊,必须配合keydown去使用)

          上 => up

          下 => down

          左 => left

          右 => right

        2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

        3.系统修饰键(用法特殊):ctrl、alt、shift、meta

          (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。

          (2).配合keydown使用:正常触发事件。

        4.也可以使用keyCode去指定具体的按键(不推荐)

        5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

3、列表渲染 key

最终效果图

操作步骤:

复制张三-18到其对应的右侧输入框

李四-19、王五-20同上操作

然后点击添加老刘就会得到上述的效果,具体原因在 下面 3.1 有解释

demo代码

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>key的原理</title><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><!-- 遍历数组 --><h2>人员列表(遍历数组)</h2><button @click.once="add">添加一个老刘</button><ul><!-- 分别通过 index 与 id作为 key --><li v-for="(p,index) of persons" :key="index">{{p.name}}-{{p.age}}<input type="text"></li></ul></div><script type="text/javascript">Vue.config.productionTip = falsenew Vue({el:'#root',data:{persons:[{id:'001',name:'张三',age:18},{id:'002',name:'李四',age:19},{id:'003',name:'王五',age:20}]},methods: {add(){const p = {id:'004',name:'老刘',age:40}this.persons.unshift(p)}},})</script>
</html>

 3.1、index作为key

解释:

  1. 当index作为key的时候(没设置key时,默认也是以index作为key的)
  2. 我们一开始渲染的是左侧的三条数据,会生成三个虚拟dom节点,key 分别为0、1、2,
  3. 然后vue根据这三虚拟dom生成真正的三个dom节点,渲染到页面上去
  4. 当我们通过 unshift 逆序添加一个元素到列表时,破坏了原列表的顺序,生成四个虚拟节点
  5. vue会通过diff算法 将左侧(原本的)和右侧(新生成)的虚拟节点进行对比,主要是通过key,去对比
  6. 发现右侧key = 0的地方 文本节点与左侧key = 0的地方文本节点不一样,则在生成真实dom节点的时候,就会重新生成dom节点,对比input虚拟节点的时候,发现是一样的,则会复用已有的dom节点而此时,由于复用的是左侧key = 0 节点下的input,所以老刘对应的输入框本应是无值的变成了 张三-18,以此类推最终就会得到 右图所示的效果,出现数据错乱
  7. 而且如果是类似上述情况,涉及逆序破坏列表顺序的情况,使用idnex作为key,会造成效率问题,让本该复用的节点,得不到复用,重复创建dom节点,所以当是类似上述情况,使用唯一标识很重要,下面解释为啥使用唯一标识重要

3.2、唯一标识作为key

解释:

  1. 当唯一标识(这里是id)作为key的时候
  2. 我们一开始渲染的是左侧的三条数据,会生成三个虚拟dom节点,key 分别为001、002、003,
  3. 然后vue根据这三虚拟dom生成真正的三个dom节点,渲染到页面上去
  4. 当我们通过 unshift 逆序添加一个元素到列表时,破坏了原列表的顺序,生成四个虚拟节点
  5. vue会通过diff算法 将左侧(原本的)和右侧(新生成)的虚拟节点进行对比,主要是通过key,去对比
  6. 发现右侧key = 001的地方 文本节点与左侧key = 001的地方文本节点与input节点是一样的,则会复用已有的dom节点,此时就能正确显示,以此类推 002、003对应的节点杜能正确配对显示,所以就能得到我们想要的效果

4、vue监测数据改变的原理

引出问题

demo代码,注意要引入 vue.js (vue 2.xx.xx版本)

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>更新时的一个问题</title><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2>人员列表</h2><button @click="updateMei">更新马冬梅的信息</button><ul><li v-for="(p,index) of persons" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul></div><script type="text/javascript">Vue.config.productionTip = falseconst vm = new Vue({el:'#root',data:{persons:[{id:'001',name:'马冬梅',age:30,sex:'女'},{id:'002',name:'周冬雨',age:31,sex:'女'},{id:'003',name:'周杰伦',age:18,sex:'男'},{id:'004',name:'温兆伦',age:19,sex:'男'}]},methods: {updateMei(){// this.persons[0].name = '马老师' //奏效// this.persons[0].age = 50 //奏效// this.persons[0].sex = '男' //奏效this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'} //不奏效// this.persons.splice(0,1,{id:'001',name:'马老师',age:50,sex:'男'}) // 奏效}}}) </script>
</html>

一个属性一个属性的更改是可以检测到的,但是当是数组的整个对象更新的时候,就不行 

临时添加的对象属性,也不具有响应式(因为没有通过Object.defineProperty 进行劫持),除非使用$set添加的 ($set就相当于是重新使用 Object.defineProperty 进行数据劫持)

数组通过索引更改值,vue也检测不到,页面也不会实时更新(当然也可以使用set,就可以检测到了),必须通过数组的七个方法更新数组(push、pop、unshift、shift、splice、sort、reverse),vue才能检测到,因为vue对上述方法进行了重写

$set局限性不能vue实例/根数据对象身上使用 set, 会报错:避免添加响应式属性到xxx

5、其他

5.1、v-model 相关的三个修饰符

v-model的三个修饰符:

           lazy:失去焦点再收集数据

           number:输入字符串转为有效的数字

           trim:输入首尾空格过滤

5.2、过滤器

过滤器:

        定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。

        语法:

            1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}

            2.使用过滤器:{{ xxx | 过滤器名}}  或  v-bind:属性 = "xxx | 过滤器名"

        备注:

            1.过滤器也可以接收额外参数、多个过滤器也可以串联

            2.并没有改变原本的数据, 是产生新的对应的数据

5.3、内置指令

v-text指令:

            1.作用:向其所在的节点中渲染文本内容。

            2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。

v-html(慎用)

因为有了可能会在指令后面的内容中,插入一些获取 cookie的操作(document.cookie),这样就会导致xss攻击,也就是类似仿冒的操作,如果服务器返回的cookie 没有设置成 httpOnly ,则可以通过document.cookie 获取到,攻击者就可以获取到cookie,v-html 就有可能会带有,类似获取cookie,然后发送到攻击者的服务器的操作,所以如果要使用v-html 一定要确保是可信的,并进行相应的校验

 v-once 只加载一次,后续相关值改变, 此处值不作变更

  v-once指令:

            1.v-once所在节点在初次动态渲染后,就视为静态内容了。

            2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。

 v-pre

v-pre指令:

          1.跳过其所在节点的编译过程。

          2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。

5.4、自定义指令

自定义指令总结:

            一、定义语法:

                  (1).局部指令:

                        new Vue({                          

                            directives{指令名:回调函数}

                        })                                 

                  (2).全局指令:

                          Vue.directive(指令名,配置对象) 或   Vue.directive(指令名,回调函数)

            二、配置对象中常用的3个回调:

                  (1).bind:指令与元素成功绑定时调用。

                  (2).inserted:指令所在元素被插入页面时调用。

                  (3).update:指令所在模板结构被重新解析时调用。

            三、备注:

                  1.指令定义时不加v-,但使用时要加v-;

                  2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。

指令可以分为函数式写法与对象式写法

new Vue({el:'#root',data:{name:'尚硅谷',n:1},directives:{big(element,binding){console.log('big',this) //注意此处的this是window// console.log('big')element.innerText = binding.value * 10},fbind:{//指令与元素成功绑定时(一上来)bind(element,binding){element.value = binding.value},//指令所在元素被插入页面时inserted(element,binding){element.focus()},//指令所在的模板被重新解析时update(element,binding){element.value = binding.value}}}})

函数式写法就相当于只写了bind 与 update, 向上面这样bind、inserted、update都写,一些小细节的东西才能处理

5.5、Vm 与 Vc

关于this指向:

                (1).组件配置中:

                      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。

                (2).new Vue(options)配置中:

                      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

Vm是指Vue实例, Vc是指VueComponent实例,一般Vm中的$children 会有相应的Vc实例,如果是嵌套组件,则其下也会有$children  也会有Vc实例, Vm 与 Vc基本长一个样 ,且Vm创建的时候又el配置项用于指定服务于那个容器,而Vc则没有

1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype

2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

5.6、插件

 写法 plugins.js

export default {install(Vue,x,y,z){console.log(x,y,z)//全局过滤器Vue.filter('mySlice',function(value){return value.slice(0,4)})//定义全局指令Vue.directive('fbind',{//指令与元素成功绑定时(一上来)bind(element,binding){element.value = binding.value},//指令所在元素被插入页面时inserted(element,binding){element.focus()},//指令所在的模板被重新解析时update(element,binding){element.value = binding.value}})//定义混入Vue.mixin({data() {return {x:100,y:200}},})//给Vue原型上添加一个方法(vm和vc就都能用了),但是一般不这么做,需要慎重考虑Vue.prototype.hello = ()=>{alert('你好啊')}}
}

在项目入口文件中引入安装一下

import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import plugins from './plugins'
//关闭Vue的生产提示
Vue.config.productionTip = false//应用(使用)插件
Vue.use(plugins,1,2,3)
//创建vm
new Vue({el:'#app',render: h => h(App)
})

经过上面操作,这些定义好的过滤器、指令、mixin就可以全局使用了

5.7、npm 查看依赖版本

5.8、解决跨域方法

  •  服务端设置cors
  • jsonp,需要前后端配置,且只能处理get请求
  • 脚手架/打包工具 代理
  • nginx代理

6、生命周期

6.1、原理图

常用的生命周期钩子:

            1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。

            2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

        关于销毁Vue实例

            1.销毁后借助Vue开发者工具看不到任何信息。

            2.销毁后自定义事件会失效,但原生DOM事件依然有效。

            3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

7、事件总线

1、Vue原型对象上包含事件处理的方法

1)$on(eventName,listener):绑定自定义事件监听

2)$emit(eventName,data):分发自定义事件

3)$off(eventName):解绑自定义事件监听4)

$once(eventName,listener):绑定事件监听,但只能处理一次

2、所有组件实例对象的原型对象的原型对象就是Vue的原型对象

1)所有组件对象都能看到Vue原型对象上的属性和方法

2)Vue.prototype.$bus=newVue(),所有的组件对象都能看到$bus这个属性对象

 事件总线其实大概就是这样一个东西

new Vue({el:'#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this //安装全局事件总线},
})

8、Vuex

8.1、基础使用

vuex官网 都是使用

但是需要注意是,vue开发者工具只能检测到mutation 的动作

mapState、mapGetters使用

computed:{//靠程序员自己亲自去写计算属性/* sum(){return this.$store.state.sum},school(){return this.$store.state.school},subject(){return this.$store.state.subject}, *///借助mapState生成计算属性,从state中读取数据。(对象写法)// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),//借助mapState生成计算属性,从state中读取数据。(数组写法)...mapState(['sum','school','subject']),/* ******************************************************************** *//* bigSum(){return this.$store.getters.bigSum}, *///借助mapGetters生成计算属性,从getters中读取数据。(对象写法)// ...mapGetters({bigSum:'bigSum'})//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)...mapGetters(['bigSum'])},

mapMutations、mapActions 

methods: {//程序员亲自写方法/* increment(){this.$store.commit('JIA',this.n)},decrement(){this.$store.commit('JIAN',this.n)}, *///借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)...mapMutations({increment:'JIA',decrement:'JIAN'}),//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)// ...mapMutations(['JIA','JIAN']),/* ************************************************* *///程序员亲自写方法/* incrementOdd(){this.$store.dispatch('jiaOdd',this.n)},incrementWait(){this.$store.dispatch('jiaWait',this.n)}, *///借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)// ...mapActions(['jiaOdd','jiaWait'])},

模块化开发

 模块化的作用,顾名思义就是模块化,减少在同事间在协作的过程中可能会出现的冲突,代码结构更清晰,方便维护

9、vue-router

官网

9.1、params参数 

携带 params 参数进行路由跳转,必须使用 name,不能使用path

若路由定义了 props: true 则会将params 作为组件的props,可以在组件里面通过prosp获取

若props 直接返回对象也可以,也可以写成函数形式

 路由跳转方式:声明式导航 router-link、编程式导航,router.push/replace

9.2、路由守卫

全局路由守卫

//全局前置路由守卫————初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{console.log('前置路由守卫',to,from)if(to.meta.isAuth){ //判断是否需要鉴权if(localStorage.getItem('school')==='atguigu'){next()}else{alert('学校名不对,无权限查看!')}}else{next()}
})//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{console.log('后置路由守卫',to,from)document.title = to.meta.title || '管理系统'
})

路由独享守卫

{name:'zhuye',path:'/home',component:Home,meta:{title:'主页'},children:[{name:'xinwen',path:'news',component:News,meta:{isAuth:true,title:'新闻'},beforeEnter: (to, from, next) => {console.log('独享路由守卫',to,from)if(to.meta.isAuth){ //判断是否需要鉴权if(localStorage.getItem('school')==='xxxx'){next()}else{alert('学校名不对,无权限查看!')}}else{next()}}}
}

组件内路由守卫

export default {name:'About',/* beforeDestroy() {console.log('About组件即将被销毁了')},*//* mounted() {console.log('About组件挂载完毕了',this)window.aboutRoute = this.$routewindow.aboutRouter = this.$router},  */mounted() {// console.log('%%%',this.$route)},//通过路由规则,进入该组件时被调用beforeRouteEnter (to, from, next) {console.log('About--beforeRouteEnter',to,from)if(to.meta.isAuth){ //判断是否需要鉴权if(localStorage.getItem('school')==='xxxxx'){next()}else{alert('学校名不对,无权限查看!')}}else{next()}},//通过路由规则,离开该组件时被调用beforeRouteLeave (to, from, next) {console.log('About--beforeRouteLeave',to,from)next()}}

路由模式

hash 与 history

history 会将路由地址,当做请求资源的地址,所以会出现404问题,需要后端去做适配,区别那些前段路由,那些是后端路由才行 ,而hash就不会出现这个问题

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

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

相关文章

选哪个短剧系统源码好:全面评估与决策指南

在短剧内容创作和分享日益流行的今天&#xff0c;选择合适的短剧系统源码对于构建一个成功的短剧平台至关重要。短剧系统源码不仅关系到平台的稳定性和用户体验&#xff0c;还直接影响到内容创作者和观众的互动质量。本文将提供一份全面的评估指南&#xff0c;帮助您在众多短剧…

七一建党节|热烈庆祝中国共产党成立103周年!

时光荏苒&#xff0c;岁月如梭。 在这热情似火的夏日&#xff0c; 我们迎来了中国共产党成立103周年的重要时刻。 这是一个值得全体中华儿女共同铭记和庆祝的日子&#xff0c; 也是激励我们不断前进的重要时刻。 103年&#xff0c; 风雨兼程&#xff0c;砥砺前行。 从嘉兴…

拓扑排序[讲课留档]

拓扑排序 拓扑排序要解决的问题是给一个有向无环图的所有节点排序。 即在 A O E AOE AOE网中找关键路径。 前置芝士&#xff01; 有向图&#xff1a;有向图中的每一个边都是有向边&#xff0c;即其中的每一个元素都是有序二元组。在一条有向边 ( u , v ) (u,v) (u,v)中&…

解析QAnything启动命令过程

一.启动命令过程日志 启动命令bash ./run.sh -c local -i 0 -b hf -m Qwen-1_8B-Chat -t qwen-7b-chat。输入日志如下所示&#xff1a; rootMM-202203161213:/mnt/l/20230918_RAG方向/QAnything# bash ./run.sh -c local -i 0 -b hf -m Qwen-1_8B-Chat -t qwen-7b-chat From …

快钱支付股东全部股权已被质押!

根据近期工商信息&#xff0c;第三方支付机构快钱支付清算信息有限公司&#xff08;简称“快钱支付”&#xff09;实际控股方快钱金融服务&#xff08;上海&#xff09;有限公司&#xff08;简称“快钱金融”&#xff09;&#xff0c;作为出质股权标的企业&#xff0c;被出质给…

Python容器 之 列表--定义

1.什么是列表呢&#xff1f; 列表(list)是 Python 中使用最频繁的数据类型, 在其他语言中通常叫做数组, 专门用来存储一组数据 列表,list, 使用 [ ] 列表可以存放任意多个数据 列表中可以存放任意类型的数据 列表中数据之间 使用 逗号隔开 2.列表如何定义&#xff1f; &#…

面向阿克曼移动机器人(自行车模型)的LQR(最优二次型调节器)路径跟踪方法

线性二次调节器&#xff08;Linear Quadratic Regulator&#xff0c;LQR&#xff09;是针对线性系统的最优控制方法。LQR 方法标准的求解体系是在考虑到损耗尽可能小的情况下, 以尽量小的代价平衡其他状态分量。一般情况下&#xff0c;线性系统在LQR 控制方法中用状态空间方程描…

Redis慢查询

Redis慢查询 目录 Redis慢查询慢查询配置慢日志操作返回参数介绍 Redis的慢查询就是当命令执行时间超过预定的阈值后将这条命令记录下来&#xff0c;与MySQL的功能类似 慢查询配置 默认阈值是10毫秒&#xff0c;即10000微秒 临时修改阈值为20毫秒 127.0.0.1:6379> confi…

docker配置redis主从复制

下载redis,复制redis.conf 主节点(6379) 修改redis.conf # bind 127.0.0.1 # 注释掉这里 protected-mode no # 改为no port 6379从节点(6380) 修改redis.conf bind 127.0.0.1 protected-mode no # 改为no port 6380 replicaof 172.17.0.2 6379 # 这里的ip为主节点容器的i…

Zuul介绍

Zuul 是 Netflix 开源的一个云平台网络层代理&#xff0c;它主要用于路由、负载均衡、中间件通信和动态路由。Zuul 本质上是一个基于 JVM 的网关&#xff0c;它提供了以下功能&#xff1a; 1.路由&#xff1a;Zuul 允许客户端和服务器之间的所有入站和出站请求通过一个中心化的…

深度挖掘数据资产,洞察业务先机:利用先进的数据分析技术,精准把握市场趋势,洞悉客户需求,为业务决策提供有力支持,实现持续增长与创新

在当今日益激烈的商业竞争环境中&#xff0c;企业想要实现持续增长与创新&#xff0c;必须深入挖掘和有效运用自身的数据资产。数据不仅是企业运营过程中的副产品&#xff0c;更是洞察市场趋势、理解客户需求、优化业务决策的重要资源。本文将探讨如何通过利用先进的数据分析技…

Python容器 之 字符串--下标和切片

1.下标&#xff08;索引&#xff09; 一次获取容器中的一个数据 1, 下标(索引), 是数据在容器(字符串, 列表, 元组)中的位置, 编号 2, 一般来说,使用的是正数下标, 从 0 开始 3, 作用: 可以通过下标来获取具体位置的数据. 4, 语法&#xff1a; 容器[下标] 5, Python 中是支持…

进程,线程,虚拟内存,交换技术

参考资料&#xff1a; 参考视频1https://www.bilibili.com/video/BV1Hs421M78w/?spm_id_from333.999.0.0&vd_source97411b9a8288d7869f5363f72b0d7613 参考视频2https://www.bilibili.com/video/BV1jE411W7e8/?spm_id_from333.337.search-card.all.click&vd_source…

独家首发 | Matlab实现SVM-Transformer多变量回归预测

独家首发 | Matlab实现SVM-Transformer多变量回归预测 目录 独家首发 | Matlab实现SVM-Transformer多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现SVM-Transformer多变量回归预测&#xff0c;SVM递归特征消除Transformer多输入单输出回归预测…

从项目中学习Bus-Off的快慢恢复

0 前言 说到Bus-Off&#xff0c;大家应该都不陌生&#xff0c;使用VH6501干扰仪进行测试的文章在网上数不胜数&#xff0c;但是一般大家都是教怎么去干扰&#xff0c;但是说如何去看快慢恢复以及对快慢恢复做出解释比较少&#xff0c;因此本文以实践的视角来讲解Bus-Off的快慢恢…

STM32人体心电采集系统

资料下载地址&#xff1a;STM32人体心电采集系统 1、项目功能介绍 此项目主要实现了以STM32为核心的人体心电采集系统软硬件的设计。软件设计过程是在STM32上移植的uCGUI做图形界面&#xff0c;并如实显示采集到的心电波形信号&#xff0c;有SD卡存储和USB数据传输功能。 2、实…

反激开关电源反馈电路相关参数选型

Vb的电压正常变化范围是&#xff1a;0-1V&#xff08;最低0V&#xff0c;由于有稳压管&#xff0c;最高不会超过1V&#xff09; Vb的电压越高&#xff0c;则输出占空比越大&#xff0c;Vb电压越低&#xff0c;则输出占空比越小 那么Va的正常变化范围应该是&#xff1a;1.4-4.…

阅读这篇文章,彻底了解响应式网页设计

随着移动设备的普及&#xff0c;访问网站的方式发生了翻天覆地的变化。人们不再仅仅依靠桌面机来获取信息和享受在线服务。这给网页设计带来了巨大的挑战。如何构建一个能够在各种设备上流畅运行并提供一致用户体验的网站&#xff0c;已经成为每个网页设计师关心的问题。此时&a…

超详细之IDEA上传项目到Gitee完整步骤

1. 注册gitee 账号密码&#xff0c;gitee官网地址&#xff1a;Gitee官网&#xff0c;注册完成后&#xff0c;登录。 2. 创建仓库&#xff0c;在主页左下角有新建按钮&#xff0c;点击新建后会进入到此页面填写仓库信息。 3. 创建完成后复制仓库地址 4. 打开IntelliJ IDEA新建或…

java基于ssm+jsp 房屋租赁系统

1 管理员登录 管理员输入个人的用户名、密码登录系统&#xff0c;这时候系统的数据库就会在进行查找相关的信息&#xff0c;如果我们输入的用户名、密码不正确&#xff0c;数据库就会提示出错误的信息提示&#xff0c;同时会提示管理员重新输入自己的用户名、密码&#xff0c;…