API:应用程序接口,Application Programming Interface,是一些预先定义的接口或者是软件系统不同组成部分衔接的约定。
响应式:一种允许以声明式的方法去适应变化的编程范例。
新的组件选项,作为composition()组合式) API的起点。
必须得有返回值,且该函数的返回值就可以在模板中进行使用;当然也可以返回一个渲染函数,该函数可以直接在同一作用域中声明响应式的状态
可以接受两个参数:
是一个响应式参数,所以不能使用ES6进行解构;如果需要解构props,可以使用setup函数中的toRefs来实现。
// 正常使用
export default{
props: {
title: string
},
setup(props){
console.log(props.title)
}
}
// 使用toRefs实现解构
import { toRefs } from 'vue'
export default{
props: {
title: string
},
setup(props){
const { title } = toRefs(props)
console.log(title.value)
}
}
// 返回一个渲染函数
import { h, ref, reactive} from 'vue'
export default{
setup(){
const readersNumber = ref(0)
const book = reactive({
title: 'Vue 3 Guide'
})
return () => h('div', [readersNumber.value, book.title ])
}
}
是一个普通的JavaScript参数,有三个属性:
attrs
:非响应式对象
attrs.x
引用属性slots
:非响应式对象
slots.x
引用属性emit
:触发事件(方法)
export default{
setup(props, context) {
console.log(context.attrs)
console.log(context.slots)
console.log(context.emit)
}
}
// 解构
export default{
setup(props, {attrs, slots, emit}) {
}
}
接收一个参数值并返回一个响应式且可改变的ref对象,该对象有一个指向内部的 单一value属性
const count = ref(0)
console.log(count.value)
当ref作为渲染上下文的属性返回,即在setup
函数中的return对象中到模板时会自动解套,不需要加上value属性,ref函数必须从vue引用才能使用
<template>
<div>{{ count }}div>
template>
<script>
import { ref } from 'vue'
export default{
setup(){
return {
count: ref(0)
}
}
}
script>
类似ref函数使用;将数据变成响应式数据,当数据发生变化,UI也会自动更新;不同于ref函数的是:ref函数作用于基本数据类型,而该函数作用于复杂数据类型,主要有对象和数组两种类型
结构一个getter函数,返回一个默认不可手动修改的ref对象
// 基本使用示例
const count = ref(1)
const plusOne = computed(() => count.value + 1)
// 报错
plusOne.value ++
// get和set使用示例
const count = ref(1)
const plusOne = computed({
get: () => count.value +1,
set: (val) => {
count.value = val-1
}
})
// 调用set方法
plusOne.value = 1
// 调用get方法
console.log(plusOne.value)
可以响应式追踪其依赖,并在其依赖变更时重新运行该函数。
该方法不需要指定要监听那个属性,其会自动收集回调函数中引用到的响应式属性,并且当组件初始化的时候,会执行一次一次用以收集属性。
停止监听两种方式
import { watchEffect, ref } from 'vue'
export default {
setup(){
const count = ref(0)
// 当count发生变化时,则立即输出
watchEffect(() => console.log(count.value))
setTimeout(() =>{
count.value ++
}, 1000)
return {
count
}
}
}
// 显式调用停止
const stopWE = watchEffect(...)
stopWE.stop();
可以为一个reactive对象的属性创建一个ref,可以被传递并且保持响应性。
const state = reactvie({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
将一个响应式对象转换成普通对象,该普通对象的每个属性都是一个ref,和响应式对象的属性一一对应
const state = reactvie({
foo: 1,
bar: 2
})
// foo和bar都是一个ref
const stateAsRefs = toRefs(state)
如果父子结构嵌套比较深,那么传递数据很繁琐,可以使用Provide和Inject进行数据传递。
该特性有两个部分:
在父组件setup函数中使用该方法,从Vue中导入,然后在调用Provide方法时定义每个属性,该方法有两个参数:
类型)provide('studentName', '刘同学')
在子组件setup函数中使用该方法,从Vue中导入,然后在调用Inject方法时定义每个属性,该方法有两个参数:
const studentName = inject('studentName', 'zs')
使用示例
父组件
<template>
<myInject />
template>
<script>
import { reactive, toRefs, provide } from 'vue'
import myInject from './Inject.vue'
export default{
components: {
myInject
},
setup() {
const state = reactive({
msg: 'Hello Vue World'
})
provide('studentName', 'ls')
provide('grode', {
Vue: 95,
jQuery: 97
})
return {
...toRefs(state)
}
}
}
script>
子组件
<<template>
学生成绩:{{ studentName }}<br>
vue成绩: {{ grode.Vue }}<br>
jQuery成绩: {{ grode.jQuery }}<br>
template>
<script>
import { reactive, toRefs, inject } from 'vue'
export default{
setup() {
const state = reactive({
count: 0
})
const studentName = inject('studentName', 'zs')
const grode = inject('grode')
return {
...toRefs(state)
studentName,
grode
}
}
}
script>
可以在provide值的时候使用ref或者reactive,可以保持其数据的响应性,如果子组件的数据不需要根据provide传递数据,建议可以使用readonly
方法保护数据
父组件
<<template>
<input type="text" v-model="studentName" /><br>
<children>children>
template>
<script>
import { reactive, toRefs, provide } from 'vue'
import children from './child1.vue'
export default{
components:{
children
},
setup() {
const studentName = ref('zs')
const grode = reactive({
Vue: 90,
jQuery: 98
})
const updateLoation = () => {
studentName.value = "ls"
grode.Vue = 99
}
provide("studentName", readonly(studentName))
provide("grode", readonly(grode))
provide("updateLoation", updateLoation)
return {
studentName
}
}
}
script>
子组件
<<template>
学生成绩:{{ studentName }}<br>
vue成绩: {{ grode.Vue }}<br>
jQuery成绩: {{ grode.jQuery }}<br>
<button @click="updateLoation">调用父组件的方法button>
template>
<script>
import { reactive, toRefs, inject } from 'vue'
export default{
setup() {
const studentName = inject('studentName', 'zs')
const grode = inject('grode')
const updateLoation = inject("updateLoation")
return {
studentName,
grode,
updateLoation
}
}
}
script>