第一章:3小时Vue基础快速入门
1、vue的起步和插值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < meta name="viewport" content="width=device-width, initial-scale=1.0"> < meta http-equiv="X-UA-Compatible" content="ie=edge"> < title >vue的起步和插值</ title > </ head > < body > < div id="app"> < h2 >{{ msg }}</ h2 > <!--插值表达式,里面可以插任意的值。这里插入了变量。--> < h3 >{{ 2 }}</ h3 > <!--插入数值--> < h3 >{{ "hello" }}</ h3 > <!--插入字符串--> < h3 >{{ {id:1} }}</ h3 > <!--插入对象--> < h3 >{{ 1>2 ? '真的':'假的'}}</ h3 > <!-- 插入表达式 --> < h3 >{{ txt.split('').reverse().join('') }}</ h3 > <!--插入了运算的结果。 排序反转。 --> < h3 ></ h3 > < h1 >{{ getContent() }}</ h1 > < h1 >{{ msg3 }}</ h1 > </ div > <!-- 1.引包 --> < script src="./vue.js"></ script > < script > // console.log(Vue); // 2.初始化 const vm = new Vue({ el: '#app', // 数据属性 data: { msg: 'hello vue', txt: 'hello', msg2: 'content', msg3:'< p >插值语法</ p >' }, // 存放的是方法 methods: { getContent() { return this.msg + ' ' + this.msg2; } } }); console.log(vm.msg); </ script > </ body > </ html > |
2、指令之v-text和v-html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>指令之v-text和v-html</title> </head> <body> <div id= 'app' > <h1>{{ msg }}</h1> <h2 v-text= 'msg' ></h2> <div v-html= 'htmlMsg' ></div> </div> <script src= "./vue.js" ></script> <script> // {{}}和v-text的作用是一样的 都是插入值 直接渲染 像css中的innerText // v-html既能插入值 又能插入标签 像css中的innerHTML new Vue({ el: '#app' , data:{ msg: "插入标签" , htmlMsg: '<h3>小马哥</h3>' } }) </script> </body> </html> |
3、条件渲染 v-if 和 v-show
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>条件渲染</title> </head> <body> <div id= 'app' > <div v- if = "isShow" > 显示 </div> <div v- else > 隐藏 </div> <h3 v-show = 'show' >小马哥</h3> </div> <script src= "./vue.js" ></script> <script> // v-if v-else-if v-else v-show // v-if 和 v-show 具有同样的作用,只是渲染时间不一样。前者执行对应的条件的时候才渲染,后者页面加载的时候就渲染。 new Vue({ el: '#app' , data: { isShow:Math.random() > 0.5, //条件判断随时数大于0.5显示,小于则隐藏。 show: true } }) </script> </body> </html> |
4、v-bind 绑定 用于绑定数据和元素属性 简写: :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < meta name="viewport" content="width=device-width, initial-scale=1.0"> < meta http-equiv="X-UA-Compatible" content="ie=edge"> < title >v-bind指令</ title > < style > .active{ color: red; } </ style > </ head > < body > < div id='app'> < a v-bind:href = 'res.url' v-bind:title='res.title'>{{res.name}}</ a > < img :src="imgSrc" alt=""> <!-- :src是v-bind:src的简写方式。--> < h3 class='name' :class = "{active:isActive}">v-bind的用法</ h3 > <!--isActive值是true则执行.active即字体红色,若值是false则不执行.active,字体默认黑色。--> <!-- <h4 :aaa = 'res.name'></h4> --> < h4 :style='{color:isColor, fontSize:fontSize+"px"}'>hello bind</ h4 > <!--通过Vue框架h4标签渲染字体颜色和字体大小。--> </ div > < script src="./vue.js"></ script > < script > new Vue({ el: '#app', data: { res:{ name:'百度', url:'https://www.baidu.com', title:'百度一下' }, imgSrc:'./images/logo.png', isActive:true, isColor:'green', fontSize:30 } }) </ script > </ body > </ html > |
5、v-on事件绑定 简写:@
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>v-on事件绑定</title> <style> .box{ width: 200px; height: 200px; background-color: red; } .active{ background-color: green; } </style> </head> <body> <div id= 'app' > <h3>{{num}}</h3> <button v-on:click.once= "handleClick" >+1</button> <div class = 'box' : class = '{active:isActive}' ></div> <button @click= 'changeClick' >切换</button> <!-- @click是v-on:click的简化。 --> <input v-on:keyup.up= "submit" > </div> <script src= "./vue.js" ></script> <script> /* 1.扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。 2.因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。 3.当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。 */ new Vue({ el: '#app' , data: { num:0, isActive: false }, methods: { handleClick(){ this .num+=1; }, changeClick(){ this .isActive = ! this .isActive; //布尔条件判断,取反。 }, submit(){ alert(1); } }, }) </script> </body> </html> |
6、v-for列表渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < meta name="viewport" content="width=device-width, initial-scale=1.0"> < meta http-equiv="X-UA-Compatible" content="ie=edge"> < title >v-for列表渲染</ title > < style > .box { width: 200px; height: 200px; background-color: red; } .active { background-color: green; } </ style > </ head > < body > < div id='app'> < div > < ul > < li v-for = '(item,index) in menus' :key = 'item.id'> <!--使用v-for的时候,记得后面要加上:key,否则遍历会出问题。--> < h3 >{{index}} - id:{{item.id}} 菜名:{{item.name}}</ h3 > </ li > </ ul > < ol > < li v-for = "(val,key) in obj" :key='key'> {{key}}---{{val}} </ li > </ ol > </ div > </ div > < script src="./vue.js"></ script > < script > new Vue({ el: '#app', data: { menus:[ {id:1,name:'大腰子'}, {id:2,name:'烤鸡翅'}, {id:3,name:'烤韭菜'}, {id:4,name:'烤大蒜'}, ], obj:{ title:'hello 循环', author:'小马哥' } }, methods: { }, }) </ script > </ body > </ html > |
7、vue 中v-model双向数据绑定 表单输入绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < meta name="viewport" content="width=device-width, initial-scale=1.0"> < meta http-equiv="X-UA-Compatible" content="ie=edge"> < title >vue的双向数据绑定v-model</ title > < style > </ style > </ head > < body > < div id='app'> < p >{{msg}}</ p > < input type="text" v-model='msg'> <!-- 复选框单选 --> < label for="checkbox">{{checked}}</ label > < input type="checkbox" id='checkbox' v-model='checked'> < div class="box"> < label for="a">黄瓜</ label > < input type="checkbox" id='a' value='黄瓜' v-model='checkedNames'> < label for="b">西红柿</ label > < input type="checkbox" id='b' value='西红柿' v-model='checkedNames'> < label for="c">芸豆</ label > < input type="checkbox" id='c' value='芸豆' v-model='checkedNames'> < br /> < span >{{checkedNames}}</ span > </ div > < label >{{txt}}</ label > < input v-model.lazy="txt"> < label >{{msg2}}</ label > < input v-model.trim="msg2"> </ div > < script src="./vue.js"></ script > < script > new Vue({ el: '#app', data: { msg: '小马哥', msg2: '', txt: '', checked: false, checkedNames: [] }, methods: { }, }) </ script > </ body > </ html > <!-- 下面在单独给大家介绍下vue中v-model使用 v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作: 1. v-bind绑定一个value属性 2. v-on指令给当前元素绑定input事件 自定义组件使用v-model,应该有以下操作: 1. 接收一个value prop 2. 触发input事件,并传入新值 --> |
8、侦听器watch的用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>侦听器watch</title> </head> <body> <div id= "app" > <input type= "text" v-model= "msg" > <h3>{{msg}}</h3> <h3>{{stus[0].name}}</h3> <button @click= 'stus[0].name = "Tom"' >改变</button> </div> <script src= "./vue.js" ></script> <script> // 基本的数据类型可以使用watch直接监听,复杂数据类型Object Array 要深度监视 new Vue({ el: '#app' , data: { msg: '' , stus:[{name: 'jack' }] }, watch: { // key是属于data对象的属性名 value:监视后的行为 newV :新值 oldV:旧值 'msg' : function (newV,oldV){ // console.log(newV,oldV); if (newV === '100' ){ console.log( 'hello' ); } }, // 深度监视: Object对象 |Array数组 "stus" :{ deep: 'true' , //表示深度监视 handler: function (newV,oldV){ console.log(newV[0].name); } } }, }) </script> </body> </html> |
9、计算属性之computed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>侦听器watch</title> </head> <body> <div id= 'app' > {{reverseMsg}} <h3>{{fullName}}</h3> <button @click= 'handleClick' >改变</button> </div> <script src= "./vue.js" ></script> <script> new Vue({ el: '#app' , data: { msg: 'hello world' , firstName: '小马' , lastName: '哥' }, methods: { handleClick(){ this .msg = '计算属性computed' ; this .lastName = '妹' ; } }, computed: { // computed默认只有getter方法 // 计算属性最大的优点:产生缓存 如果数据没有发生变化 直接从缓存中取 reverseMsg: function () { return this .msg.split( '' ).reverse().join( '' ) }, fullName: function () { return this .firstName + this .lastName; } }, }) </script> </body> </html> |
10、计算属性之computed的setter方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>计算属性setter</title> </head> <body> <div id= 'app' > {{content}} <input type= "text" v-model= 'content' @input = 'handleInput' > <button @click= 'handleClick' >获取</button> </div> <script src= "./vue.js" ></script> <script> new Vue({ el: '#app' , data: { msg: '' , }, methods: { handleInput: function (event){ const {value} = event.target; this .content = value; }, handleClick(){ // console.log(); if ( this .content) { console.log( this .content); } } }, computed: { content:{ set: function (newV){ this .msg = newV; }, get: function (){ return this .msg; } } }, }) </script> </body> </html> |
11、Vue的过滤器 filters 讲解 全局过滤器 局部过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>过滤器</title> </head> <body> <div id= "app" > <h3>{{price | myPrice( '¥' )}}</h3> <h3>{{msg|myReverse}}</h3> </div> <script src= "./vue.js" ></script> <script> // 创建全局过滤器 Vue.filter( 'myReverse' , (val) => { return val.split( '' ).reverse().join( '' ); }) // 为数据添油加醋 // ¥ $20 new Vue({ el: '#app' , data: { price: 10, msg: 'hello 过滤器' }, // 局部过滤器 filters: { myPrice: function (price, a) { return a + price; } } }) </script> </body> </html> |
12、案例:音乐播放器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>案例:音乐播放器</title> <style> * { padding: 0; margin: 0; } ul { list-style: none; } ul li { margin: 20px 20px; padding: 10px 5px; border-radius: 3px; } ul li.active { background-color: #D2E2F3; border-radius: 10px; border: 2px solid #3684d8; } #app{ width: 500px; border: 2px solid #e26fc5; border-radius: 20px; padding: 20px; margin: 50px auto; background-color: rgb(227, 233, 139); } </style> </head> <body> <div id= 'app' > <audio :src= "currentSrc" controls autoplay @ended= 'handleEnded' ></audio> <ul> <li : class = '{active:index===currentIndex}' v- for = '(item,index) in musicData' :key= 'item.id' @click= 'handleClick(item.songSrc,index)' > <h2>{{item.id}}-歌名: {{item.name}}</h2> <p>歌手: {{item.author}}</p> </li> </ul> <button @click= 'handleNext' >下一首</button> </div> <script src= "./vue.js" ></script> <script> const musicData = [{ id: 1, name: '于荣光 - 少林英雄' , author: '于荣光' , songSrc: './static/于荣光 - 少林英雄.mp3' }, { id: 2, name: 'Joel Adams - Please Dont Go' , author: 'Joel Adams' , songSrc: './static/Joel Adams - Please Dont Go.mp3' }, { id: 3, name: 'MKJ - Time' , author: 'MKJ' , songSrc: './static/MKJ - Time.mp3' }, { id: 4, name: 'Russ - Psycho (Pt. 2)' , author: 'Russ' , songSrc: './static/Russ - Psycho (Pt. 2).mp3' } ]; new Vue({ el: '#app' , data: { //此处是data,不是date musicData, currentSrc: './static/于荣光 - 少林英雄.mp3' , currentIndex: 0 }, methods: { //此处是方法里面添加事件函数 handleClick(src, index) { this .currentSrc = src; this .currentIndex = index; }, handleEnded() { // // 下一首的播放 // this.currentIndex++; // this.currentSrc = this.musicData[this.currentIndex].songSrc; this .handleNext(); //此处的this千万不能忘了。 }, handleNext() { this .currentIndex++; if ( this .currentIndex === this .musicData.length) { this .currentIndex = 0; } this .currentSrc = this .musicData[ this .currentIndex].songSrc } } }) </script> </body> </html> |
13、音乐播放器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta http-equiv= "X-UA-Compatible" content= "IE=edge" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <title>Document</title> <style> *{ margin: 0; padding: 0; } ul{ list-style: none; } #app{ width: 500px; border: 2px solid rgb(55, 79, 143); padding: 30px; margin: 50px auto; border-radius: 20px; background-color: rgb(209, 238, 105); } #app ul li{ padding: 10px 5px; } #app ul li.active{ background-color: rgb(168, 180, 235); border-radius: 10px; } </style> </head> <body> <div id= "app" > <audio :src= "currentSrc" controls autoplay @ended= "handleEnded" ></audio> <ul> <li : class = "{active:currentIndex===index}" v- for = '(item,index) in musicData' :key= "item.id" @click= "handleClick(item.songSrc,index)" > <h3>{{item.id}}--歌曲: {{item.name}}</h3> <p>歌手: {{item.author}}</p> </li> </ul> <button @click= "handleNext" >下一首</button> <button @click= "handlePrev" >上一首</button> </div> <script src= "./vue.js" ></script> <script> const musicData = [{ id:1, name: '大籽 - 白月光与朱砂痣' , author: '大籽' , songSrc: './static/大籽 - 白月光与朱砂痣.mp3' }, { id:2, name: 'MKJ - Time' , author: 'MKJ' , songSrc: './static/MKJ - Time.mp3' }, { id:3, name: '清远Dj鸿少-全国语Club音乐放过自己庄心妍专辑慢摇串烧' , author: '清远Dj鸿少' , songSrc: './static/清远Dj鸿少-全国语Club音乐放过自己庄心妍专辑慢摇串烧.mp3' } ] new Vue({ el: '#app' , data:{ musicData, currentSrc: './static/大籽 - 白月光与朱砂痣.mp3' , currentIndex:0 }, methods:{ handleClick(src,index){ this .currentSrc = src; this .currentIndex = index; }, handleEnded(){ this .handleNext(); }, handleNext(){ this .currentIndex++; if ( this .currentIndex=== this .musicData.length){ this .currentIndex = 0 } this .currentSrc = this .musicData[ this .currentIndex].songSrc; }, handlePrev(){ this .currentIndex--; if ( this .currentIndex===-1){ this .currentIndex= this .musicData.length-1; } console.log( this .currentIndex); this .currentSrc = this .musicData[ this .currentIndex].songSrc; } } }) </script> </body> </html> |
14、音乐播放器 computed方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <meta name= "viewport" content= "width=device-width, initial-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>案例:音乐播放器 computed</title> <style> * { padding: 0; margin: 0; } ul { list-style: none; } ul li { margin: 20px 20px; padding: 10px 5px; border-radius: 3px; } ul li.active { background-color: #D2E2F3; } </style> </head> <body> <div id= 'app' > <audio :src= "getCurrentSongSrc" controls autoplay @ended= 'handleEnded' ></audio> <ul> <li : class = '{active:index===currentIndex}' v- for = '(item,index) in musicData' :key= 'item.id' @click= 'handleClick(index)' > <h2>{{item.id}}-歌名:{{item.name}}</h2> <p>{{item.author}}</p> </li> </ul> <button @click= 'handlePrev' >上一首</button> <button @click= 'handleNext' >下一首</button> </div> <script src= "./vue.js" ></script> <script> const musicData = [{ id: 1, name: '于荣光 - 少林英雄' , author: '于荣光' , songSrc: './static/于荣光 - 少林英雄.mp3' }, { id: 2, name: 'Joel Adams - Please Dont Go' , author: 'Joel Adams' , songSrc: './static/Joel Adams - Please Dont Go.mp3' }, { id: 3, name: 'MKJ - Time' , author: 'MKJ' , songSrc: './static/MKJ - Time.mp3' }, { id: 4, name: 'Russ - Psycho (Pt. 2)' , author: 'Russ' , songSrc: './static/Russ - Psycho (Pt. 2).mp3' } ]; new Vue({ el: '#app' , data: { musicData, currentIndex: 0 }, computed:{ getCurrentSongSrc(){ return this .musicData[ this .currentIndex].songSrc; } }, methods: { handleClick(index) { this .currentIndex = index; }, handleEnded() { this .handleNext(); }, handlePrev(){ this .currentIndex--; if ( this .currentIndex===-1){ this .currentIndex = this .musicData.length-1; } }, handleNext() { this .currentIndex++; if ( this .currentIndex === this .musicData.length) { this .currentIndex = 0; } } } }) </script> <!-- 18511803134 小马哥 --> <!-- vue组件 --> <!-- ajax axios ajax库 --> </body> </html> |
作者:龙飞
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理