做网站要求的资料,来广营做网站,清远医院网站建设费用,北京网站优化解决方案Composition API
认识Composition API 前几篇文章中主要用Options API进行编写代码#xff0c;但是有一些弊端 Options API弊端 在 Options API中#xff0c;有data、watch、computed、methods以及生命周期函数各种各样的选项而一个变量#xff0c;为了实现某个功能#x…Composition API
认识Composition API 前几篇文章中主要用Options API进行编写代码但是有一些弊端 Options API弊端 在 Options API中有data、watch、computed、methods以及生命周期函数各种各样的选项而一个变量为了实现某个功能会分散在各个选项中不利于代码的维护 此时 Composition API就出现了 使用 setup函数可以将大部分选项代替data、watch、computed、methods以及生命周期函数
ssetup函数的参数 setup函数主要有两个参数 propscontext props是一个对象包含着父组件传递过来的属性 context主要包含三个属性 attrs所有的非prop的attribute**slots**父组件传递过来的插槽在以渲染函数返回时会有作用**emit**当我们组件内部需要发出事件时会用到emit在setup函数中不能访问this 简单实现
templatedivspan{{ count }}/spanbutton clickadd1/buttonbutton clickdeAdd-1/button/div
/templatescript
//引入ref函数
import { ref } from vue;
export default {setup() {//定义变量,此时count并不是响应式数据,需要用ref进行包裹let count ref(0);//定义函数//要对count进行修改需要通过.value的方式进行修改let add () count.value;let deAdd () count.value--;//将变量以及函数返回出去template中才可以使用return {count,add,deAdd,};},
};
/script同时我们可以将内部的逻辑代码封装单独的一个文件而后进行引入
script
//引入函数
import counter from ./utils/counter;export default {setup() {let { count, add, deAdd } counter();return {count,add,deAdd,};},
};
/script
-------还可以做以下优化
script
//引入函数
import counter from ./utils/counter;export default {setup() {return {...counter()};},
};
/script
setup定义数据
定义普通函数
setup(){//可以直接使用但不是响应式let message helloreturn{message}
}定义响应式数据reactive 定义复杂数据对象/数组等不能传入普通类型的比如字符串等在 option api中data中定义的数据实际上就是交给了reactive函数
import {reactive} from vue
setup(){//此时就是响应式了let obj reactive({a:100,b:200})//对obj进行修改obj.a 300return{obj}
}定义响应式数据ref:返回的是ref对象需要使用.value进行获取值 定义简单类型的响应式数据也可以定义复杂类型的数据但是在template中会自动解包即自动获取 变量.value的值直接使用变量即可
template{{count}}
/templateimport {ref} from vue
setup(){//定义简单数据,也可以定义复杂数据let count ref(0)//修改变量count.value 100return {count }
}ref定义数据和reactive定义数据的开发
在实际开发中使用ref的频次比较多 ref可以定义复杂数据 reactive应用场景 应用于本地数据const obj reactive({username:123})不是从数据库中得来的多个数据之间是有关系/联系的 const user reactive({username:admin,password:123456}) ref应用场景其余的场景基本都用ref 定义本地的简单数据定义从网络获取的数据
const music ref([])
onMounted((){const serverMusic [野狼,小苹果]music.value serverMusic
})单向数据流的规范和做法
父组件传递给子组件一个对象/数组此时子组件能否对其进行修改在代码层面子组件是可以进行修改的 —但是不符合规范因为父组件引用的子组件很多的情况下若子组件擅自修改了对象中的数据那么就不清楚到底是谁对数据进行了修改正确的做法 父组件将数据传递给了子组件子组件抛出事件以及要修改的值父组件使用 子组件事件来将数据进行修改
readonly函数 创建出来的数据也是响应式数据但是不能对数据进行修改但是我们可以对元数据进行修改 其返回的也是一个Proxy对象只是setter方法受到了限制
setup(){let obj ref({a:100})//此时readonlyObj不能进行修改可以将其传给子组件let readonlyObj readonly(obj)//若我们向修改其内容可以对obj进行修改}Reactive判断的API isProxy 检查对象 是否由reactive或者readonly创建的Proxy isReactive 检查对象是否由 reactive创建的响应式代理 isReadonly 检查对象 是否由readonly创建的只读代理 toRaw 返回proxy代理对象的原始数据 shallowReactive 创建一个响应式代理但是只响应浅层次的数据 shallowReadonly 创建一个响应式代理但是不执行嵌套对象的深度只读转换
toRef和toRefs
现在有如下代码 我们在使用user的时候想直接通过name age height的方式直接展示不是通过 user.name user.age user.height的方式展示
templatedivdiv{{ user.name }}-{{ user.age }}-{{ user.height }}/divbutton click/button/div
/templatescript
//引入函数
import { reactive, ref, toRef, toRefs } from vue;export default {setup() {let user reactive({name: zhangcheng,age: 18,height: 1.88,});return {user,};},
};
/scriptstyle scoped/style为了实现上述要求可以将user进行解构 之后将解构的数据返回出去 const {name,age,height} user但是解构出来的变量就是普通的变量不再是响应式数据了 因此我们可以通过 toRef和toRefs方法进行操作
let user reactive({name: zhangcheng,age: 18,height: 1.88,
});//toRefs对多个值进行ref转化
const { name, age } toRefs(user);
// toRef对某个属性进行ref转化
const height toRef(user, height);这种做法实际上是将 name.value与user.name做了某种联系使其中一方修改另外一方也会进行修改
ref定义数据其他的API
unref
unref实际上是 语法糖 其内部会先判断传进来的参数是否是ref对象是的化就返回 ref.value不是的化就直接返回值本身
const a ref(2)
const b unref(a)//内部实际上是 b isRef(a)?a.value:aisRef
判断值 是否是一个ref对象
setup函数中不能使用this
在官方文档中有对setup函数中不能使用this进行过提示大概意思如下 this并没有指向当前组件的实例在 setup被调用之前datacomputed、methods等都没有被解析
computed函数使用 当某些数据需要进行某些逻辑转化再显示就会用到计算属性 computed 在里面传入一个回调函数默认调用的是其中的getter方法 此时 computedStr变量就是计算属性且这个计算属性是只读的
import {computed} from vue
setup(){const computedStr computed((){return ab}) return {computedStr}
}如果想要调用computed中的getter方法需要在computed函数中传入对象 computed函数返回值实际上是ref对象因此想要修改的话需要使用 .value进行修改
import {computed} from vue
//可以调用setter方法
const computedObjStr computed({set: function (newValue) {const temp newValue.split( );str.first temp[0];str.last temp[1];},get: function () {return str.first str.last;},
});
//若想修改computedObjStr的话需要computedObjStr.valueli siref引入元素 此ref不是定义数据的ref 在vue中我们可以通过ref this.$refs.ref进行获取元素那么在setup函数中怎么使用 直接在setup函数内部打印 ref引用的元素是不会获取到的因此需要在onMounted生命周期中查看
templatedivdiv reftable123/divdiv refdivEl456/div/div
/templatescript
//引入函数
import { onMounted, ref, reactive, computed } from vue;export default {setup() {const refTable ref();const divEl ref();onMounted(() {//需要使用.value获取值//对于组件使用也是如此console.log(refTable.value);console.log(divEl.value);});return {//两种返回方式一种是对象的增强写法table: refTable,divEl,};},
};
/scriptstyle scoped/style生命周期钩子 在setup中使用生命周期的方式 onX 需要进行导入 生命周期的函数调用之后再 其内部传入函数才是生命周期的函数在 vue的官网中有这样的提示setup就是围绕 beforeCreate和created进行的因此之前在该生命周期中做的事可以直接写在setup中
选项式APIHook inside setupbeforeCreate不需要created不需要beforeMountonBeforeMountmountedonMountedbeforeUpdateonBeforeUpdateupdatedonUpdatedbeforeUnmountonBeforeUnmountunmountedonUnmountedactivatedonActivateddeactivatedonDeactivated
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted,onActivated,onDeactivated,
} from vue;
setup() {onMounted(() {console.log(onMounted 执行);});return {};
},provide和inject函数
在 option API中我们用到了provide和inject用于组件之间传递数据那么 在 composition API中要怎么使用provide(key,value)key是传递参数的代表value 是具体数据inject(key,default)key是父组件传递参数的代表default是父组件没有传递数据的时候的默认值
import { provide, inject } from vue;
//父组件
const obj ref({ a: 100 })
provide(objStr, obj)//子组件
inject(objStr,{a:0})侦听数据的变化 在option API中使用的是watch中进行监听数据的变化那么在composition中怎么进行监听 watch
首先导入 watch函数基本使用 可以监听多个数据newValue, oldValue返回的都是proxy对象
import { reactive, ref, watch } from vue;export default {setup() {/*** 参数* 1.数据源* 针对于ref包裹的需要监听.value* 使用数组可以监听多个数据* 2.执行的逻辑* 3.配置项配置deep以及immediate* 默认就是深度监听*///定义数据let obj ref({ a: 100, b: { c: 200 } });let objRea reactive({ username: zhangcheng });//对数据进行监听watch([objRea, obj.value], (newValue, oldValue) {console.log(newValue, oldValue);},{immediate: true,});return { obj, objRea };},
};
};若 newValue, oldValue返回的是普通对象 数据源需要传递一个函数且配置项中需要进行深度监听的配置默认不启用深度监听 /*** 参数* 1.数据源* 针对于ref包裹的需要监听.value* 使用数组可以监听多个数据* 2.执行的逻辑* 3.配置项配置deep以及immediate* 默认就是深度监听*/let obj ref({ a: 100, b: { c: 200 } });let objRea reactive({ username: zhangcheng, b: { c: 200 } });watch(() ({ ...obj.value, ...objRea }),(newValue, oldValue) {console.log(newValue, oldValue);},{deep: true,immediate: true,});watchEffect 相较于watch而言watchEffect可以自动监听依赖变量的变化 传入warchEffect中的回调函数在页面初次加载的时候会先执行一次而后在依赖的数据发生变化的时候也会执行回调函数同时达到某一个条件的时候可以停止数据的监听
const stopWatch watchEffect(() {//当obj.value发生变化的时候会自动调用这个回调函数console.log(obj.value);//执行watchEffect的返回值就可以停止对数据的监听if (obj.value 10) {stopWatch();}
});script setup语法 本质就是setup函数的语法糖 就是在 script的标签中加入setup的attribute 这种写法有更好的运行效率因为内部会将script与template模板放在同一个作用域中代码会更加的简洁有更好的提示
script setup//实际上就是在setup中在编写代码//不用写return
/script顶层的绑定会直接暴露给模板
在 script setup标签中直接写的内容在template中可以直接使用 若是在函数中定义一个变量则不属于顶层
template{{ message }}
/templatescript setup
//引入函数
import { ref } from vue;let message ref(123);
/scriptstyle scoped/style导入组件直接使用
导入的组件无需注册 直接在template中使用即可
templatehome-vue/home-vue
/templatescript setup
//导入组件直接使用
import HomeVue from ./components/HomeVue;/scriptstyle scoped/style子组件通过 defineProps()接受父组件传进来的参数defineEmits()发送事件
templatebutton clickmessageClick{{ message }}/button
/templatescript setup
//defineEmits和defineProps都是内部绑定的因此不用注册//接受参数
defineProps({message: {type: String,default: 默认信息,},
});//定义发射的事件
const messageEmit defineEmits([message-click]);
function messageClick() {messageEmit(message-click, 传递参数);
}
/scriptstyle scoped/styledefineExpose将子组件中的数据暴露 默认都是在 script setup/script标签中写的代码 子组件 定义变量函数等之后暴露出去
import { ref } from vue;function expsoeFun() {console.log(暴露出去了);
}
const message ref(我是变量);
//子组件中有一个函数想被父组件直接调用需要用到 defineExpose将函数暴露或者将变量暴露
defineExpose({ expsoeFun, message });父组件 首先通过ref获取子组件之后调用其暴露的内容即可
import { onMounted, ref } from vue;
import HomeVue from ./components/HomeVue.vue;//绑定实例
const homeVue ref();
onMounted(() {//调用实例中的方法homeVue.value.exposeFun();//获取实例中的变量console.log(homeVue.value.message);
});