Vue

2023-10-26

一、vue-router的实现原理

路由的概念来源于服务端,服务端中的路由描述的是URL和处理函数之间的映射关系;web前端单页应用SPA(single page application)中,路由描述的是URL和UI之前的映射关系,这种映射是单向的,即URL的变化引起UI更新;

如何实现前端路由?
解决两个核心问题:

  • 如何监测URL发生变化?
  • 如何改变URL却不引起页面刷新?

使用hash和history两种实现方法可以解决上面两个问题;

  • hash实现
    • hash是URL中hash(#)后面的内容,改变URL的hash部分不引起页面刷新;
    • hash通过hashchange事件监听URL的变化;改变URL的方式有:window.location、a标签、浏览器的前进后退 ;这几种方式都可以被hashchange监听到;
  • history实现
    • history提供了pushState和replaceState两种方法,这两种方法改变URL的pash部分不会引起页面的刷新;
    • history提供类似hashchange事件的popstate事件,用来监听URL的变化,但是只能监听到浏览器前进后退改变的URL,不能监听a标签、以及pushState和replaceState改变的URL;
    • 解决办法:拦截pushState和replaceState的调用以及a标签的点击事件来检测URL的变化;
<a href="https://jingyan.baidu.com/">百度经验</a> 
// 默认在当前页打开链接网页
<a href="https://jingyan.baidu.com/" target="_blank">百度经验</a>
// 加上target,在新的标签页打开链接网页

二、Vue的双向绑定原理和生命周期函数

Vue的双向绑定首先就是MVVM(model-view-viewmodel)模式;当视图发生改变的时候传递给VM,再让数据得到更新,当数据发生改变时传给VM,使得视图发生改变。
MVVM模式通过以下三个核心组件组成,每个都有它独特的角色:

  • Model:包含了业务和验证逻辑的数据模型;
  • view:定义了屏幕中view的结构,布局和外观;
  • viewmodel:扮演model和view之间的使者,帮忙处理view的全部业务逻辑;
    在这里插入图片描述
    vue的数据双向绑定主要通过Object.defineProperty(obj对象,prop属性,descriptor具体的改变方法)方法,进行数据劫持以及发布者——订阅者模式;

任务拆分:

1)组件初始化时,利用Object.defineProperty(在一个对象上定义一个新的属性)方法,给每一个data属性注册getter和setter方法,也就是reaction化(数据劫持);

2)在mount阶段会创建watcher类(每个组件对应一个watcher),然后再new一个watcher对象,watcher对象会立即调用组件的render函数生成虚拟DOM,在调用render函数时会访问data的属性值,此时会触发属性的getter函数,getter函数将当前的watcher注册到属性的dep中;watcher在组件渲染的过程中把“接触”过的data属性记录为依赖;

3)之后当data属性发生变化时,触发setter函数,之后调用dep的notify函数,通知watcher调用updata函数进行更新,从而使它关联的组件重新渲染。

  • 实现一个解析器Compile,可以扫描和解析每个节点的相关指令,把它们初始化成一个订阅者Watcher,并且绑定相应的函数。
  • 实现一个监听器Observer,用来劫持并监听所有属性,如有变动,就通过订阅者管理器(Dep,每个data属性都有一个dep)来通知订阅者Watcher;(每一个data的属性都会有一个dep对象)
  • 实现一个订阅者Watcher,(一个组件对应一个watcher)可以收到属性的变化通知,并执行相应的patch函数,从而更新视图;(watcher在mounted阶段生成)

三、Vue的生命周期

创建阶段:

  • beforeCreate:data和methods中的数据还没有被初始化;
  • created:data和methods已经被初始化好;调用methods中的方法,最早在created中操作;
  • beforeMount:模板在内存中编译完成,但尚未把模板渲染到页面中,此时页面还是旧的;
 beforeMount() {  
    console.log(document.getElementById('h3').innerText)  
    //{{msg}}
}, 
  • mounted:内存中编译好的模板替换到浏览器的页面中;(如果想要通过某些插件操作页面上的DOM节点,最早要在mounted中进行);执行完mounted,就表示整个Vue实例已经初始化完了;此时组件脱离了创建阶段,进入到了运行阶段。
mounted() {    
    console.log(document.getElementById('h3').innerText)  
    //ok
}, 

运行阶段:

  • beforeUpdate:页面中的显示的数据,还是旧的;此时data数据是最新的;页面尚未和最新的数据保持同步。
  • updated:页面和data数据已经保持同步了,都是最新的。

销毁阶段:

  • beforeDestroy:实例身上所有的data和所有的methods,以及过滤器,指令都处于可用阶段,此时,还没有真正执行销毁的过程。
  • destroyed:组件完全被销毁。

四、页面之间的通信

子组件Scroll.vue

<template>
    <div class="wrapper" ref='wrapper'>
      <div class='content'>
        <slot></slot>
      </div>
    </div>
</template>

<script>
import BScroll from 'better-scroll'
export default {
    name: 'Scroll',
    props: {
      probeType: {
        type: Number,
        default: 0
      },
    },
    data() {
      return {
        scroll: null,
      }
    }
 </script> 

父组件:Detail.vue

<template>
    <div id="detail">
        <scroll class="scroll-content" ref="scroll"
         :probe-type="2" @scroll="contentScroll" >
              <detail-swiper :top-images="topImages"/>
              <goods-list :goods="recommends" ref="recommend"/>
        </scroll>
    </div>
</template>

<script>
import Scroll from '@/components/common/scroll/Scroll'
export default {
  name: "Detail",
  components: {
    Scroll
  },
</script>

五、Vue2

data() {
	return {xx: xx, yy:yy}
},
methods: {
	login() { },
	layout() { }	
},
mounted() {	
	this.login()
},
computed:{	
    lowerCaseUsername () {
      	return this.username.toLowerCase()
    }
} 

六、Vue中的data为什么要使用函数?

七、动态绑定

<div v-bind:class="{ active: isActive }"></div>

八、项目的创建

1、创建项目时可以选择runtime-only和runtime-compiler

  • runtime-only:代码中不可以任何的template
  • runtime-compiler:代码中,可以有template,因为compiler可以来编译template

在这里插入图片描述
vue-template-compiler可以将template解析成ast,再将ast编译为render函数,render函数可以将template翻译成虚拟DOM树,之后将虚拟DOM树渲染成真实DOM树;

使用runtime-compiler:template => ast => render函数 => 虚拟DOM树 => 真实DOM树;
使用runtime-only:render函数 => 虚拟DOM树 => 真实DOM树;

九、vue中的keep-alive:

kee-alive 是 Vue 内置的一个抽象组件,它自身不会渲染一个DOM元素;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的组件缓存;

使用keep-alive组件保留了组件状态且不会重新渲染,这样会导致created(){ } 钩子函数不会再次触发;

keep-alive不仅仅能保存页面 / 组件的状态这么简单,还可以避免组件反复创建和渲染,有效提升系统性能。

include定义缓存白名单,keep-alive会缓存命中的组件;exclude定义缓存黑名单,被命中的组件将不会被缓存;

keep-alive实现原理 原文

export default {
  name: 'keep-alive',
  abstract: true, 
  // 判断当前组件虚拟dom是否渲染成真实dom的关键,true不渲染
  props: {
      include: patternTypes, // 缓存白名单
      exclude: patternTypes, // 缓存黑名单
      max: [String, Number] // 缓存的组件
  },
  created() {
     this.cache = Object.create(null) // 缓存虚拟dom
     this.keys = [] // 缓存的虚拟dom的键集合
  },
  destroyed() {
    for (const key in this.cache) {
       // 删除所有的缓存
       pruneCacheEntry(this.cache, key, this.keys)
    }
  },
 mounted() {
   // 实时监听黑白名单的变动
   this.$watch('include', val => {
       pruneCache(this, name => matched(val, name))
   })
   this.$watch('exclude', val => {
       pruneCache(this, name => !matches(val, name))
   })
 },

 render() {
    // 先省略...
 }
}

keep-alive在它生命周期内定义了三个钩子函数:

  • created:初始化两个对象cache和keys,分别缓存VNode(虚拟DOM)和Vnode对应的键集合
  • destroyed:删除this.cache中缓存的VNode实例;这不是简单地将this.cache置为null,而是遍历调用pruneCacheEntry函数删除。删除缓存的VNode还要对应组件实例的destory钩子函数
  • mounted:在mounted这个钩子中对include和exclude参数进行监听,然后实时地更新this.cahce对象数据;
  • 取出keep-alive包裹着的子组件对象,按照黑白名单进行匹配,决定是否缓存;在缓存对象中查找是否缓存过该组件实例;最后讲该组件实例的keepAlive属性值设为true

vue渲染:render函数将组件对象转化为一个VNode实例,之后调用update函数把Vnode渲染成真实DOM;这个工程调用patch函数完成;

activated // 用于keep-alive激活
 activated() {
  //刚进入该组件时,执行
  // console.log('组件刚进来')
  this.$refs.scroll.scrollTo(0, this.saveY, 0)
  this.$refs.scroll.refresh()  
},
destroyed // 用于keep-alive停用
deactivated() {
  //离开该组件时,执行
  //1.保存Y值
  this.saveY = -this.$refs.scroll.getScrollY
  //2.取消全局事件的监听
  this.$bus.$off('itemImageLoad', this.itemImgListener)
},

新的问题:keep-alive不会生成真正的DOM节点,因为Vue在初始化生命周期的时候,为组件实例建立父子关系会根据abstract属性决定是否忽略某个组件;keep-alive中设置了abstract:true,那么Vue就会跳过该组件实例。

被缓存的组件实例会为其设置keepAlive = true,而在初始化组件钩子函数中,不会再进入$mount过程,那么mounted之前的所有钩子函数(beforeCreate、created、mounted)都不再执行

十、v-if和v-show的区别:

1、相同点:v-if和v-show都可以动态控制DOM元素的显示与隐藏

2、不同点:

  • v-if动态地向DOM树中添加或删除DOM元素节点;

  • v-show通过向DOM元素设置样式display属性值控制显示隐藏。
    当两个demo用一个button按钮执行函数控制v-if和v-show的值,在控制台可以看出,两值都为false时,v-if控制的元素直接从DOM树销毁,而v-show控制的元素还是在DOM树中,只是以display:none的样式隐藏元素内容;
    在这里插入图片描述

  • 编译方面:v-if惰性,若最初指令值为false,不会编译;直至指令值为true时,才会编译存入缓存;
    v-show不管最初指令值为真还是为假,都会马上编译存入缓存;

  • 消耗方面:v-if切换性能消耗较大;v-show最初渲染消耗较大;

  • 适用场景:v-if适用切换条件、项目需求稳定;v-show使用与频繁需要切换;

  • 语法方面:v-if可以v-else、v-else-if配合使用,进行判断执行;但一定需要相邻,不可中断。

拓展

display:none; 不在文档流,无法触发绑定的事件,不会被子元素继承;但是父元素都不在了,子元素肯定也不在了~

visibilty:hidden; 会被子元素继承;在文档流中,会占据位置,但是不能触发绑定的事件;由于父元素隐藏,所以子元素也会隐藏,为了使子元素不被隐藏,可以使用visibility:visible

opacity:0; 在文档流中,会占据位置;绑定的事件也可以触发。

十一、监听input中value属性值发生变化的事件

1、onchange事件:

此事件会在元素内容发生改变,且失去焦点的时候触发。
浏览器支持度较好。

2、onpropertychange事件:

此事件会在元素内容发生改变时立即触发,即便是通过js改变的内容也会触发此事件。

元素的任何属性改变都会触发该事件,不止是value。只有IE11以下浏览器支持此事件。

3、oninput事件:

此事件会在value属性值发生改变时触发,通过js改变value属性值不会触发此事件。只有IE8以上或者谷歌火狐等标准浏览器支持。

十二、keep-alive组件的使用

参考 https://www.cnblogs.com/answershuto/p/7825022.html

是Vue.js一个内置组件;它能够将不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中也不会出现在父组件链中;它提供了includeexclude两个属性,允许组件有条件地进行缓存;

<keep-alive>
    <component></component>
</keep-alive>

这里面的component组件会被缓存起来。

举例说明:

<keep-alive>
    <coma v-if="test"></coma>
    <comb v-else="test"></comb>
</keep-alive>
<button @click="test=handleClick">请点击</button>

export default {
    data () {
        return {
            test: true
        }
    },
    methods: {
        handleClick () {
            this.test = !this.test;
        }
    }
}

在点击button时候,coma与comb两个组件会发生切换,但是这时候这两个组件的状态会被缓存起来,比如说coma与comb组件中都有一个input标签,那么input标签中的内容不会因为组件的切换而消失。

1、include与exclude属性

keep-alive组件提供了include与exclude两个属性来允许组件有条件地进行缓存,二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。

<keep-alive include="a">
  <component></component>
</keep-alive>
将缓存name为a的组件
<keep-alive exclude="a">
  <component></component>
</keep-alive>
name为a的组件将不会被缓存

2、keep-alive提供的生命钩子

activated与deactivated

keep-alive会将组件保存在内存中,并不会销毁以及重新创建,所以不会重新调用组件的created等方法;需要使用activated与deactivated两个生命钩子来得知当前组件是否处于活动状态;

3、深入keep-alive组件实现

created钩子会创建一个cache对象,用来作为缓存容器,保存vnode节点;

created () {
    /* 缓存对象 */
    this.cache = Object.create(null)
},

destroyed钩子则在组件被销毁的时候清除cache缓存中的所有组件实例。

/* destroyed钩子中销毁所有cache中的组件实例 */
destroyed () {
    for (const key in this.cache) {
        pruneCacheEntry(this.cache[key])
    }
},

4、render函数

首先通过getFirstComponentChild获取第一个子组件,获取该组件的name(存在组件名则直接使用组件名,否则会使用tag)。接下来会将这个name通过include与exclude属性进行匹配,匹配不成功(name不在inlcude中或者在exlude中,说明不需要进行缓存)则不进行任何操作直接返回vnode,vnode是一个VNode类型的对象,不了解VNode的同学可以参考笔者的另一篇文章《VNode节点》。

5、watch

用watch来监听pruneCache与pruneCache这两个属性的改变,在改变的时候修改cache缓存中的缓存数据。

6、总结

Vue.js内部将DOM节点抽象成了一个个的VNode节点,keep-alive组件的缓存也是基于VNode节点的而不是直接存储DOM结构。它将满足条件(pruneCache与pruneCache)的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染。

十三、element.js表单验证

在失去焦点时,进行规则的验证,并且发送ajax请求,在数据库中搜索,用户名有没有被注册;

password: [
 { required: true, message: '密码不能为空', trigger: 'blur' },
 { type: 'string', min: 6, message: '密码不允许小于6位', trigger: 'blur' }
],

十四、async / await

来源:https://www.jianshu.com/p/72e36168944f

async/await 执行原理详解

async函数就是generator函数的语法糖。

async函数,就是将generator函数的 * 换成async,将yield替换成await

1、async函数对generator的改进

  • 内置执行器,不需要使用next()手动执行。

  • await命令后面可以是Promise对象或原始类型的值,yield命令后面只能是Thunk函数或Promise对象。

  • 返回值是Promise;返回非Promise时,async函数会把它包装成Promise返回(Promise.resolve(value))

2、async函数作用

异步编程的终极解决方案

3、通俗理解

async/await,就是异步编程回调函数写法的替代方法。(使代码以同步方式的写法完成异步操作)

4、执行顺序

  • 原理

函数执行时,一旦遇到await就会返回。等到触发的异步操作完成(并且调用栈清空),再接着执行函数体内后面的语句。

await语句后面的代码,相当于回调函数。(即:await的下一行开始,都视作回调函数的内容)

async showSetRightDialog(role) {
  const { data: res } = await this.$http.get('rights/tree')
  if (res.meta.status !== 200) {
    return this.$message.error('获取权限列表失败')
  }
  this.rightsList = res.data
  // console.log(this.rightsList)
  this.getLeafKeys(role, this.defKeys)
  this.dialogVisible = true
  this.roleId = role.id
}

回调函数会被压入microtask队列,当主线程调用栈被清空时,去microtask队列里取出各个回调函数,逐个执行。

await只是让当前async函数内部的代码等待,并不是所有代码都卡在这里。遇到await就先返回,执行async函数之后的代码。

  • await执行细节

(2019.8.20测试发现:浏览器实际执行结果发生变化。await后面的函数,无论返回promise、还是非promise,执行结果都与曾经返回非promise相同)

主线程执行过程中,遇到await后面的函数调用,会直接进入函数,并执行。

(1)当这个函数返回非promise:

await后面的代码被压入microtask队列。当主线程执行完毕,取出这个回调,执行。

(2)当这个函数返回promise:—— 这种情况,看浏览器实际表现,已经不是这样处理了。

await后面的代码被压入microtask队列。当主线程执行完毕,取出这个回调,发现await语句等待的函数返回了promise,把后续代码赋给这个promise对象的then,并把这个promise的回调再压入microtask队列,重新排队。当它前面的回调函数都被取出执行后,再取出它,执行。

- 举例说明

【1】await返回非promise

async function func1(){
  console.log('func1');
  var a = await func2(); //当await返回非promise
  console.log('func1 return');
}

function func2(){
  console.log('func2');
}
 
func1();

new Promise(function(resolve){
    console.log('promise1')
    resolve('resolved');
}).then(function(data){
    console.log(data);
})

// 结果:
// func1
// func2
// promise1
// func1 return
// resolved

【No2】await返回promise(来自头条笔试题)

async function async1() {     
  console.log("async1 start");      
  await  async2();     
  console.log("async1 end");   
}  
async function async2() {    
  console.log( 'async2');  
} 

console.log("script start");  

setTimeout(function () {      
  console.log("settimeout");  
},0);

async1();  

new Promise(function (resolve) {      
  console.log("promise1");      
  resolve();  
}).then(function () {      
  console.log("promise2"); 
}); 
console.log('script end');  

//结果:
// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// settimeout

【注】
async1 end、promise2的console顺序,原来是反过来的。

十五、Vuex

来源
这里有一个非常重要的问题: 为什么要用Action管理异步操作?

action和mutation

乍一想,使用mutation也可以实现异步操作,为什么要多此一举,使用actions呢?

mutation必须同步执行这个限制,action不受约束;
可以在actions内部执行异步操作;

如果遇到异步操作涉及互相依赖的情况的时候,我们希望被依赖的操作执行完成之后,再执行依赖项,这样能保证程序执行得到正确的结果。但是异步操作,比如接口访问,往往不能确定执行完成的时间;

比如:在接口A中得到一个值,a;接口B需要使用这个值,结合B接口返回的值进行一些判断操作,if(a&&b){ … }; 这个时候如果B接口执行完毕了,A接口的值还没过来的话,就可能得到错误的结果。 a => undefined

addCountAction (context) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      context.commit('add') // 先提交
      resolve()
    }, 1000)
  })
}

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

在这里插入图片描述
具体实例:

  1. 点击“加入购物车”,将商品添加到购物车
    在mutations中写入方法:this.$store.commit("addCart", product)
    首先在状态的carList列表中使用find函数去查找之前数组中是否有该商品,有的话,购物车数量 + 1;
    没有的话,将该数据添加到carList中,将其count属性设为1;
    在这里插入图片描述
  2. 购物车页面需要显示加入商品的数量,所以需要拿到state,可以使用getters;
    在这里插入图片描述
  3. actions返回一个promise
addCart(context, payload) {
	return new Promise((resolve, reject) => {
	})
}

1、state状态的更改

当在其他地方更改了state状态时,其他组件应用到这个状态的时候,也会得到更新;

2、mutations:

  • 更改Vuex的store中的状态的唯一方法是提交mutation;
  • 通过this.$store.state来直接修改store中的状态也是有效的;但是这种方式的修改无法被Vue的调试工具记录(所以不推荐)
  • 通常情况下,Vuex要求mutation中的方法必须是同步,这是由于mutation对异步方法的提交无法被Vue调试工具记录。

3、store的状态是响应式的

Vuex中的store的状态是响应式的,mutations作为更改store中状态的唯一方法,需要遵循Vue的响应规则;

提前在store中初始化好所需的属性;
当给state中的对象添加新属性时,使用以下方法;
方式一:使用Vue.set()方法

addProp(state, payload) {
    // 该方法新增的属性不会添加至响应系统
    // state.obj.id = payload.id
    // Vue.set()添加的属性可以加入响应式系统
    // 三个参数分别是改变的对象,新增的属性名,新增的属性值
    Vue.set(state.obj, 'id', payload.id) 
    // 删除对象使用Vue.delete()方法
}

方式二:用新对象给旧对象重新赋值(新对象替换旧对象)

addPorp(state, payload) {
    // (...) 扩展运算符(对象展开符)
    state.obj = {...state.obj, 'id': payload.id}
}

4、为什么要加action功能?

在 mutation 中混合异步调用会导致你的程序很难调试。例如,当你调用了两个包含异步回调的 mutation 来改变状态,无法知道什么时候回调和哪个先回调

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue 的相关文章

  • SpringCloud服务间调用

    SpringCloud服务间的调用有两种方式 RestTemplate和FeignClient 不管是什么方式 他都是通过REST接口调用服务的http接口 参数和结果默认都是通过jackson序列化和反序列化 因为Spring MVC的R
  • 修改jar包增加自己需要功能的操作步骤(小白实践)

    一 修改静态文件的方式比较简单 1 先将要修改的jar包备份 cp xxx jar xxx 2 jar 2 建立一个新的目录便于后面的打包 mkdir jar tmp 3 将包放到刚刚创建的目录里解压 mv xxx 2 jar jar tm
  • GUI系统之SurfaceFlinger(11)SurfaceComposerClient

    文章都是通过阅读源码分析出来的 还在不断完善与改进中 其中难免有些地方理解得不对 欢迎大家批评指正 转载请注明 From LXS http blog csdn net uiop78uiop78 GUI系统之SurfaceFlinger章节目
  • qwtplot3D安装--终结解决方案

    帮同学做一个地热信息展示的软件 需要用到3D显示的内容 一方面 自己比较懒 懒去看OpenGL相关的内容 虽然以前做过3D开发相关的内容 但是毕竟需要处理的代码太多了 另一方面 也是一直在用QWT在帮他做2D图形显示这块 因此就想着用qwt
  • python3面向对象

    一些术语 类 class 用来描述具有相同的属性和方法的对象的集合 它定义了该集合中每个对象所共有的属性和方法 对象是类的实例 an example 4 learning class nClass i 123456

随机推荐

  • 论文笔记1——SSDA-YOLO: SEMI-SUPERVISED DOMAIN ADAPTIVE YOLO FOR CROSS-DOMAIN OBJECT DETECTION

    SSDA YOLO SEMI SUPERVISED DOMAIN ADAPTIVE YOLO FOR CROSS DOMAIN OBJECT DETECTION 源码地址 https github com hnuzhy SSDA YOLO
  • c#中“?”的几种用法

    c 中 的几种用法 1 可空类型修饰符 如 A B表示如果A为null则返回B 否则返回A 2 三元运算符 如 bool f false return f true 1 0 如果f为true则返回1 否则返回0 3 空合并运算符 如 a b
  • MySQL 管理方法

    MySQL 管理方法 一 Mysql介绍 二 Mysql启动 三 Mysql用户管理 一 Mysql介绍 MySQL是一个开放源码的小型关联式数据库管理系统 开发者为瑞典MySQL AB公司 目前MySQL被广泛地应用在Internet上的
  • Pytest系列-使用自定义标记mark(6)

    简介 pytest 可以支持自定义标记 自定义标记可以把一个 web 项目划分为多个模块 然后指定模块名称执行 Pytest 里面自定义标记 用法 将 pytest mark 标记名称 放到测试函数或者类上面 使用 执行时加上 m 标记名
  • 单片机新手指导1:STM32单片机学习思路

    学习内容 1 写在前面 1 学习态度 单片机 编程学习需要持续的恒心和毅力 涉及的学科跨度大 知识多 前期需长期投入大的精力入门 整个学习过程中最难的是入门这一步 也就是从0到1的过程 后期的学习是从1到10 由于掌握了一定的学习方法 所以
  • 真题详解(有向图)-软件设计(六十二)

    真题详解 极限编程 软件设计 六十一 https blog csdn net ke1ying article details 130435971 CMM指软件成熟度模型 一般1级成熟度最低 5级成熟度最高 采用更高级的CMM模型可以提高软件
  • 2022最简单易懂的IOS App打包发布完整流程

    创建appid标识符 进入apple开发者中心点击Account 点击Certificates Identifiers Profiles 创建AppIDS标识符 点击左侧菜单栏Identifiers 再点击 按钮 选择App IDs 再点击
  • python批量 txt转xml_Python版YOLOV3 Label(.txt)文件转xml文件

    最近在训练自己的yolo模型 训练之后想算mAP 发现网络上基本都是VOC数据集的标签制作方法 我的标签一开始是这样的 类型 x y w h 所以和VOC的不一样 于是就自己做xml文件 附代码 from xml dom minidom i
  • 栈溢出及解决方法

    栈溢出及解决方法 文章目录 栈溢出及解决方法 1 什么是栈溢出 2 栈溢出的解决方法 1 什么是栈溢出 缓冲区溢出是由于C语言系列设有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小 因此当这个数据足够大的时候 将会溢出缓冲区的范围
  • IC SPEC相关数据

    恢复内容开始 静态电流 静态电流是指没有信号输入时的电流 也就是器件本身在不受外部因素影响下的本身消耗电流 纹波电压的害处 1 容易在用设备中产生不期望的谐波 而谐波会产生较多的危害 2 降低了电源的效率 3 较强的纹波会造成 浪涌电压或电
  • c++中string类与字符串数组

    strlen及用 给c 字符串数组赋值 strlen 很笨 它会在遇到 0之前一直找下去 所以在cstr2中没有 0的时候 它会一直找下去 而那些地方还没有被初始化过 所以就是乱的 而且strlen计算出的字符串数组长度是不包含 0的那部分
  • elasticsearch中mapping中的可设置的属性

    mappings 在index 库 下创建时使用 下面可以有多个mapping 以下数据结构主要针对每个mapping进行说明 一级属性 二级属性 三级属性 说明 dynamic 新增字段自动模式 true 表示自动识别新字段并创建索引 f
  • 动态爬虫(ajax)-爬取bilibili热门视频信息

    文章目录 前言 一 页面分析 二 编写爬虫 1 引入库 2 发出请求 2 1生成请求头 2 2发出请求并获取响应 3 解析响应的内容 4 保存提取的信息到本地 5 康康主函数 三 运行结果 前言 使用python爬虫爬取bilibli每日热
  • VS2019利用Developer Command Prompt for VS 2019查看对象模型中的Class

    本文利用Developer Command Prompt for VS 2019工具 快速查看对象模型中类的结构 便于大家迅速了解衍生类和基类的关系 文章目录 一 打开开发人员命令提示工具 二 使用步骤 1 确定cpp文件位置 1 1 查找
  • chatGPT侧边栏历史记录消失解决方法

    从昨天3月8日开始 很多程序员发现自己的chatGPT打开后左侧侧边栏历史记录消失了 自己辛辛苦苦测试的Prompt都没有了 折腾了很久都不行 不得不重新写Prompt 解决方法 其实很简单 就是退出账号登录 然后重新登录账号再刷新就恢复了
  • QT界面UI文件不读取问题

    QT的C 项目有一段时间没有打开 重新打开时发现部分ui界面不知道为什么无法在QT Creator中用designer编辑器打开了 问题如下图 1 双击该ui界面不会自动跳转到界面编辑器了 2 可以随意更改ui界面的代码内容了 正常的ui界
  • C/C++使用Windows的API实现共享内存以及同步

    目录 共享内存 事件 Event 实现思路 创建方 服务端 连接方 进程同步 windows的API CreateFileMapping MapViewOfFile CreateEvent WaitForSingleObject Creat
  • 复习js笔记

    JS w3cschool官网 1000多本编程教程免费学 在日常中遇到的js函数 forms document forms name for in 循环 let x name lai age 18 city nanyang var y fo
  • 深度学习:激活函数的比较和优缺点,sigmoid,tanh,relu

    1 什么是激活函数 2 为什么要用 3 都有什么激活函数 4 sigmoid Relu softmax 1 什么是激活函数 如下图 在神经元中 输入的 inputs 通过加权 求和后 还被作用了一个函数 这个函数就是激活函数 Activat
  • Vue

    一 vue router的实现原理 路由的概念来源于服务端 服务端中的路由描述的是URL和处理函数之间的映射关系 web前端单页应用SPA single page application 中 路由描述的是URL和UI之前的映射关系 这种映射