|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 组合式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>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 路由
|
|
|
|
|
|
|
|
|
|
以实现单页面多应用
|