Vue3学习
1. 配置环境
1.1. 安装nodejs(建议安装14版本稳定)
下载|Nodejs官网
装好之后可以使用以下命令进行查看,来确定是否安装成功
1.2. 构建vite项目
1.2.1 使用vite初始化一个项目
npm
npm init vite@latest
yarn
yarn create vite
运行之后,跟着提示走就好(项目名称、项目模板......)
1.3 安装vue cli 脚手架
npm install @vue/cli -g 进行脚手架安装
vue -V 检查是否安装成功
vue create 项目名称 进行项目创建
1.4 VSCode 插件
- Vue Language Features(Volar)
- TypeScript Vue Plugin (Volar)
1.5 安装less
在项目路径下使用如下命令进行安装
npm install less less-loader
2. Vite目录&Vue单文件组件
2.1. Vite目录
public 下面的不会被编译,可以存放静态资源
assets 下面可以存放可编译的静态资源
components 下面用来我们的组件
App.Vue 是全局组件
main.ts 全局的ts文件
index.html 非常重要的入口文件(webpack,rollup他们的入口文件都是enrty input是一个js文件而Vite的入口文件是一个html文件,他刚开始不会编译这些js文件,只有当你用到的时候 如 script src="xxxx.js"会发起一个请求被vite拦截这时候才会解析js文件)
vite.config.ts 这是vite的配置文件具体配置项
2.2 SFC语法规范
.vue都由三种类型的顶层语法块所组成:<template>、<script>、<style>
- <template>
- 每个*.vue文件最多可同时包含一个顶层<template>块
- 其中的内容会被提取出来传递给@vue/compiler-dom,预编译为JavaScript的渲染函数,并附属到导出的组件上作为其render选项
- <script>
- 每一个*.vue文件最多可同时包含一个<script>块(不包括<script setup>)
- 该脚本将作为ES Module来执行
- 其默认导出的内容应该是Vue组件选项对象,它要么是一个普通对象,要么是defineComponent的返回值
- <script setup>
- 一个*.vue文件最多可同时包含一个<script setup>块(不包括常规的<script>)
- 该脚本会被处理并作为组件的setup()函数使用,也就是说它会在每个组件实例中执行。<script setup>的顶层版绑定会自动暴露给模板
- <style>
- 一个*.vue文件最多可同时包含多个<style>标签
- <style>标签可以通过scoped和module将样式封装在当前组件中。多个不同封装模式的<style>标签可以在同一个组件中混用
3. Vue指令
v- 开头都是vue的指令
- v-text 用来显示文本
- v-html 用来展示富文本
- v-if 用来控制元素的显示隐藏(切换真假的DOM)
- v-else-if 表示v-if的"else if"块。可以链式调用
- v-else v-if 条件收尾语句
- v-show 用来控制元素的显示隐藏(display none block Css切换)
- v-on 简写@ 用来给元素添加事件
- v-bind 简写: 用来绑定元素的属性Attr
- v-model 双向绑定
- v-for用来遍历元素
- v-on 修饰符 (冒泡)
4. ref全家桶
4.1 ref
接受一个内部值并返回一个响应且可变的ref对象。ref对象仅有一个.value property,指向该内部值
<template>
<div>
<button @click="changeMsg">change</button>
{{message}}
</div>
</template>
<script setup lang="ts">
import {ref,Ref} from 'vue';
// let message:Ref<string>=ref('hello')
let message=ref<string|number>('hello')
const changeMsg=()=>{
message.value="你好"
}
</script>
<style scoped>
</style>
4.2 isRef
判断是不是一个ref对象
<script setup lang="ts">
import {isRef, ref,Ref} from 'vue';
let message:Ref<string>=ref('hello')
let notRef:number=123
const changeMsg=()=>{
message.value="你好"
// isRef() 判断是不是一个ref对象
console.log(isRef(message)) //true
console.log(isRef(notRef)) //false
}
</script>
4.3 shallowRef
创建一个跟踪自身.value变化的ref,但不会使其值也变成响应式的
<script setup lang="ts">
import {shallowRef} from 'vue';
let message=shallowRef({
name:'hello'
})
const changeMsg=()=>{
// message.value.name='你好' //无法响应式改变值
// console.log(message)
message.value={name:'你好'} //可以动态响应
}
</script>
4.4 triggerRef
强制更新页面DOM
<script setup lang="ts">
import {shallowRef, triggerRef} from 'vue';
let message=shallowRef({
name:'hello'
})
const changeMsg=()=>{
message.value.name='你好' //无法响应式改变值
triggerRef(message) //强制更新dom
}
</script>
4.5 customRef
自定义ref
5. Reactive 全家桶
5.1 reactive
用来绑定复杂的数据类型,例如 对象、数组,绑定普通的数据类型可以使用ref
<template>
<div>
<button @click="changeMsg">change</button>
{{person.name}}
</div>
</template>
<script setup lang="ts">
import {reactive} from 'vue';
let person=reactive({
name:'zs'
})
const changeMsg=()=>{
person.name="张三"
}
</script>
<style scoped>
</style>
5.2 readonly
拷贝一份proxy对象将其设置为只读
<script setup lang="ts">
import {reactive,readonly} from 'vue';
let person=reactive({
name:'zs'
})
let copy=readonly(person)
const changeMsg=()=>{
copy.name='张三' //无法赋值,只读的 (浏览器控制台输出警告)
}
</script>
<style scoped>
5.3 shallowReactive
只能怼浅层的数据,如果是深层的数据只会改变值,不会改变视图
<template>
<div>
<button @click="changeMsgname">changename</button>
<button @click="changeMsgshow">changeshow</button>
{{person}}
</div>
</template>
<script setup lang="ts">
import {shallowReactive} from 'vue';
let person=shallowReactive({
name:'zs',
test:{
test2:{
show:'test_test2:show'
}
}
})
const changeMsgname=()=>{
person.name="张三"
}
const changeMsgshow=()=>{
person.test.test2.show="test_test2_显示" //这里修改,知识值会变,显示不变
console.log(person)
}
</script>
<style scoped>
</style>
6 to系列全家桶
6.1 toRef
如果原始对象是非响应式的就不会更新视图,数据是会变的
<template>
<div>
<button @click="change">change</button>
{{state}}
</div>
</template>
<script setup lang="ts">
import {toRef,reactive} from 'vue';
// const obj={
// foo:1,
// bar:1
// }
const obj=reactive({
foo:1,
bar:1
}) //添加reactive后进行操作,页面显示会改变
const state=toRef(obj,'bar')
const change=()=>{
state.value++
console.log('原始对象',obj);
console.log('引用对象',state);
}
</script>
<style scoped>
</style>
6.2 toRefs
可以帮我们批量创建ref对象主要是方便我们解构使用
<template>
<div>
<button @click="change">change</button>
foo---{{foo}}
bar--{{bar}}
</div>
</template>
<script setup lang="ts">
import {toRefs,reactive} from 'vue';
let obj=reactive({
foo:1,
bar:1
}) //添加reactive后进行操作,页面显示会改变
let {foo,bar}=toRefs(obj)
console.log(foo,bar);
const change=()=>{
foo.value++
bar.value++
console.log(foo,bar);
}
</script>\
<style scoped>
</style>
6.3 toRaw
将响应式对象转化为普通对象
<template>
<div>
</div>
</template>
<script setup lang="ts">
import {toRaw,reactive} from 'vue';
let obj=reactive({
foo:1,
bar:1
}) //添加reactive后进行操作,页面显示会改变
const raw=toRaw(obj) //将响应式对象变为原始对象
console.log('响应式的',obj);
console.log('raw',raw);
</script>
<style scoped>
</style>
7 computed计算属性
用法
计算属性就说当依赖的属性的值发生变化的时候,才会触发它的改变,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值
<template>
<div>
<input type="text" v-model="firstname">
<input type="text" v-model="lastname">
{{firstname}} --{{lastname}}
{{name}}
</div>
</template>
<script setup lang="ts">
import {ref,computed} from 'vue';
let firstname=ref('')
let lastname=ref('')
// 函数形式
// const name=computed(()=>{
// return firstname.value+'---'+lastname.value
// })
// 对象形式
const name=computed({
get(){
return firstname.value+lastname.value
},
set(){
firstname.value+lastname.value
}
})
</script>
<style scoped>
</style>
8. watch侦听器
watch需要侦听特定的数据源,并在单独的回调函数中执行
watch第一个参数监听源
watch第二个参数回调函数cb(newValue,oleValue)
watch第三个参数一个options配置项是一个对象{
immediate:true //是否立即调用一次
deep:true 是否开启深度监听
}
<template>
<div>
<!-- <input type="text" v-model="obj.nar.bar.name" /> -->
<!-- <input type="text" v-model="message2"> -->
<input type="text" v-model="obj.name" />
<input type="text" v-model="obj.age" />
</div>
</template>
<script setup lang="ts">
import { ref, watch, reactive } from "vue";
// let message = ref<string>("");
// let message2 = ref<string>("");
// 监听一个值
// watch(message,(newVal,oldVal)=>{
// console.log('新值',newVal);
// console.log('旧值',oldVal);
// })
//监听多个值
// watch([message, message2], (newval, oldval) => {
// console.log("新值", newval);
// console.log("旧值", oldval);
// });
// 监听对象(深度监听,有bug新旧值一样)
// let obj=ref({
// nar:{
// bar:{
// name:'zs'
// }
// }
// })
// watch(obj,(newval,oldval)=>{
// console.log('新的',newval);
// console.log('旧的',oldval);
// },{
// deep:true
// })
//监听对象(监听reactive,可以不配置deep也可以深度监听,新旧值一样)
// let obj=reactive({
// nar:{
// bar:{
// name:'zs'
// }
// }
// })
// watch(obj,(newval,oldval)=>{
// console.log('新的',newval);
// console.log('旧的',oldval);
// })
//监听对象单一值
let obj = reactive({
name: "zs",
age: 18,
});
watch(
() => obj.name,
(newval, oldval) => {
console.log("新值", newval);
console.log("旧值", oldval);
}
);
</script>
<style scoped></style>
9 watchEffect高级侦听器
立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该行数
如果用到message就只会监听message,就是用到几个监听几个,而且是非惰性,会默认调用一次
<template>
<div>
<input type="text" v-model="message" />
<input type="text" v-model="message2">
</div>
</template>
<script setup lang="ts">
import { ref,watchEffect } from "vue";
let message=ref<string>('大猫')
let message2=ref<string>('大狗')
watchEffect(()=>{
console.log('message---',message.value);
})
</script>
<style scoped></style>
清楚副作用
就说在触发监听器之前会调用一个函数可以处理你的逻辑 例如防抖
<template>
<div>
<input type="text" v-model="message" />
<input type="text" v-model="message2">
</div>
</template>
<script setup lang="ts">
import { ref,watchEffect } from "vue";
let message=ref<string>('大猫')
let message2=ref<string>('大狗')
watchEffect((oninvalidate)=>{
console.log('message---',message.value);
oninvalidate(()=>{
console.log("监听之前");
})
})
</script>
<style scoped></style>
停止跟踪watchEffect返回一个函数,调用之后将停止监听
<template>
<div>
<input type="text" v-model="message" />
<input type="text" v-model="message2">
<button @click="stopwatch">停止</button>
</div>
</template>
<script setup lang="ts">
import { ref,watchEffect } from "vue";
let message=ref<string>('大猫')
let message2=ref<string>('大狗')
const stop= watchEffect((oninvalidate)=>{
console.log('message---',message.value);
oninvalidate(()=>{
console.log("监听之前");
})
})
const stopwatch=(()=>{
stop()
})
</script>
<style scoped></style>
10 组件生命周期
- onBeforeMount
页面(组件)创建之前,页面的dom元素是无法读取到的 - onMounted
页面(组件)创建完成,可以拿到dom元素 - onBeforeUpdate
dom元素(组件)更新之前 - onUpdated
dom元素(组件)更新之后 - onBeforeUnmount
组件卸载之前 - onUnmounted
组件卸载之后
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义