You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

520 lines
9.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

### 组合式API
#### 拉开序幕的setup
选项式api
```js
data(){
return {
name:'张三',
age:18,
tel:'13888888888'
}
},
methods:{
// 修改姓名
changeName(){
this.name = 'zhang-san'
},
// 修改年龄
changeAge(){
this.age += 1
},
// 展示联系方式
showTel(){
alert(this.tel)
}
}
```
在vue3的setup中可以与Data和mathods共存
冲突是按生命周期读取一般data可以读setup反之不能
##### 引入插件
`npm i vite-plugin-vue-setup-extend -d`
p 010 setup 语法糖
方便简单的对组件命名而不改变文件名,直接在script标签中加上name属性命名即可
set格式
```
setup(){
//数据
//想要修改数据时页面刷新,需要定义响应式的数据
let name = 'shu'
let age = '16'
let tel = '181'
//setup函数中this是undefind
function changeName(){
name = 'uhs'
}
function changeAge(){
age=51
}
function showTel(){
tel = '393'
}
//简写返回数据
//setup的返回值也可以是渲染函数
return {name,age,changeName,changeAge,showTel}
}
```
vue3响应式=>
ref && reactive
基本类型 && 对象类型
##### ref
```
<template>
<div class="person">
<h2>姓名:{{name}}</h2>
<h2>年龄:{{age}}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="showTel">查看联系方式</button>
</div>
</template>
<script setup name="person" >
//引入ref
import {ref} from 'vue'
let name = ref('shu')
let age = ref(16)
let tel = '181'
//setup函数中this是undefind
function changeName(){
name.value = 'uhs'
}
function changeAge(){
age.value++
}
function showTel(){
tel = '393'
}
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button {
margin: 0 5px;
}
</style>
```
ref在js层使用数据必须.value。直接在数组名或者对象名或者变量名后 . 而不是在最底层的数据后 .
reactive不用
##### toRefs & roRef
区别是可不可以批量改造
###### 解构赋值
从响应式对象中解构后的变量是非响应式的
`let{name ,age}=person`
`let{name ,age}=toRefs(person)`
##### computed
作用:根据已有数据计算出新数据(和`Vue2`中的`computed`作用一致)。
引入知识点:双向绑定
```vue
<template>
<div class="person">
<input type="text" v-model="firstName"> <br>
<input type="text" v-model="lastName"> <br>
全名<span>{{fullName}}</span> <br>
<button @click="changeFullName">全名改为:li-si</button>
</div>
</template>
<script setup lang="ts" name="App">
import {ref,computed} from 'vue'
let firstName = ref('zhang')
let lastName = ref('san')
// 计算属性——只读取,不修改
/* let fullName = computed(()=>{
return firstName.value + '-' + lastName.value
}) */
// 计算属性——既读取又修改
let fullName = computed({
// 读取
get(){
return firstName.value + '-' + lastName.value
},
// 修改
set(val){
console.log('有人修改了fullName',val)
firstName.value = val.split('-')[0]
lastName.value = val.split('-')[1]
}
})
function changeFullName(){
fullName.value = 'li-si'
}
</script>
```
计算属性有缓存,多次调用的情况下,如果依赖属性没有改变。不会多次计算。而方法没有缓存
计算属性定义get和set就可以直接改变
### watch
- 作用:监视数据的变化(和`Vue2`中的`watch`作用一致)
- 特点:`Vue3`中的`watch`只能监视以下**四种数据**
> 1. `ref`定义的数据。
> 2. `reactive`定义的数据。
> 3. 函数返回一个值(`getter`函数)。
> 4. 一个包含上述内容的数组。
解除监视watch的返回值用cons接收在使用后即可解除监视
1.ref定义的数据
```vue
<template>
<div class="person">
<h2>当前求和为{{ sum }}</h2>
<button @click="changeSum">点我sum+1</button>
</div>
</template>
<script setup name="Person">
// 引入监视
import { ref,watch } from 'vue'
//数据
let sum = ref(0)
//方法
function changeSum() {
sum.value++
}
//监视
watch(sum,(newValue,oldValue)=>{
console.log('sum变了',newValue,oldValue)
})
</script>
<style>
</style>
```
2.reactive定义的数据
```vue
<template>
<div class="person">
<h1>情况二监视ref定义的对象类型数据</h1>
<h2>姓名{{ person.name }}</h2>
<h2>年龄{{ person.age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改整个人</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {ref,watch} from 'vue'
// 数据
let person = ref({
name:'张三',
age:18
})
// 方法
function changeName(){
person.value.name += '~'
}
function changeAge(){
person.value.age += 1
}
function changePerson(){
person.value = {name:'李四',age:90}
}
/*
监视情况一监视【ref】定义的【对象类型】数据监视的是对象的地址值若想监视对象内部属性的变化需要手动开启深度监视
watch的第一个参数是被监视的数据
watch的第二个参数是监视的回调
watch的第三个参数是配置对象deep、immediate等等.....
*/
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{deep:true})
</script>
```
3.
```vue
<template>
<div class="person">
<h1>情况三监视reactive定义的对象类型数据</h1>
<h2>姓名{{ person.name }}</h2>
<h2>年龄{{ person.age }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改整个人</button>
<hr>
<h2>测试{{obj.a.b.c}}</h2>
<button @click="test">修改obj.a.b.c</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {reactive,watch} from 'vue'
// 数据
let person = reactive({
name:'张三',
age:18
})
let obj = reactive({
a:{
b:{
c:666
}
}
})
// 方法
function changeName(){
person.name += '~'
}
function changeAge(){
person.age += 1
}
function changePerson(){
Object.assign(person,{name:'李四',age:80})
}
function test(){
obj.a.b.c = 888
}
// 监视情况三监视【reactive】定义的【对象类型】数据且默认是开启深度监视的
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
})
watch(obj,(newValue,oldValue)=>{
console.log('Obj变化了',newValue,oldValue)
})
</script>
```
4.
```vue
<template>
<div class="person">
<h2>姓名{{ person.name }}</h2>
<p>年龄{{ person.age }}</p>
<p>汽车{{ person.car.c1 }}{{ person.car.c2 }}</p>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeC1">修改第一台车</button>
<button @click="changeC2">修改第一台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script setup name="Person">
import { reactive,watch } from 'vue'
let person = reactive({
name: '张三',
age: 18,
car:{
c1: '奔驰',
c2: '宝马'
}
})
//
// 方法
function changeName(){
person.name += '~'
}
function changeAge(){
person.age += 1
}
function changeC1(){
person.car.c1 = '奥迪'
}
function changeC2(){
person.car.c2 = '大众'
}
function changeCar(){
person.car = {c1:'雅迪',c2:'爱玛'}
}
// 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
/* watch(()=> person.name,(newValue,oldValue)=>{
console.log('person.name变化了',newValue,oldValue)
}) */
// 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数
watch(()=>person.car,(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})
</script>
<style>
</style>
```
5.
```
<template>
<div class="person">
<h1>情况五:监视上述的多个数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeC1">修改第一台车</button>
<button @click="changeC2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {reactive,watch} from 'vue'
// 数据
let person = reactive({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
// 方法
function changeName(){
person.name += '~'
}
function changeAge(){
person.age += 1
}
function changeC1(){
person.car.c1 = '奥迪'
}
function changeC2(){
person.car.c2 = '大众'
}
function changeCar(){
person.car = {c1:'雅迪',c2:'爱玛'}
}
// 监视,情况五:监视上述的多个数据
watch([()=>person.name,person.car],(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})
</script>
```
```
```
### 路由
以实现单页面多应用