项目答辩终于结束了:
学习规划
下面先对自己的目前的情况来说:
学长学姐让我先把vue和boot学完,所以我打算先把vue3和boot学一下,但是每天还要花一点时间在六级的听力和阅读上面,还有就是算法;
下面进行一天的具体安排:
11.15争取晚上十二点学完vue3,然后在他们答辩的时候把boot学一下;周五写试着写一下算法比赛,六级的话完成指定软件上的任务;
学习总结
vue两种风格:
选项式:API(vue2)
组合式:API(vue3)
创建vue项目名称不要用大写;
vue项目文件:
.vscode工具配置文件;
node_modules支持Vue项目运行依赖的文件夹:
public资源文件夹
src源码文件夹
git的忽略文件
index.html文件:入口html文件
package.json信息描述文件
README.md注释文件
vite.config.js vue配置文件
文本插值模板语法(双大括号语法)
可以是很多类型,到最后都可以转为文本:
<template>
<p>{{ msg }}</p>
</template>
<script>
export default{
data()
{
return {
msg:"神奇的魔法"
}
}
}
</script>
还可以用js表达式,但是是要有返回值的表达式,单纯的语句是不行的;要想插入html标签可以用v-html标签,因为{{}}两个大括号会将传过来的值转换为纯文本,像下面的例子
<template>
<p>{{ msg }}</p>
<p v-html="rawHtml"></p>
</template>
<script>
export default{
data()
{
return {
msg:"神奇的魔法",
rawHtml:"<a href='https://xinghuo.xfyun.cn/desk'>星火问答模型</a>"
}
}
}
</script>
vue属性绑定:
标签里面的属性绑定用v-bind属性:
下面是一个例子以及渲染出来的结果:
<script>
export default{
data(){
return{
dynamicClass:"active"
}
}
}
</script>
<template>
<p v-bind:class= dynamicClass>笑死了</p>
</template>
注意:如果这个要绑定的属性是null或者undefined,则不会渲染该属性,当然v-bind也可以省略只留下冒号是他的简写方式;除了字符串类型,布尔类型也是可以的,使用双引号括号起来,可以动态绑定多个属性的js对象,语法是这样的:
<script>
export default{
data(){
return{
dynamicClass:"active",
objectOfAttrs:{
id:"appid",
class:"appClass"
}
}
}
}
</script>
<template>
<!-- 两个class分开写会自动合并也不会报错 -->
<p v-bind:class= dynamicClass v-bind="objectOfAttrs">笑死了</p>
</template>
如果在某个vue文件里面运行但是并没有出现渲染,可能是没有在对应的app.vue里面去引入对应的文件 ;
条件渲染:
v-if,v-else,v-if-else
<template>
<h3>条件渲染</h3>
<div v-if="flag">你能看见我吗</div>
<div v-else>那你还是看看我吧</div>
<div v-if="type=='A'">A</div>
<div v-else-if="type=='B'">B</div>
<div v-else-if="type=='C'">C</div>
<div v-else>not a/b/c</div>
</template>
<script>
export default {
data () {
return {
flag:false,
type:"D"
}
}
}
</script>
v-show VS v-if:
列表渲染:
<template>
<h3>列表渲染</h3>
<p v-for="item in names">{{ item }}</p>
</template>
<script>
export default{
data(){
return{
names:["小麻子","小饺子","小卷卷"]
}
}
}
</script>
也可以读取JSON格式的数据,比如下面的代码:
<template>
<h3>列表渲染</h3>
<p v-for="item in names">{{ item }}</p>
<div v-for="item in result">
<div>{{ item.title }}</div>
<img :src="item.avatar" >
</div>
</template>
<script>
export default{
data(){
return{
names:["小麻子","小饺子","小卷卷"],
result:[
{"id":21113, "title":"我真的笑死了","avatar":"https://cn.bing.com/images/search?q=%E5%A5%BD%E7%9C%8B%E7%9A%84%E5%9B%BE%E7%89%87%E5%A3%81%E7%BA%B8&FORM=IQFRBA&id=985463A26E79383AD02B13F646EE714A578B2449"},
{"id":21121,"title":"我要提升自己,让自己变得很厉害很厉害","avatar":"https://cn.bing.com/images/search?q=%E5%A5%BD%E7%9C%8B%E7%9A%84%E5%9B%BE%E7%89%87%E5%A3%81%E7%BA%B8&FORM=IQFRBA&id=80FEE061772B98718F21F1E8D46994176E042DA1"}
]
}
}
}
</script>
有可选参数是数组的下标,还有就是in可以用of来替换;
还可以遍历一个对象的所有属性:
<template>
<h3>列表渲染</h3>
<p v-for="(item,index) of names">{{ item }}--{{ index }}</p>
<div v-for="item in result">
<div>{{ item.title }}</div>
<img :src="item.avatar" >
</div>
<div v-for="(value,key,index) of personInfo">{{ value }}---{{ key }}---{{ index }}</div>
</template>
<script>
export default{
data(){
return{
names:["小麻子","小饺子","小卷卷"],
result:[
{"id":21113, "title":"我真的笑死了","avatar":"https://cn.bing.com/images/search?q=%E5%A5%BD%E7%9C%8B%E7%9A%84%E5%9B%BE%E7%89%87%E5%A3%81%E7%BA%B8&FORM=IQFRBA&id=985463A26E79383AD02B13F646EE714A578B2449"},
{"id":21121,"title":"我要提升自己,让自己变得很厉害很厉害","avatar":"https://cn.bing.com/images/search?q=%E5%A5%BD%E7%9C%8B%E7%9A%84%E5%9B%BE%E7%89%87%E5%A3%81%E7%BA%B8&FORM=IQFRBA&id=80FEE061772B98718F21F1E8D46994176E042DA1"}
],
personInfo:
{
//对于对象来说上面会有三个属性value,key,index
"id":11111,
"name":"小饺子",
"signature":"我是一只小小小鸟"
}
}
}
}
</script>
小插曲
还有就是两个在实践敲代码出现了两个问题以及解决方案:
第一个问题,在用v-for的时候报错,配置不同表达方式不同,解决方案:
v-for报错及其解决方案
第二个问题:在关于列表渲染的时候如果用了第二个参数但是没有使用的话就会报错,如果不用的话可以不选,可以看看这个博客:
同时解释一下:
vue默认按照就地更新策略:
这样会消耗很大的性能,所以我们可以通过索引的方式来优化,所以还是建议用刚开始带有key的 :
下面是有关的例子:
<template>
<h3>key属性添加</h3>
<div v-for=" (item,index) of result" :key="index">{{ item }}</div>
</template>
<script>
export default{
data(){
return{
result:["小麻子","小饺子","小卷卷"]
}
}
}
</script>
但是在实际工作场景中,我们一般的话就是要将数据的唯一索引作为key,比如这个例子里面是将id作为唯一索引 :
温馨提示:
index第二个可选参数报错及其解决
还有就是穿插一下自己前面几个写代码的时候容易犯的错误还不容易被发现的:
1.总是忘记返回的两个数据之间要用逗号间隔;
2.返回的数据里面数值和布尔值不用双引号;
3.属性都要用概括,而且数组名和数组之间也要用引号
事件处理:
内联事件处理器:
<template>
<h3>内联事件处理器</h3>
<button v-on:click="count++">按钮</button>
<div>{{ count }}</div>
</template>
<script>
export default{
data()
{
return{
count:0
}
}
}
</script>
方法事件处理器:
注意,要将data里面的数据放到方法里面一起用的话,可以在data的同级创建一个methods:{}里面放所有的方法,下面是方法事件处理器的举例:
<template>
<h3>方法处理器</h3>
<button @click="myClick">按钮</button>
<div>{{ count }}</div>
</template>
<script>
export default{
data()
{
return{
count:0
}
},
methods: {
myClick()
{
this.count++;
}
}
}
</script>
事件传参
vue中的event对象就是原生的js对象;
下面是一个传递参数的demo:
<template>
<h3>事件传参</h3>
<button @click="myClick(item)" v-for="(item,index) in names" :key="index">{{ item }}</button>
<div>{{ count }}</div>
</template>
<script>
export default{
data()
{
return{
count:0,
names:["haha","hehe","wuyu"]
}
},
methods: {
myClick(msg)
{
console.log(msg)
}
}
}
</script>
注意:如果传入的函数没有传参,这是就可以在方法上面加上方法本身参数,但是如果传递了参数,还想要传递方法参数,这时候可以通过这种方法来额外获得(加一个$event):
<template>
<h3>事件传参</h3>
<button @click="myClick(item,$event)" v-for="(item,index) in names" :key="index">{{ item }}</button>
<div>{{ count }}</div>
</template>
<script>
export default{
data()
{
return{
count:0,
names:["haha","hehe","wuyu"]
}
},
methods: {
myClick(msg,e)
{
console.log(msg);
console.log(e.target);
}
}
}
</script>
事件修饰符:
.prevent表示阻止默认事件,(比如点击a标签就会跳转到对应的href的默认事件),.stop表示阻止冒泡事件,下面是对应的例子:
<template>
<h3>事件修饰符</h3>
<a @click.prevent="myClick" href="https://blog.csdn.net/qq_43617869/article/details/111453185#:~:text=%E5%A6%82%E4%BD%95%E5%9C%A8vscode%E4%B8%AD%E6%94%BE%E5%A4%A7%E7%BC%A9%E5%B0%8F%E4%BB%A3%E7%A0%81%201%20%E4%BE%9D%E6%AC%A1%E7%82%B9%E5%87%BB%E2%80%9C%E6%96%87%E4%BB%B6%E2%80%9D-%E2%80%9C%E9%A6%96%E9%80%89%E9%A1%B9%E2%80%9D-%E2%80%9C%E8%AE%BE%E7%BD%AE%E2%80%9D%E3%80%82%202%20%E7%84%B6%E5%90%8E%E7%82%B9%E5%87%BB%22%E5%9C%A8settings.json%E4%B8%AD%E7%BC%96%E8%BE%91%22%E3%80%82,3%20%E5%9C%A8setting%E6%B7%BB%E5%8A%A0%E5%A6%82%E4%B8%8B%E4%BB%A3%E7%A0%81%EF%BC%8C%E6%B7%BB%E5%8A%A0%E4%B9%8B%E5%90%8E%E8%AE%B0%E5%BE%97%E5%9C%A8%E5%89%8D%E4%B8%80%E5%8F%A5%E7%9A%84%E7%BB%93%E5%B0%BE%E5%A4%84%E5%8A%A0%E4%B8%8A%E8%8B%B1%E6%96%87%E7%9A%84%E9%80%97%E5%8F%B7%22%2C%22%E3%80%82%204%20%22editor.mouseWheelZoom%22%3A%20true">我的博客</a>
<div @click="myClickCopy"><div @click.stop="myClick"></div></div>
</template>
<script>
export default{
data()
{
return{
count:0,
names:["haha","hehe","wuyu"]
}
},
methods: {
myClick(e)
{
console.log(e.target);
console.log("small");
},
myClickCopy()
{
console.log("big");
}
}
}
</script>
数组变化侦测:
<t<template>
<!-- 有些方法是可以被识别让ui更新的,但是有些是不可以的 -->
<h3>数组变化侦听</h3>
<div v-for="(name,index) in names" :key="index">{{ name }}</div>
<button @click="addSome">添加</button>
</template>
<script>
export default{
data(){
return{
names:["mazi","juanjuan","jiaozi"]
}
},
methods: {
addSome()
{
//第一种可以引起UI变化
//this.names.push("笑哈哈");
//第二种不可以引起UI变化
this.names.concat(["笑嘻嘻"]);
//第二种解决方案,可以认为合并之后的是创建了一个新的数组,而不是原来的
// this.names=this.names.concat(["笑嘻嘻"]);
console.log(this.names);
}
}
}
</script>
后面才发现这是vue2的内容,下面才是vue3;
vue3:
认识vue3的文件根目录
这里介绍几个其中的特点:
App.vue
<!-- setup表示组合式API可以在script里面使用 -->
<script setup>
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
</script>
<template>
<!-- 可以在template里面放置多个根元素 -->
<header>
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
<div class="wrapper">
<HelloWorld msg="You did it!" />
</div>
</header>
<main>
<TheWelcome />
</main>
</template>
<style scoped>
header {
line-height: 1.5;
}
.logo {
display: block;
margin: 0 auto 2rem;
}
@media (min-width: 1024px) {
header {
display: flex;
place-items: center;
padding-right: calc(var(--section-gap) / 2);
}
.logo {
margin: 0 2rem 0 0;
}
header .wrapper {
display: flex;
place-items: flex-start;
flex-wrap: wrap;
}
}
</style>
main.js
import './assets/main.css'
// 入口文件
// createApp创建应用实例,保证了每个实例的封闭独立性
import { createApp } from 'vue'
import App from './App.vue'
// 提供id是app的挂载点
createApp(App).mount('#app')
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<!-- 挂载到id是app的盒子里面 -->
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
初识setup
1.执行时机,setup比beforeCreate还要早;
2.所以this是undefined,this不利于组合式封装;
3.如果没有在script加上setup,数据和函数需要在最后return才能在模板中应用;
setup原理:语法糖原理
示例代码:
<!-- setup表示组合式API可以在script里面使用 -->
<script setup>
const message = 'this is a message'
const logMessage = ()=>{
console.log(message);
}
</script>
<template>
<div>{{ message }}</div>
<button @click="logMessage">按钮</button>
</template>
ref和reactive关键字
reactive:接收对象数据的类型参数传入并返回一个响应式对象(随着数值变化,UI自动更新);也就是说,在这里面没有用这个包起来的就不是响应式数据,就不会随着数值的变化而变化
实例:
<!-- setup表示组合式API可以在script里面使用
<script setup>
const message = 'this is a message'
const logMessage = ()=>{
console.log(message);
}
</script>
<template>
<div>{{ message }}</div>
<button @click="logMessage">按钮</button>
</template>
-->
<script setup>
import { reactive } from 'vue';
const state=reactive({
count:100
})
const logCount=()=>
{
state.count++;
}
</script>
<template>
<h3>reactive关键字</h3>
<div>{{ state.count }}</div>
<button @click="logCount">按钮</button>
</template>
ref:接受简单类型或者对象,然后返回一个响应式对象:
本质上还是在原有传入数据的基础上再包了一层对象,包成了复杂类型;底层还是借助reactive实现,注意在脚本中.value要写上,但是在template中就不需要了;
实例:
<script setup>
import { ref } from 'vue';
const state=ref(100)
const logCount=()=>
{
state.value++;
}
</script>
<template>
<h3>reactive关键字</h3>
<div>{{ state}}</div>
<button @click="logCount">按钮</button>
</template>
计算属性:
两种方式:
方式一:只读
<script setup>
import { ref } from 'vue';
import{ computed } from 'vue';
const state=ref(100)
const list=ref([1,2,3,4,5,6]);
const addInfo=()=>
{
list.value.push(state.value);
}
const computedList=computed(()=>{
return list.value.filter(item=>item>2)
})
</script>
<template>
<h3>computed关键字</h3>
<div>{{ list }}</div>
<div>{{ computedList }}</div>
<button @click="addInfo">按钮</button>
</template>
方式2:可读可写:
<script setup>
import { ref } from 'vue';
import{ computed } from 'vue';
const state=ref(100)
const list=ref([1,2,3,4,5,6]);
const addInfo=()=>
{
list.value.push(state.value);
}
const computedList=computed({
get:()=> list.value.filter(item=>item>2),
set:(val)=>list.value.push(val+1)
})
</script>
<template>
<h3>computed关键字</h3>
<div>{{ list }}</div>
<div>{{ computedList }}</div>
<button @click="addInfo">按钮</button>
</template>
具体可写属性调用可以参考:Vue Computed中get 和set讲解_computed get set-CSDN博客
watch:
watch(ref对象,(newValue,oldValue)=>{...})单个对象
<!-- setup表示组合式API可以在script里面使用
<script setup>
const message = 'this is a message'
const logMessage = ()=>{
console.log(message);
}
</script>
<template>
<div>{{ message }}</div>
<button @click="logMessage">按钮</button>
</template>
-->
<!--
<script setup>
import { reactive } from 'vue';
const state=reactive({
count:100
})
const logCount=()=>
{
state.count++;
}
</script>
<template>
<h3>reactive关键字</h3>
<div>{{ state.count }}</div>
<button @click="logCount">按钮</button>
</template> -->
<!--
<script setup>
import { ref } from 'vue';
const state=ref(100)
const logCount=()=>
{
state.value++;
}
</script>
<template>
<h3>reactive关键字</h3>
<div>{{ state}}</div>
<button @click="logCount">按钮</button>
</template> -->
<!--
<script setup>
import { ref } from 'vue';
import{ computed } from 'vue';
const state=ref(100)
const list=ref([1,2,3,4,5,6]);
const addInfo=()=>
{
list.value.push(state.value);
}
const computedList=computed({
get:()=> list.value.filter(item=>item>2),
set:(val)=>list.value.push(val+1)
})
</script>
<template>
<h3>computed关键字</h3>
<div>{{ list }}</div>
<div>{{ computedList }}</div>
<button @click="addInfo">按钮</button>
</template> -->
<script setup>
import { ref,watch} from 'vue';
const count=ref(1);
const nickName=ref("张三");
const setCount=()=>
{
count.value=2;
}
const setNickName=()=>
{
nickName.value="利斯";
}
watch(count,(newValue,oldValue)=>{
console.log(newValue,oldValue);
});
</script>
<template>
<div>{{ count }}</div>
<button @click="setCount">改数字</button>
<div>{{ nickName }}</div>
<button @click="setNickName">改昵称</button>
</template>
watch([ref对象1,ref对象2],(newValue,oldValue)=>{...})
<script setup>
import { ref,watch} from 'vue';
const count=ref(1);
const nickName=ref("张三");
const setCount=()=>
{
count.value=2;
}
const setNickName=()=>
{
nickName.value="利斯";
}
watch([count,nickName],(newValues,oldValues)=>{
console.log(newValues,oldValues);
});
</script>
<template>
<div>{{ count }}</div>
<button @click="setCount">改数字</button>
<div>{{ nickName }}</div>
<button @click="setNickName">改昵称</button>
</template>
可以额外配置立刻触发回调:(也就是一进页面就触发一次),
<script setup>
import { ref,watch} from 'vue';
const count=ref(1);
const nickName=ref("张三");
const setCount=()=>
{
count.value=2;
}
const setNickName=()=>
{
nickName.value="利斯";
}
watch([count,nickName],(newValues,oldValues)=>{
console.log(newValues,oldValues);
},
{
immediate:true
});
</script>
<template>
<div>{{ count }}</div>
<button @click="setCount">改数字</button>
<div>{{ nickName }}</div>
<button @click="setNickName">改昵称</button>
</template>
对于ref来说,只能浅层监视,也就是只有出现新的对象的时候才会被发现,二reactive默认的是强制开启了深层监视,里面的成员值变化也可以看见;但是对象的话无法正确获取旧的值:
<script setup>
import { ref,watch} from 'vue';
const userInfo=ref({
age:18,
nickName:"zhangsan"
})
const setUserInfo=()=>{
userInfo.value.age++;
}
watch(userInfo,(newValues,oldValues)=>{
console.log(newValues,oldValues);
},
{
deep:true
});
</script>
<template>
<button @click="setUserInfo">改信息</button>
<div>{{ userInfo}}</div>
</template>
精确侦听对象的某个属性:
<script setup>
import { ref,watch} from 'vue';
const userInfo=ref({
age:18,
nickName:"zhangsan"
})
const setUserInfo=()=>{
userInfo.value.nickName="笑死";
}
watch(()=>userInfo.value.age,(newValues,oldValues)=>{
console.log(newValues,oldValues);
},
{
deep:true
});
</script>
<template>
<button @click="setUserInfo">改信息</button>
<div>{{ userInfo}}</div>
</template>
生命周期函数
<script setup>
// beforeCreate 和created的相关代码
// 一律放在setup中执行
// 一进入页面的请求
import { onMounted } from 'vue';
// 如果有些代码需要在mounted生命周期中执行
onMounted(()=>
{
})
</script>
还有一些还没来的及写总结,但是这一周的执行力是真的不高,什么都没有真正完成,新的一周要加油啊?然后就是看到一段特别有感触的话,虽然已经不适合我这个年龄了,但是性质还是差不多的:
作者:
链接:https://www.zhihu.com/question/336477952/answer/1124121900
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本人今年高二,家里最大的一个孩子。我给你讲个事儿,我的壁纸是我自己写的便签,上面写着明天和意外,你永远不知道哪个先来。在3月21日,这一天我和往常一样咸鱼,桌上放着堆着的作业,不想写,不会写,放着吧,想着等到要交的时候我再写。然后,我妈突然在房间喊我和我妹,声音是颤抖的。我跑过去,就看见我妈躺在床上不得动弹,捂着心脏。我顿时就慌了神,也不知道该怎么办,只能去拼命去喊住在我们家对面的小婶。当时是真的很害怕。后来我小婶过来了,我妈当时就靠着我小婶哭了,说她难受,说她冷,明明她还盖着一层很厚的被子。后来,我爸回来了,载着我妈和我小婶去医院急诊。那一晚,我整夜没有合眼。而我小婶也是半夜三四点才回家。我就在窗边听她说。她说,我妈就坐在急诊室门口,心率从九十多飚到一百6,一百七,忽上忽下。又说,医生说:如果,我妈不乖乖住院的话,他也不敢保证我妈会怎样。还说,我爸当时去交钱的时候,全身上面只有几百块钱,钱也不够。还有我妈当时和她说,怎么办,家里欠着别人债没还,孩子也还没养大。怎么办,我也不知道,但那一次确确实实意识到,如果,意外来了,我什么也干不了。幸好,后来我妈康复出院了,检查最后的结果是没有什么大问题。真的,对于一个普通家庭来说,目前最快速的方法就是高考。不是说其他方法不行,但谁能保证意外在你准备好的时候就来呢?你能做的只有在意外来临之前,让自己更强。