3.计算属性我们一般使用计算属性来描述依赖响应式状态的复杂逻辑。说白了就是这个计算属性的值依赖于其他响应式属性的值,依赖的属性发生变化,那么这个计算属性的值就会进行重新计算。<script setup> import { ref
我们一般使用计算属性来描述依赖响应式状态的复杂逻辑。说白了就是这个计算属性的值依赖于其他响应式属性的值,依赖的属性发生变化,那么这个计算属性的值就会进行重新计算。
<script setup>
import { ref, computed } from 'Vue'
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
// getter
get() {
return firstName.value + ' ' + lastName.value
},
// setter
set(newValue) {
// 注意:我们这里使用的是解构赋值语法
[firstName.value, lastName.value] = newValue.split(' ')
}
})
</script>
当调用fullName.value = 'John Doe'
时,setter
会被调用,而firstName
和 lastName
会被更新,在vue3.2
中我们可以直接在<template>
标签中使用它,不在需要return返回。
- 不要在计算函数中做异步请求或者更改 DOM!
- 一个计算属性仅会在其响应式依赖更新时才重新计算,如果他依赖的是个非响应式的依赖,及时其值发生变化,计算属性也不会更新。
- 相比于方法而言,计算属性值会基于其响应式依赖被缓存,一个计算属性仅会在其响应式依赖更新时才重新计算
在组合式api中,我们可以使用watch
函数在每次响应式状态发生变化时触发回调函数,watch
的第一个参数可以是不同形式的“数据源”:它可以是一个 ref
(包括计算属性)、一个响应式对象、一个 getter
函数、或多个数据源组成的数组:watch()
是懒执行的:仅当数据源变化时,才会执行回调,例如:
<script setup>
import { ref,watch } from 'vue';
const props = defineProps({
title: String,
itemList: {
type: Array,
default: () => [{
text: 'title',
value: 0
}]
}
})
watch(() => props.itemList.length,(newValue,oldValue) => {
console.log('newValue===',newValue);
console.log('oldValue===',oldValue);
})
</script>
这里监听
props.itemList.length
,当传入的itemList
数量发生变化时,后面的回调方法会被调用。当然wacth()
还有第三个可选参数:否开启深监听(deep)
, 如果这里这样写:
<script setup> import { ref,watch } from 'vue'; ... watch(() => props.itemList,(newValue,oldValue) => { console.log('newValue===',newValue); console.log('oldValue===',oldValue); }) </script>
当传入的
itemList
数量发生改变时,回调函数不会触发,正确的写法是加上其第三个参数deep:true
<script setup>
import { ref,watch } from 'vue';
...
watch(() => props.itemList,(newValue,oldValue) => {
console.log('newValue===',newValue);
console.log('oldValue===',oldValue);
},{deep:true})
</script>
watch
也可以同时监听多个属性:
<script setup>
import { ref,watch } from 'vue';
const props = defineProps({
title: String,
itemList: {
type: Array,
default: () => [{
text: 'title',
value: 0
}]
}
})
// 同时监听多个属性
watch(() => [props.itemList,props.title],(newValue,oldValue) => {
console.log('newValue===',newValue);
console.log('oldValue===',oldValue);
},{deep:true})
</script>
watchEffect()
与watch()
的懒执行不同的是,watchEffect()
会立即执行一遍回调函数,如果这时函数产生了副作用,Vue
会自动追踪副作用的依赖关系,自动分析出响应源。上面的例子可以重写为:
<script setup>
...
watchEffect(() => {
console.log('itemList===',props.itemList.length);
console.log('title===',props.title);
})
</script>
这个例子中,回调会立即执行。在执行期间,它会自动追踪props.itemList.length
作为依赖(和计算属性的行为类似)。每当传入的itemList.length
变化时,回调会再次执行。
如果要清除watchEffect()
的的监听,只需要显示的调用watchEffect()
的返回函数就可以了,例如:
<script setup>
...
const stopEffect = watchEffect(() => {
console.log('itemList===',props.itemList.length);
console.log('title===',props.title);
})
stopEffect()
</script>
watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。我们能更加精确地控制回调函数的触发时机。 watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。
vue3.0
中如果我们的子组件触发父组件的方法,我们的做法:
子组件
<script>
export default {
emits: ['inFocus', 'submit'],
setup(props, ctx) {
ctx.emit('submit',params)
}
}
// 或者将可以将emit解构使用
export default {
setup(props,{emit}) {
emit('submit',params)
}
}
</script>
父组件
<template>
<Children @submit="submitHandel"/>
</div>
</template>
<script>
export default {
name: 'TodoItem',
setup(props, { emit }) {
const submitHandel = () => {
console.log('子组件调用了父组件的submitHandel方法');
}
return {
submitHandel,
}
}
};
</script>
vue3.2
语法糖中,子组件要触发的事件需要显式地通过 defineEmits()
宏来声明
子组件
<script setup>
const emit = defineEmits(['inFocus', 'submit'])
function buttonClick(parmas) {
emit('submit', parmas)
}
</script>
父组件
<template>
<Children @submit="submitHandel"/>
</div>
</template>
<script setup>
const submitHandel = () => {
console.log('子组件调用了父组件的submitHandel方法');
}
};
</script>
vue3.0
中如果父组件触发子组件的方法或是属性,直接在return函数中返回就可以,数据都是默认隐式暴露给父组件的。
<script>
// 子组件
setup(props, { emit }) {
const isshow = ref(false)
// 父组件调用这个方法
const showSubComponent = () => {
isShow.value = !isShow.value
}
return {
// return 返回
showSubComponent,
}
}
</script>
父组件中通过ref
获取到子组件,并对子组件暴露的方法进行访问
父组件
<template>
<div class="todo-list">
<TodoItemVue :itemList="itemList" @clickItemHandel="clickItemHandel" ref="todoItemVueRef" />
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup(props, { emit }) {
//获取子组件ref
const todoItemVueRef = ref(null)
// 调用子组件的方法
const callItemFuncHandel = () => {
todoItemVueRef.value.showSubComponent()
}
return {
todoItemVueRef
}
}
};
</script>
vue3.2
语法中,父组件的调用方式相同,子组件通过defineExpose()
将方法或是属性暴露出去
子组件
<script setup>
const isShow = ref(false)
// 父组件调用这个方法
const showSubComponent = () => {
isShow.value = !isShow.value
}
// 通过defineExpose将方法暴露出去
defineExpose({
showSubComponent
})
</script>
父组件
<template>
<div class="todo-list">
<TodoItemVue :itemList="itemList" @clickItemHandel="clickItemHandel" ref="todoItemVueRef" />
</div>
</template>
<script setup>
import { ref } from 'vue';
//获取子组件ref
const todoItemVueRef = ref(null)
// 调用子组件的方法
const callItemFuncHandel = () => {
todoItemVueRef.value.showSubComponent()
}
</script>
在vue3.0
与vue3.2
中创建Vuex
没有区别,只不过在<template>
模板中使用Vuex的store
有细微差别。
import { createStore } from 'vuex';
import { ADD_ITEM_LIST, REDUCE_ITEM_LIST, CHANGE_ITEM_LIST_ASYNC } from './constants';
export default createStore({
state: {
itemList: [
{ text: 'Learn javascript', done: true },
{ text: 'Learn Vue', done: false },
{ text: 'Build something awesome', done: false },
],
},
getters: {
doneItemList: (state) => state.itemList.filter((todo) => todo.done),
},
mutations: {
// 使用ES2015风格的计算属性命名功能 来使用一个常量作为函数名
[ADD_ITEM_LIST](state, item) {
console.log('增加数据', item);
state.itemList.push(item);
},
[REDUCE_ITEM_LIST](state) {
console.log('减少数据');
state.itemList.pop();
},
},
actions: {
[CHANGE_ITEM_LIST_ASYNC]({ commit, state }, todoItem) {
/// 模拟网络请求
setTimeout(() => {
commit(ADD_ITEM_LIST, todoItem);
console.log('state===', state);
}, 1000);
},
},
modules: {
},
});
在vue3.0
中我们一般在return中对store.state
进行解构,然后可以直接在<template>
中使用state
中的值
<template>
<div class="todo-item">
<ol>
<li v-for="(item,index) in itemList" :key="index" class="todos" @click="clickItem(index)">
{{ item.text }}
</li>
</ol>
</div>
</template>
<script>
export default {
name: 'TodoItem',
setup(props, { emit }) {
return {
// 对store.state进行解构
...store.state,
clickItem,
count,
isShow,
showSubComponent,
}
}
};
</script>
vue3.2
中没有了return,需要我们显示的获取要使用的stare
的值
<template>
<div class="todo-item">
<ol>
<li v-for="(item,index) in itemList" :key="index" class="todos" @click="clickItem(index)">
{{ item.text }}
</li>
</ol>
</div>
</template>
<script setup>
import { useStore } from 'vuex';
const store = useStore()
// 获取后在<template>中使用
const itemList = store.state.itemList
</script>
<style>
中的 v-bind<style>
中的 v-bind
: 用于在 SFC <style>
标签中启用组件状态驱动的动态 CSS 值
<script setup>
import { ref, watchEffect } from 'vue';
const color = ref('black')
const callChangeColorHandel = () => {
if(color.value === 'black') {
color.value = 'red'
}else {
color.value = 'black'
}
}
</script>
<style lang="scss" scoped>
.todo-list {
color: v-bind(color);
}
</style>
触发callChangeColorHandel
函数,在<style>
中的v-bind
指令可以动态绑定的响应式状态。
整体来说,setup语法糖的引入简化了使用Composition API
时冗长的模板代码,也就是让代码更加简洁,可读性也更高。并且官方介绍vue3.2
在界面渲染的速度以及内存的使用量上都进行了优化,本文只是对setup语法糖的常用方式进行了总结,更多vue3.2
新特性可以去官方文档查看。
以上就是什么是语法糖?Vue3.2中怎么使用语法糖?的详细内容,更多请关注编程网其它相关文章!
--结束END--
本文标题: 什么是语法糖?Vue3.2中怎么使用语法糖?
本文链接: https://lsjlt.com/news/173612.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2023-05-25
2023-05-25
2023-05-25
2023-05-25
2023-05-25
2023-05-24
2023-05-24
2023-05-24
2023-05-24
2023-05-24
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0