快速上手Vue全家桶学习笔记(一)
我是一名后端工程师,平时开发一些小工具需要前端展示,所以学习一些前端技术。Vue.js是一种渐进式框架,无论是搭建简单项目还是复杂项目都是很方便的。
不过任何技术都要反复使用才能熟练掌握,有的时候太长时间没做前端开发可能就会有些生疏,于是写下这篇笔记整理Vue的知识点防止自己遗忘,同时,对于想学习Vue的朋友提供一点帮助。
我本人对Vue研究得不是特别深入,如有错误之处,希望大家帮忙指正。感谢。
1.Vue开发环境的搭建
-
首先进入Vue的官网:Vue.js
-
选择起步-安装,可以看到有几种方式
- 手动下载vue.js文件,用script标签引入
- 用script标签引入cdn地址
- 使用npm工具
-
我们在实际开发的时候常常会使用一些脚手架如Vue-Cli、Vite搭配npm去构建项目,但现在尚在学习阶段,我们使用最朴素的方式去引入Vue.js
-
在官网的起步-安装页面提供了Vue.js的下载链接,有两个版本,开发版本和生产版本。生产版本就是项目正式上线所需要的版本,相对于开发版本而言,删去了一些提示和警告,减小了文件的体积。
-
那么在开发阶段,我们是需要这些提示和警告的,所以我们下载开发版本。
-
-
下载完成之后,打开VScode新建一个源码文件夹,在文件夹下面新建vue.js文件夹,把刚才下载的js文件放在里面
-
我们新建一个html文件来测试一下,输入如下测试代码
-
点击查看代码
<!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> <script src="../vue.js/vue.js"></script> </head> <body> <div id="app">{{message}}</div> <script> new Vue({ el: '#app', data: { message: 'vue.js引入成功', }, }); </script> </body> </html>
-
-
然后通过Open with Live Server打开浏览器,可以看到页面正常显示,证明vue.js引入成功
-
注意
- script引入js文件时,src地址要输入正确
- 如果不知道Open with Live Server的,要安装扩展live server
2.第一个hello world
-
我们更改一下上面的代码
点击查看代码
<!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> <script src="../vue.js/vue.js"></script> </head> <body> <div id="app">{{message}}</div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { message: 'hello world', }, }); </script> </body> </html>
-
然后用浏览器打开,发现就可以输出hello world了
-
那么这是怎么做到的呢
- 首先,我们用的既然是Vue,我们可以先实例化一个Vue对象
new Vue()
- 从例子中可以看到,我们实例化这个对象可以配置一些属性进去,当然这些属性都是内置好的
- 用花括号{}把属性括起来,属性是以键值对的形式存在,属性名和属性值之间用冒号隔开,每个键值对之间用逗号隔开
new Vue({ el: '#app', data: { message: 'hello world', }, });
- 例子当中就有两个属性,一个是
el
,一个是data
,后面我会介绍更多常用的属性以及方法 el
这个属性是css选择器,表示我们操作的是哪里的元素- 可以看到例子中我定义了一个div
<div id="app">{{message}}</div>
- 其id是app,而
el: '#app'
就表示指定id为app的div作为一个容器给这个Vue实例使用 - 另外一个属性
data
是用来保存Vue实例的数据的,它的值是一个对象,用花括号{}括起来,里面可以定义一些属性和值 - 例子中我们定义了一个属性
message: 'hello world'
- 而在我们定义的id为app的div中,我们通过插值语法{{}}把
message
值传到里面 - 这样在浏览器上就能显示我们想要的值:hello world
- 注意
- 一个Vue实例只能接管一个容器
- 插值语法:{{}}可以读取到data里的所有属性
- data中的数据发生变化,容器中的值也会自动更新
- 首先,我们用的既然是Vue,我们可以先实例化一个Vue对象
3.Vue中的模板语法
插值语法
- 作用:可以在视图中显示data中的数据
- 用法:
{{xxx}},xxx里是data中的定义的属性
- 例子:
<div id="app">hello,{{name}}</div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, }); </script>
指令语法
- 特点:用在标签的解析(标签属性,标签体内容,绑定事件等)
- 用法:
v-xxx
- 例子:
v-bind:href='url' 动态数据绑定(单向)
<div id="app"> <a v-bind:href="url">点击跳转</a> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', url: 'https://www.baidu.com', }, }); </script>
v-bind:href='url'
可以简写为:href='url'
4.双向数据绑定
单向数据绑定
- 简介:上面我们用了
v-bind:
来动态绑定数据,它就是一种单向的数据绑定 - 例子:
<div id='app'> 单向数据绑定<input :value='name'/> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, }); </script>
- 当我在控制台里修改name的值,页面输入框中的值也随之发生改变
- 但当我修改页面输入框中的值,可以看到,控制台中data里的name的值没有变化
- 这就是单向数据绑定
双向数据绑定
- 用法:
v-model
- 例子:
<div id='app'> 双向数据绑定<input v-model:value='name'/> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, }); </script>
- 这次当我改变输入框中的数据时,data中的数据也会发生改变,这就是双向数据绑定
- 注意:v-model只能用在表单元素上
v-model:value='xxx'
可以简写为v-model='xxx'
5.事件的绑定
事件的绑定
- 用法:
v-on:事件名
- 例如:
- 点击事件
v-on:click='xxx'
- 简写:
@click='xxx'
- xxx里面是自己定义的方法名,定义在Vue实例里面的methods属性里
- 点击事件
- 代码:
<div id='app'> <h3 v-on:click='showMessage'>点击此处弹窗</h3> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { showMessage(){ alert('hello world'); } } }); </script>
- 效果如下
事件传参
-
定义函数的时候在括号里输入参数
<div id='app'> <h3 v-on:click='showMessage("hello world")'>点击此处弹窗</h3> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { showMessage(text){ alert(text); } } }); </script>
-
效果如下:
-
注意:
- 如果是无参函数,则
@click='xxx'
里xxx
可以只写函数名,不加括号 - 定义在methods里的函数不能用箭头函数
- 使用
event.target.innerText
可以获取标签里的内容,调用的函数不加括号,或者括号里加$event
- 代码如下
或者<div id='app'> <h3 v-on:click='getMeaagseinTag'>点击此处显示此处内容</h3> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { getMeaagseinTag(event){ alert(event.target.innerText) } } }); </script>
<div id='app'> <h3 v-on:click='getMeaagseinTag($event)'>点击此处显示此处内容</h3> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { getMeaagseinTag(event){ alert(event.target.innerText) } } }); </script>
- 效果如下
- 如果是无参函数,则
6.常用事件修饰符
阻止默认事件
- 方法:在事件后面加
.prevent
就可以做的,这里就不演示原生js的做法了 - 例子:在
<a></a>
标签里加一个点击事件,不想让它跳转,代码如下<div id='app'> <a href="https://www.baidu.com" @click.prevent='showMessage'>点击此处跳转</a> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { showMessage(){ alert('hello world'); } } }); </script>
- 在
@click
后面加了一个.prevent
,这样当我们点击这个超链接时,触发弹框,但是没有跳转
阻止冒泡事件
- 方法:在事件后面加
.stop
就可以做到 - 例子:在
<h1>
标签和它的父节点<div>
标签里都加了同一个点击事件,点击<h1>
标签里的内容,会触发两次弹框事件,我只想弹一次,那么就在子节点里面的@click
后面加.stop
,代码如下:<div id='app' @click='showMessage'> <h3 @click.stop='showMessage'>点击此处弹窗</h3> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { showMessage(){ alert('hello world'); } } }); </script>
- 注意:
.prevent
和.stop
可以连用
一次事件
- 顾名思义,让事件只触发一次
- 用法:在事件后面加
.once
就可以做到 - 用法和上面一样,在
@click
后面加.once
,那么第一次点击会触发弹框事件,第二次点击则不触发,代码如下:<div id='app'> <h3 @click.once='showMessage'>点击此处弹框</h3> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { showMessage(){ alert('hello world'); } } }); </script>
回车键事件
- 简介:当我们使用
@keyup
绑定键盘事件的时候,每一次敲击键盘就会触发一次事件,我们希望敲完完整的内容时才触发键盘事件,则需要使用.enter
修饰符 - 例子:
<div id='app'> 请输入:<input @keyup='log'/> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { log(){ console.log('键盘事件'); } } }); </script>
- 效果:
- 可以看到,输入‘你好’两个字,还没有确认,就已经触发了10次键盘事件
- 修改代码如下:
<div id='app'> 请输入:<input @keyup.enter='log'/> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { name: '张三', }, methods: { log(){ console.log('键盘事件'); } } }); </script>
- 效果如下:
- 可以看到,当我把整个‘你好’敲完,并按回车后,才触发一次键盘事件
7.Vue中的计算属性
-
定义:通过已有的属性计算新的属性,使用Vue实例中的
computed
属性 -
例子:如果我知道一个人的姓,和这个人的名,那么我能不能计算出他的姓名,答案很简单,就是姓+名,那么怎么在Vue中实现呢?
<div id='app'> 姓:<input type="text" v-model='firstName'/> <br/> 名:<input type="text" v-model='lastName'/> <br/> 姓名:<input type="text" v-model='fullName'/> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { firstName: '张', lastName: '三', }, computed: { fullName:{ get(){ return this.firstName+'-'+this.lastName }, set(val){ this.firstName = val.split('-')[0] this.lastName = val.split('-')[1] } } } }); </script>
-
从代码中我们看到,我在Vue实例的
data
属性里,定义了一个firstName
和一个lastName
,并且在<div>
中写了两个输入框,一个叫“姓”,一个叫“名”,这两个输入框中的值是和Vue实例双向数据绑定的。再看到第三个名叫“姓名”的输入框,它的值我写的是fullName
,但是可以发现,这个fullName
我不是定义在data
里的,而是定义在computed
属性里的。 -
这个
computed
属性,就是我们的计算属性了,可以看到,我定义的fullName
属性里,有两个函数,一个叫get()
,一个叫set()
,在get()
函数中,我实现了姓名的计算方法,把firstName+'-'+lastName
return出去,显示在第三个输入框上,如下图所示。
-
而
set()
函数里定义的方法,是更改第三个输入框中的值去改变firstName
和lastName
的属性值,现在这个场景我们用不着,所以可以将set()
方法省略,省略了set()
方法之后,fullName
就可以简写了,简写为
computed: {
fullName(){
return this.firstName+'-'+this.lastName
}
}
- 注意:当我们使用
computed
里面属性的时候,不用加‘()’,因为这个属性里存储的只是一个返回值 - 同样的效果我们可以在
methods
里定义方法去实现,但为什么还要用计算属性呢?因为计算属性的优势- 有缓存机制,可以复用
- 效率高,调试方便
8.监视属性
- 原理:被监视的属性发生改变时,调用回调函数,执行相关操作,使用
watch
属性 - 例子:制定计划的时候,我希望晴天出去打篮球,不是晴天就敲代码,这个时候我们就需要有一个属性来监视天气,代码如下
<div id='app'>
今日计划:{{plan}}
<br/>
<button @click='change'>切换天气</button>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
plan: '打篮球',
isSunny: true
},
methods: {
change(){
this.isSunny = !this.isSunny
}
},
watch: {
isSunny: {
handler() {
this.plan = this.isSunny?'打篮球':'敲代码'
}
}
}
});
</script>
- 可以看到在Vue实例中定义了一个
watch
属性,用来监视isSunny
属性,当isSunny
发生改变的时候,执行handler()
里面定义的方法 - 注意:
watch
里监视的属性一定要在data中定义 immediate: true
是开启初始化调用deep: true
是开启深度监视- 如果不需要开启初始化调用和深度监视,则可以简写:
watch: {
isSunny() {
this.plan = this.isSunny?'打篮球':'敲代码'
}
}
计算属性和监视属性的异同
- 监视属性是命令式的且重复的
- 通过计算属性实现更加简洁明了
- 两者都能实现的,优先选择计算属性
- 监视属性能实现异步调用,计算属性不行
9.class样式和style样式的动态绑定
Vue中class样式的绑定
字符串写法
- 使用场景:样式的类型不确定
- 写法:
<div :class='bg'>点击此处更换颜色</div>
- 原理:通过
v-bind:class
动态绑定class
的值,可以切换不同class选择器从而切换样式 - 注意:动态绑定的
class
的值必须是data
中定义的,不能直接写class选择器的名字 - 例子:
<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"> <script src="../vue.js/vue.js"></script> <title>Document</title> <style> .bg_red{ background-color: red; } .bg_blue{ background-color: blue; } </style> </head> <body> <div id='app' :class="bg" @click='change'> 点击此处更换背景颜色 </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { bg: 'bg_red', }, methods: { change(){ this.bg = 'bg_blue'; } } }); </script> </body>
- 可以看到,
class
的值与data
中定义的属性值bg
动态绑定,bg
的值就是class选择器的名字,通过change()
函数动态改变bg
的值从而改变class
的值,最终显示不同的样式
对象写法
- 使用场景:样式个数、类名确定,通过Boolean动态展示与否
- 用法:
<div :class='obj'>Hello World!!!</div>
- 原理:还是通过
v-bind:class
动态绑定data
里的数据,这次直接在data
里定义一个对象obj
,将各种样式定义在里面 - 例子:
<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"> <script src="../vue.js/vue.js"></script> <title>Document</title> <style> .bg_red{ background-color: red; } .font{ font-size: 50px; } </style> </head> <body> <div id='app' :class="obj"> Hello World!!! </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { obj: { bg_red: true, font: true }, }, }); </script> </body>
obj
里面定义了各种样式,通过true
和false
来确定这些样式是否显示
数组写法
- 使用场景:需要绑定的样式个数不确定,类名也不确定
- 用法:用法:
<div :class='arr'>Hello World!!!</div>
- 原理:还是通过
v-bind:class
动态绑定data
里的数据,这次直接在data
里定义一个数组arr
,将各种样式定义在里面 - 例子:
<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"> <script src="../vue.js/vue.js"></script> <title>Document</title> <style> .bg_red{ background-color: red; } .font{ font-size: 50px; } .color{ color: yellow; } </style> </head> <body> <div id='app' :class="arr"> Hello World!!! </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { arr: ['bg_red', 'font', 'color'], }, }); </script> </body>
- 样式都定义在数组
arr
里面,可以自定义方法增删arr
里面的值从而动态改变样式
Vue中style样式的动态绑定
- 用法和class样式的动态绑定一样,都是通过
v-bind:
来绑定 - 用法:
<div id='app' :style="{backgroundColor: bg, color: cl, fontSize: font+'px'}">Hello World!!!</div>
- 例子:
<div id='app' :style="{backgroundColor: bg, color: cl, fontSize: font+'px'}"> Hello World!!! </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { bg: 'red', cl: 'blue', font: 50, }, }); </script>
- 可以看到在
<div>
标签里动态绑定的style
后面是一个对象,用{}
括起来了,里面是key-value
键值对,用逗号隔开,而且key
值要写成驼峰的形式,background-color
改为backgroundColor
,font-size
改为fontSize
。而value
值是定义在data
里面的 - 效果:可以打开Vue的开发者工具,看到
style
样式全部显示在data
里面,可以动态地去调整
10.Vue中的条件渲染
v-if用法
- 用法:
<v-if='xxx'>
<v-else-if='xxx'>
<v-else>
- 直接看例子:
<div id='app'> <p v-if='num===1'>打篮球</p> <p v-else-if='num===2'>敲代码</p> <p v-else-if='num===3'>约会</p> <p v-else>睡觉</p> <button @click='randomNum'>随机生成</button> <p>随机数:{{num}}</p> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { num:'' }, methods: { randomNum(){ this.num = Math.floor(Math.random() * 4) } } }); </script>
- 其实学过js或者后端语言的都能看出来,这就是
if-else
,我定义一个方法生成随机数,随机到哪个数,那么那个<p>
标签显示,其他的不显示 - 效果展示:
- 用法很简单,有一点要注意的是
<v-if='xxx'>
<v-else-if='xxx'>
<v-else>
需要连用,否则会报错
v-show用法
<v-if>
符合条件的Dom显示了,那不符合条件的Dom怎么处理呢?- 我们先来看另外一个指令
<v-show>
- 例子:
<div id='app'> <p v-show='num===1'>打篮球</p> <p v-show='num===2'>敲代码</p> <p v-show='num===3'>约会</p> <button @click='randomNum'>随机生成</button> <p>随机数:{{num}}</p> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { num:'' }, methods: { randomNum(){ this.num = Math.floor(Math.random() * 4) } } }); </script>
- 我们发现使用
<v-show>
也可以让Dom节点隐藏,那么这和<v-if>
有什么区别呢? - 站内有一篇文章解释的很清楚:点击此处查看
- 总的来说
v-if
和<v-show>
的特点是这样的:<v-if>
不展示时直接移除Dom元素(实际上是因为Vue没有去渲染),适合切换频率低的场景<v-show>
不展示时使用隐藏样式,适合切换频率高的场景- 一般来说,
<v-if>
有更高的切换开销,<v-show>
有更高的初始渲染开销 - 如果需要非常频繁地切换,就使用
<v-show>
,如果运行时条件很少改变,就用<v-if>
11.Vue中的列表渲染
v-for的用法
- 定义:使用
v-for
指令基于一个数组来渲染一个列表。v-for
指令的值需要使用item in items
形式的特殊语法,其中items
是源数据的数组,而item
是迭代项的别名
遍历字符串
<div id='app'>
<div v-for='item in msg'>{{item}}</div>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
msg: 'Hello World!!!'
},
});
</script>
遍历数组
<div id='app'>
<div v-for='item in arr'>{{item}}</div>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
msg: 'Hello World!!!',
arr: [1,2,3]
},
});
</script>
- 第二个参数:索引
- 遍历数组时可以添加第二个参数,表示数组的索引
<div id='app'>
<div v-for='(item, index) in arr'>{{item}}-{{index}}</div>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
msg: 'Hello World!!!',
arr: [1,2,3]
},
});
</script>
遍历对象
<div id='app'>
<div v-for='item in obj'>{{item}}</div>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
msg: 'Hello World!!!',
arr: [1,2,3],
obj: {
name: '张三',
age: 18,
gender: '男'
}
},
});
</script>
- 只有一个参数的话默认是对象的
value
值 - 第二个参数:
key
值,第三个参数:索引
<div id='app'>
<div v-for='(value,key,index) in obj'>{{index}}-{{key}}-{{value}}</div>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: {
msg: 'Hello World!!!',
arr: [1,2,3],
obj: {
name: '张三',
age: 18,
gender: '男'
}
},
});
</script>
12.Vue中数据的更新问题
对象更新问题
- 描述:在
data
中定义一个对象obj
,现在需要通过外部方法动态地为obj
添加一个属性,应该怎么操作? - 方法:
Vue.set(vm.object, propertyName, value);
或this.$set(vm.object, propertyName, value);
- 例子:
<div id='app'> <p v-for='i in obj'>{{i}}</p> <button @click='add'>add</button> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { obj: { name: '张三', } }, methods: { add(){ Vue.set(this.obj, 'age', 18); } } }); </script>
- 效果:
- 注意:
- 不能使用普通方法
this.obj.age = 18
来新增对象属性 - 设置属性的对象不能是Vue实例,或者Vue实例的根数据对象,也就是不能通过此方法增加
Vue
实例对象得属性和data
里的属性
- 不能使用普通方法
数组数据更新问题
- 描述:对于
data
中定义的数组,要去操作改变里面的数据,应该用什么方法? - 例子:我要将数组中的第一项
arr[0]
改为“王五-22”,应该怎么去定义change()
里的方法?
- 用法:Vue封装了数组操作的七种方法
push() pop() shift() unshift() splice() sort() reverse()
- 这七种方法是Vue调用原生的数组操作方法再重新解析模板而封装成的
- 上述问题的代码:
<div id='app'> <p v-for='i in arr'>{{i.name}}-{{i.age}}</p> <button @click='change'>change</button> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { arr: [{name :'张三', age: 18},{name :'李四', age: 20}], }, methods: { change(){ this.arr.splice(0,1,{name :'王五', age: 22}) } } }); </script>
- 效果:
13.v-text和v-html
- 已经陆陆续续写了很多常用的指令语法,基本都是常用的,还有几个没提及的大家可以上官网学习一下Vue指令
- 现在最后再来补充一下
v-text
和v-html
的用法
v-text
v-text
就是将data
里的数据渲染到页面上,和插值语法{{xxx}}
的作用类似- 例子:
<div id='app'> <div v-text='message'></div> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { message: 'Hello World!' }, }); </script>
- 效果:
- 注意:如果用
v-text
渲染数据,那么写在标签中间的文字将会被覆盖掉,所以如果只想要部分渲染,还是得用插值语法
v-html
v-html
也是渲染数据,不过会将html
标签解析- 例子:
<div id='app'> <div v-html='message'></div> </div> <script> Vue.config.productionTip = false; new Vue({ el: '#app', data: { message: '<h1>Hello World!</h1>' }, }); </script>
- 效果:
- 可以看到,
<h1></h1>
标签被解析了 - 注意:在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用
v-html
,永不用在用户提交的内容上。
14.Vue的生命周期函数(TODO)
关于Vue的生命周期函数后面我重新写一篇文章
那么到此为止,Vue的基础语法都写完了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)