uniapp开发:uniapp快速体验vue3.2之setup语法糖,怎么使用怎么爽 您所在的位置:网站首页 uniappp uniapp开发:uniapp快速体验vue3.2之setup语法糖,怎么使用怎么爽

uniapp开发:uniapp快速体验vue3.2之setup语法糖,怎么使用怎么爽

2022-06-13 04:34| 来源: 网络整理| 查看: 265

目录 概要拉开序幕的setup语法糖生命周期钩子ref函数与reactive函数对比computed计算属性监视(watch、watchEffect)组件传值provide/injectstyle样式使用v-bind绑定动态值获取路由信息全局API的转移Composition API 的优势关注我,不迷路vue3.x相关会在将来持续更新… 概要

随着vue3.0的发布,不久后vue3.2紧接着发布了,现在uniapp也支持了vue3.2的编译。vue3.x的优点我在这里就不多说了,了解更多到uniapp官方vue3的教程。

从学习前端开始,学习的主要框架就是vue,一直以来也是vue的忠实粉丝。现在3.x的发布,让我感觉到它用在移动端上面是目前最好的选择,毕竟不需要考虑ie兼容。uniapp本身初衷就是为移动端而生,所以vue3.x用在uniapp上面,简直就是完美至极。

目前vue3.2在uniapp中暂时只支持h5,小程序端目前只支持到vue3.0,这只是时间的问题,uniapp的小程序肯定会支持vue3.2的,那么我们可以先拿h5来预热吧!uniapp中的vue3.2的用法在_vue-cli脚手架_项目中是完全一样,放心学习。

vue3.2改进了 setup语法糖,怎么使用怎么爽! vue3.2的一些特性在vue3.0的基础上做出了改动,这篇文章直接总结vue3.2的特性,接下来就让我们快速体验vue3.2。

下面讲解的内容不局限于vue3.2做出的改动,部分写法已在vue3.0中改动。

拉开序幕的setup语法糖

从vue3.2开始setup直接写在script标签上面,意味着所有的js代码直接在script中间完成。setup语法糖在vue的将来绝对是一种趋势,而且这种趋势已经到来。

是一种编译时语法糖,可在 SFC 内使用Composition API 时极大地提升工作效率。在script中声明的 js变量,template模板中可以直接读取使用,后面会有大量相关案例展示。

生命周期

虽然3.x写法上与2.x的script里面的代码相差很大,但是生命周期还是必不可少,毕竟在开发的过程中还是有需求不同阶段进行处理逻辑。

特性:在2.x的生命周期钩子前面加上“on”来访问组件的生命周期钩子。 了解更多vue3.x生命周期钩子

import { onBeforeMount, onMounted } from 'vue'; onBeforeMount(() => { console.log('onBeforeMount生命周期') }) onMounted(() => { console.log('onMounted生命周期') })

vue2.x与vue3.x生命周期的区别:

选项式 API

Hook inside setup

beforeCreate

Not needed*

created

Not needed*

beforeMount

onBeforeMount

mounted

onMounted

beforeUpdate

onBeforeUpdate

updated

onUpdated

beforeUnmount

onBeforeUnmount

unmounted

onUnmounted

errorCaptured

onErrorCaptured

renderTracked

onRenderTracked

renderTriggered

onRenderTriggered

activated

onActivated

deactivated

onDeactivated

Tips: 因为setup是围绕beforeCreate和 created生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。

ref函数与reactive函数对比

从定义数据类型角度区分:

ref用来定义:基本数据类型 。reactive用来定义:对象(或数组)类型数据 。备注:ref也可以用来定义对象(或数组)类型数据,其内部会自动通过reactive转换代理对象。

从原理角度区分:

ref通过Object.defineProperty()的get与set来完成响应式(数据劫持)。reactive通过使用Proxy 来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据。

从使用角度区分:

ref定义的数据:在js中操作数据需要.value,template模板中读取数据不需要.value:

const v = ref(999); consle.log(v.value);// 这样获取的值是 999

reactive定义的数据:操作数据与读取数据:均不需要.value。

const data = reactive({ a:1, b:2 }); consle.log(data);// 这样获取的值是{a:1,b:2}

computed计算属性

_computed_与vue2.x的配置项一致

{{fullname1}} {{fullname2}} import { reactive,computed } from 'vue' let person = reactive({ firstName:'尤', lastName:'大' }); // 计算属性-简写 const fullname1 = computed(()=>{ return `${person.firstName}-${person.lastName}` }) // 计算属性-完整 const fullname2 = computed({ get(){ return `${person.firstName}-${person.lastName}` }, set(value){ const nameArr = value.split('-') person.firstName = nameArr[0] person.lastName = nameArr[1] } }) 监视(watch、watchEffect)

1. watch函数

watch的配置项与vue2.x中watch一致。

注意的坑:在uniapp中,newValue和oldValue不要写成new和old,否则会报错。

情况一: 监视单个ref定义的响应式数据:

import { ref } from 'vue' const v1 = ref(1); const v2 = ref(2); watch(v1, (newValue, oldValue) => { console.log('v1====', newValue, oldValue) },{immediate:true}) watch(v2, (newValue, oldValue) => { console.log('v2====', newValue, oldValue); })

情况二: 监视多个ref定义的响应式数据:

import { ref } from 'vue' const v1 = ref(1); const v2 = ref(2); watch([v1,v2], (newValue, oldValue) => { console.log('v1====', newValue, oldValue); })

情况三: 监视多个reactive定义的响应式数据:

注意: watch监视的是reactive定义的响应式数据,则强制开启了深度监视,也就是说设置{deep:false}无效。

情况四: 监视reactive定义的响应式数据中的某个属性:

import { ref, reactive } from 'vue' let data = reactive({ a: 1, b: 2, c:{ sss:'yes' } }); watch(() => data.a, (newValue, oldValue) => { console.log('监视reactive定义的响应式数据中的某个属性a:', newValue, oldValue) }) watch(() => data.c.sss, (newValue, oldValue) => { console.log('监视reactive定义的响应式数据中的某个属性sss:', newValue, oldValue) })

情况五: 监视reactive定义的响应式数据中的多个属性:

import { ref, reactive } from 'vue' let data = reactive({ a: 1, b: 2, c:{ sss:'yes' } }); watch([() => data.a,() => data.c.sss], (newValue, oldValue) => { console.log('监视reactive定义的响应式数据中的多个属性a和sss:', newValue, oldValue) })

情况六: 监视reactive定义的数组:

import { reactive } from 'vue' const list = reactive([1,2,3]) watch(()=>[...list], (newValue, oldValue) => { console.log('监视数组:', newValue, oldValue) })

情况七: 监视vuex中的值:

vuex在vue3中的使用异同可以到另一篇博客了解更多详情: vue3.2开发:vuex在vue3与vue2中异同之快速体验

2. watchEffect函数

watchEffect与computed相似:

但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

watch的套路是:既要指明监视的属性,也要指明监视的回调。

watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

组件传值

1. props/emit

vue3.2子组件中使用defineProps接受父组件的值,使用defineEmits向父组件传递方法。

父组件father.vue

父亲的值:{{v}} import { ref } from 'vue' import Son from './components/son.vue' const v = ref(0); function change(){ v.value++; }

子组件son.vue

son中接受父亲的值:{{v}} 子组件的按钮 import { defineProps, defineEmits } from 'vue' defineProps({ v:Number }) const emits = defineEmits(['change']) function change(){ emits('change') } provide/inject provide/inject算是props的加强版,父组件用provide 提供数据,所有子组件可以通过inject获取这些数据,父组件不需要知道哪些子组件使用它provide的数据。

基本套路:

// 父组件中 provide('值',值); // 子组件中 const v = inject('值');

注意:

provide也可以传递普通数据,但是传递ref或reactive定义的数据才具有响应性。不同于props,provide是双向数据流,即可以在子组件里修改父组件传递过来的值。如果不想让子组件修改父组件传递的值,使用readonly,下面有示例。

父组件father.vue

父亲的值:{{v}} import { ref, defineComponent } from 'vue' import Son from './components/s.vue' const v = ref(0); function change(){ v.value++; }

子组件son.vue

从父组件读取的值:{{count}} import { inject } from 'vue' import grandChild from './grandChild.vue' const count = inject('count')

孙组件grandChild.vue

孙组件接收爷爷的值:{{count}} import { inject } from 'vue' const count = inject('count') setTimeout(()=>{ count.value = 10;// 3秒之后,发现值都变了,证明了上面注意中的第二点 },3000)

readonly

import { readonly } from 'vue'; const count = ref(1); provide('count',readonly(count)); style样式使用v-bind绑定动态值

以前在做项目的时候,有场景就想着style中可以绑定js中的动态值,没想到vue3.2中就支持了,爽歪歪!

v-bind 在 SFC 标签中启用组件状态驱动的动态 CSS 值。

带颜色的文字 获取路由信息

注意: uniappp中获取路由信息的方式不能用useRoute和useRouter,官方给出的方案是用getCurrentPages,如下:

var pages = getCurrentPages(); var page = pages[pages.length - 1]; console.log(page);

vue-cli脚手架搭建的项目可以使用useRoute和useRouter,如下:

import { useRoute, useRouter } from 'vue-router' const r1 = useRoute(); const r2 = useRouter(); console.log(r1,r2); 全局API的转移

1. vue2.x中部分全局API和配置

比如:注册全局组件、注册全局指令等。

//注册全局组件 Vue.component('MyButton', { data: () => ({ count: 0 }), template: 'Clicked {{ count }} times.' }) //注册全局指令 Vue.directive('focus', { inserted: el => el.focus() }

2. vue3.x中对这些API做出了调整

将全局的API,即:Vue.xxx调整到应用实例(app)上。

2.x 全局 API(Vue)

3.x 实例 API (app)

Vue.config.xxxx

app.config.xxxx

Vue.config.productionTip

移除

Vue.component

app.component

Vue.directive

app.directive

Vue.mixin

app.mixin

Vue.use

app.use

Vue.prototype

app.config.globalProperties

Composition API 的优势

1. vue2.x中的Options API 存在的问题

使用传统_Options API_中,新增或者修改一个需求,就需要分别在data,methods,computed里修改。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EhzjwQJ1-1645546301375)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f84e4e2c02424d9a99862ade0a2e4114~tplv-k3u1fbpfcp-watermark.image “Options API 存在的问题演示1”)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NR9HLClu-1645546301376)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e5ac7e20d1784887a826f6360768a368~tplv-k3u1fbpfcp-watermark.image “Options API 存在的问题演示2”)]

1. vue2.x中的Composition API的优势

使用_Composition API_中,我们可以更加优雅的组织我们的代码,函数。让相关功能的代码更加有序的组织在一起。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1L1L0qVt-1645546301377)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bc0be8211fc54b6c941c036791ba4efe~tplv-k3u1fbpfcp-watermark.image “Composition API的优势演示1”)]

关注我,不迷路 小伙伴,用你可爱的小手,点个赞,关注我了解更多知识!!!

如果任何疑问的可以在评论区留言或者私聊。

也可以扫下面二维码加我wx,备注‘地区-名字-技术类型’,我会拉进我的微信技术分享群。注意:必须备注清楚哈。

也可以加QQ群交流:568984539,加群备注‘地区-名字-技术类型’。

更多前端、uniapp、nodejs等相关知识可关注我个人博客:https://blog.csdn.net/qq_42961150spm=1011.2124.3001.5343

3



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有