共计 4193 个字符,预计需要花费 11 分钟才能阅读完成。
options-api
首先咱们来看看 option-api。
default export {data() {
return {state:0}
},
methods:{myFun() {console.log(this.state)
}
}
}
下面代码的形式就是 option-api, 也是 vue2.x 中最罕用的形式。
composition-api
在 vue3.x 中,能够应用上面的 composition-api 形式。
default export {setup(){const state = ref(0)
function myFunOne() {console.log(state.value)
}
function myFunTwo() {console.log(state.value + 1)
}
return {
state,
myFunOne
}
}
}
解决痛点
看上面的图片(起源:https://composition-api.vuejs.org/#code-organization),雷同业务的代码色彩雷同,能够看见 Options API 的雷同业务代码扩散在各处,这样前期保护起来就会十分麻烦,而 Composition-Api 解决了这个痛点。
知识点梳理
对于 composition-api 所蕴含的函数有以上这么多,上面依据相干例子一个个来学习。
setup
setup
性能是新的组件选项。它是组件外部应用 Composition-API 的入口。
可选参数
它有两个可选参数 props 和 context。
这两个参数能够解构应用。
- props 和 vue2.x props 是一样的,外面的属性是 父组件传给自组子或 vue-router 传给 页面的参数。
- context 具备与 vue2.x 中 this.$attrs,this.$slots,this.$emit,this.$parent,this.$root 对应的属性。
示例代码
props: {msg: String},
// 须要在 emits 中申明 不然会报错 上面会有解释
emits: {
sayhi: payload => {
// validate payload by returning a boolean
return payload
}
},
// 1. 个别应用
// setup(props, context) {// console.log('====>', props)
// context.emit('sayhi', 'hi')
//}
// 2. 可解构应用
setup({msg}, {emit}) {console.log('====>', msg)
emit('sayhi', 'hi')
}
留神点⚠️
在 setup 中应用 emit , 须要在 emits 中申明它,否则会报以下谬误。
Extraneous non-emits event listeners (此处是函数名) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the “emits” option.
ref
<template>
<div>
<div>{{state}}</div>
<button @click="addOne"> 新增 1 </button>
</div>
</template>
<script lang="ts">
import {defineComponent, ref, onMounted} from "vue"
export default defineComponent({setup(){
// 通过 ref 初始化一个响应式的对象
const state = ref(0)
// 在生命周期 onMounted 中打印 state
onMounted(() => {console.log(state)
})
function addOne() {state.value += 1}
return {
state,
addOne
}
}
})
</script>
咱们再来看看这段代码。
在 dom 挂载结束的生命周期 onMounted
中打印 state
, 发现它是一个对象。
因为 state
是通过 ref 传参,而后返回的一个对象(ref 是一个函数,它承受一个参数,返回的一个响应式对象)。咱们初始化的这个 0 作为参数包裹到这个对象中去,在将来能够检测到扭转并作出对应的相应。
在 addOne
函数中,若要扭转 这个 state
响应式对象的值,则须要通过 赋值 state.value
来实现。
在 template 模板中,vue 曾经帮咱们主动获取了其 value 属性,所以咱们只须要传 {{state}}
即可。
reactive
reactive 和 ref 十分类似,也是一个函数,然而其接管一个对象。咱们革新下面学习 ref 的 例子来理解 reactive。
<template>
<div>
<div>{{state}}</div>
<button @click="addOne"> 新增 1 </button>
</div>
</template>
<script lang="ts">
import {defineComponent, onMounted, reactive, toRefs} from "vue"
export default defineComponent({setup(){
// 通过 reactive 初始化数据
const data = reactive({state: 0,})
// const state = ref(0)
// 在生命周期 onMounted 中打印 state
onMounted(() => {console.log('无 toRefs', data)
console.log('通过 toRefs 解决', toRefs(data))
})
function addOne() {data.state += 1}
return {
// ...data, // 这样导出会使数据失去响应式
...toRefs(data), // 通过 toRefs 使得 data 中数据取得响应式
addOne
}
}
})
</script>
与 ref 相比:
- reactive 能够将 零散的 变量汇集在一个对象中。
- reactive 中的变量 的取值和赋值不须要 取其 value 属性。
留神点:
应用 reactive
时要记得应用 toRefs
保障 reactive
对象属性放弃响应性。
watch 和 watchEffect
代码示例
// 通过 reactive 初始化数据
const data = reactive({
state: 0,
num: 2,
arr: [1, 2, 3]
})
// 简略监听
watch(data, () => {console.log(data.state)
})
// 上面间接监听 data.state 会报错。watch 监听的指标只能是 getter/effect 函数、ref、reactive 对象或数组。// watch(data.state, (newValue, oldValue) => {// console.log('newValue', newValue)
// console.log('oldValue', oldValue)
// })
// 监听 新的值和旧值
watch(() => data.state, (newValue, oldValue) => {console.log('newValue', newValue)
console.log('oldValue', oldValue)
})
// watch 监听多个属性,返回的也是多个值的数组
watch([() => data.num, () => data.state], (newValue, oldValue) => {console.log('old', oldValue)
console.log('new', newValue)
})
// watchEffect 不须要指定监听的属性
watchEffect(()=>{console.log('watchEffect ===>', data.state);
});
watch
A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.
watch 监听源只能是 getter/effect 函数、ref、reactive 对象或数组。
具体用法如上述代码所见
- 简略监听值的扭转。
- 能够获取到新值与旧值。
watch
只能监听指定的属性而做出变更,vue3.x 能够同时监听多个属性。
watchEffect
watchEffect 和 watch 相似,能够监听属性的变动。具体应用形式如上述代码。
不同点
watchEffect
不须要指定监听的属性,它会主动的收集依赖,只有咱们回调中援用到了 响应式的属性,那么当这些属性变更的时候,这个回调都会执行,而watch
只能监听指定的一个或多个属性而做出变更。-
watch
能够获取到新值与旧值,而watchEffect
是拿不到的oldValue
watchEffect
在组件初始化的时候就会默认执行一次,而 watch 不须要。
computed
计算属性和 vue2.x 中一样,代码示例如下。
<template>
<div>
<div>{{state}}</div>
<div>{{double}}</div>
<button @click="addOne"> 新增 1 </button>
</div>
</template>
<script lang="ts">
import {computed, defineComponent, reactive, toRefs} from "vue"
export default defineComponent({setup(){
// 通过 reactive 初始化数据
const data = reactive({state: 0,})
// 通过计算属性取得的新的值
const double = computed(() => data.state * 2)
function addOne() {data.state += 1}
return {...toRefs(data), // 通过 toRefs 使得 data 中数据取得响应式
addOne,
double
}
}
})
</script>
参考文献
composition-api 官网文档