1,composition api的使用.vue
Setup函数是一个新的组件选项,作为组件中composition API的起点
从生命周期钩子的角度来看,setup会在beforeCreate钩子函数之前执行
Setup中不能使用this,this指向undefined
<template>
<div>
<h1>当前鼠标的位置</h1>
<div>{{ msg }}</div>
<div>{{ x }}, {{ y }}</div>
</div>
</template>
<script>
import { reactive, onMounted, onUnmounted, toRefs, ref } from 'vue'
function mouseHandle() {
const mouse = reactive({
x: 0,
y: 0
})
const move = (e) => {
mouse.x = e.pageX
mouse.y = e.pageY
}
onMounted(() => {
document.addEventListener('mousemove', move)
})
onUnmounted(() => {
document.removeEventListener('mousemove', move)
})
return mouse
}
export default {
setup() {
// composition api的入口 setup会在beforeCreate钩子函数之前执行
// 不能访问this
const mouse = mouseHandle()
const msg = ref('hello')
return {
...toRefs(mouse),
msg
}
}
}
</script>
2,reactive使用
Reactive函数接受一个普通对象,返回该对象的响应式代理。
<template>
<div class="app">
<div>{{ car.brand }}----{{ car.price }}</div>
<button @click="car.brand = '奔驰'">修改</button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
// 1. setup需要返回值, setup中返回的值才能在模板中使用
// 2. reactive中传入一个普通对象,返回一个代理对象
const car = reactive({
brand: '宝马',
price: 100
})
return {car}
}
}
</script>
3,ref使用
ref函数接受一个简单类型的值,返回一个可改变的ref对象。返回的对象有唯一的属性 value
在setup函数中,通过ref对象的value属性可以访问到值
在模板中,ref属性会自动解套,不需要额外的.value
如果ref接受的是一个对象,会自动调用reactive
<template>
<div class="app">
<div>我的金钱:{{ money }}</div>
<button @click="money++">修改</button>
</div>
</template>
<script>
import {ref } from 'vue'
export default {
setup() {
// 1. ref函数接受一个简单类型, 返回一个响应式的对象
// 2. 这个响应式对象只有一个属性 value
// 3. 在模板中使用ref,会自动解套,,,,会自动调用value
let money = ref(100)
money.value++
return {money}
}
}
</script>
4,toRefs使用
把一个响应式对象转换成普通对象,该普通对象的每个 property 都是一个 ref
Reactive的响应式功能是赋予给对象的,但是如果给对象解构或者展开的时候,会让数据丢失响应式的能力。
使用toRefs可以保证该对象展开的每一个 属性都是响应式的
<template>
<div class="app">
<div>我的金钱:{{ money }}</div>
<div>{{ car.brand }} --- {{ car.price }}</div>
<div>{{ name }}</div>
<button @click="money++">修改</button>
<button @click="name = 'ls'">修改</button>
</div>
</template>
<script>
import { reactive, ref, toRefs } from 'vue'
export default {
setup() {
const state = reactive({
money: 100,
car: {
brand: '宝马',
price: 1000000
},
name: 'zs'
})
return {
// money, car, name
...toRefs(state)
}
}
}
</script>
5,readonly
传入一个对象(响应式或普通)或 ref,返回一个原始对象的只读代理。
一个只读的代理是“深层的”,对象内部任何嵌套的属性也都是只读的。
可以防止对象被修改
<template>
<div class="app">
<div>我的钱: {{ money }}</div>
<div>{{ car.brand }} ---{{ car.price }}</div>
<button @click="money++">按钮</button>
<button @click="car.price = 200">按钮</button>
</div>
</template>
<script>
import { reactive, ref, readonly } from 'vue'
export default {
setup() {
const money = ref(100)
const car = readonly({
brand: 'zs',
price: 18
})
return {
money: readonly(money),
car
}
}
}
</script>
6,computed
Computed函数用于创建一个计算属性
如果传入的是一个getter函数,会返回一个不允许修改的计算属性
如果传入的是一个带有getter和setter函数的对象,会返回一个允许修改的计算属性
<template>
<div class="app">
<div>我今年的年龄:<input type="text" v-model="age" /></div>
<div>我明年的年龄:<input type="text" v-model="nextAge" /></div>
<div>我后年的年龄: <input type="text" v-model="nextAge2" /></div>
</div>
</template>
<script>
import { ref, computed } from 'vue'
export default {
setup() {
// computed计算属性的使用
const age = ref(18)
// computed是一个函数
// 1. 传入一个函数 getter 返回一个不允许修改的计算属性。
const nextAge = computed(() => {
return parseInt(age.value) + 1
})
// 2. 传入一个对象,包括get和set,,可以创建一个可以修改的计算属性
const nextAge2 = computed({
get() {
return parseInt(age.value) + 2
},
set(value) {
age.value = value - 2
}
})
return {
age,nextAge,nextAge2
}
}
}
</script>
7, watch
Watch函数接受3个参数。
参数1:数据源,可以是ref或者getter函数
参数2:回调函数
参数3:额外选项,immediate和deep
Watch可以监听一个ref或者一个带有返回值的getter函数
Watch可以监听单个数据源,也可以监听多个数据源
watch函数会有返回值,用于停止监听。
<template>
<div class="app">
<div>{{ money }}</div>
<div>{{ car.brand }}</div>
<button @click="money++">按钮</button>
<button @click="car.brand = '奔驰'">按钮2</button>
</div>
</template>
<script>
import { ref, toRefs, watch, reactive } from 'vue'
export default {
setup() {
const state = reactive({
money: 100,
car: {brand: '宝马'}
})
// 接受3个参数
// 参数1:监视的数据源 可以是一个ref 或者是一个函数
// 参数2:回调函数 (value, oldValue) =>{}
// 参数3:额外的配置 是一个对象 { deep: true, immediate: true } //深度监听,初次渲染就立即执行
// watch(
// () => state.money,
// (value, oldValue) => {
// console.log('money变化了', value, oldValue)
// }
// )
// watch(
// () => state.car,
// (value) => {
// console.log('车变了', value)
// },
// {
// deep: true,
// immediate: false
// }
// )
// watch([() => state.money, () => state.car], ([money, car]) => {
// console.log('数据变化了', money, car)
// })
watch(
state, //监听整个数据
(value) => {console.log('数据变化了', value)},
{deep: true }
)
// watch用于实现监听
return {...toRefs(state)}
}
}
</script>
8,生命周期钩子函数
Vue3提供的生命周期钩子注册函数只能在 setup() 期间同步使用
9,provide和inject
Vue3中提供了provide和inject提供依赖注入,用于实现组件之间的通讯。类似于vue2中的provide和inject。
Vue3提供的provide和inject可以用于跨多级组件进行通讯
<template>
<div class="app">
<h1>钩子函数----{{ money }}</h1>
<button @click="money++">按钮</button>
<hr />
<Demo :money="money"></Demo>
</div>
</template>
<script>
import Demo from './Demo.vue'
import { ref, provide } from 'vue'
export default {
components: {
Demo
},
setup() {
// provider和inject
const money = ref(100)
// js中作用域问题
const changeMoney = (n) => {
console.log(money)
money.value = n
}
// 组件提供了money属性
provide('money', money) //传值
provide('changeMoney', changeMoney) //子传父,传方法
return {
money
}
}
}
</script>
子组件
<template>
<div class="demo">
我是demo组件 ---{{ money }}
<hr />
<Hello></Hello>
</div>
</template>
<script>
import { inject } from 'vue'
import Hello from './Hello.vue'
export default {
components: {
Hello
},
setup(props) { //使用props方法,没有了this
console.log(props)
const money = inject('money') //多个属性,就要inject多次
return {
money
}
},
props: {
money: Number
}
}
</script>
子孙组件
<template>
<div>
hello组件 ---{{ money }}
<button @click="fn">修改</button>
</div>
</template>
<script>
import { inject } from 'vue'
export default {
setup() {
const money = inject('money')
const changeMoney = inject('changeMoney')
const fn = () => {
changeMoney(200000) //调用传值
}
return {
money,
fn
}
}
}
</script>
10,模板refs
为了获得对模板内元素或组件实例的引用,我们可以像往常一样在 setup() 中声明一个 ref 并返回它
<template>
<div class="app">
<h1 ref="hRef">钩子函数----123</h1>
<Demo ref="dRef"></Demo>
</div>
</template>
<script>
import Demo from './Demo.vue'
import { ref, provide, onMounted } from 'vue'
export default {
components: {Demo},
setup() {
// 创建了一个空的ref
const hRef = ref(null)
const dRef = ref(null)
onMounted(() => {
console.log(hRef.value.innerHTML)
console.log(dRef.value)
})
return {hRef,dRef}
}
}
</script>