百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

uniapp入门到进阶(必备知识扩展-1) - vue3你不知道的那些事

ztj100 2024-11-26 11:15 20 浏览 0 评论

一、组合式API

1、setup函数:组件中所有数据、方法、钩子函数等存放的容器,返回值有两个:

在beforeCreate之前调用,没有this

setup函数有两参数 setup(props,context)

props外部传入、内部声明接受的属性,值为对象;

context 包含

1、 attrs外部传入,props未声明,相当于this.$attrs

2、slots收到的插槽相当于this.$slots

3、emit 函数,相当于this.$emit

返回对象:则对象内的属性、方法可在模板直接使用;

若返回渲染模板函数,我们可以自定义渲染的内容

例如:

<script lang="ts">
    import { h } from 'vue'
    
    exportt default {
        name:'myApp',
        setup(props,context){
            //属性
            const name = '胖奶奶与胖小伙'
            
            //方法
            const Hi = (name:string):voild =>{
                console.log('Hi'+name)
            }
            
            //必须返回在模版才可以用,返回对象
            return {
                name,
                Hi
            }
            
            //返回渲染函数,需要我们引入 h
            return () => {
              return  h('span','我是渲染函数')
            }
        }
    }
    
</script>

2、ref,reactive的使用

<script lang="ts">
    //引入ref 、reactive
    import { ref,  reactive } from 'vue'
    
    exportt default {
        name:'myApp',
        setup(){
            //声明响应数据 name 
            //`基本类型数据`,不存在数据劫持
            const name = ref('胖奶奶与胖小伙')
            //修改 name  .value不可缺少 ,模板中使用不用 `.value`
            name.value = '我改变了'
            //获取 name
            console.log(name.value)
            
            //reactive,Proxy代理对象数据劫持实现响应式
            //1、对象类型数据   
            //**`处理一个响应式的对象数据` 注意无法处理基本类型数据**
            const msgList = reactive({
                name:'',
                job:'挖矿小伙'
            }) 
            //修改数据
            msgList.name = '胖奶奶与胖小伙'
            //获取数据job
            console.log(msgList.job)
            
            //2、数组数据
            const study = reactive(['语文','数学','体育'] )
            //修改 语文
            study[0] = '政治'
            //获取 数学
            console.log(study[1])
        }
    }
    
</script>

3、理解vue3响应式实现原理

在vue2中:存在的问题及解决方案,新增、删除数据或直接下标修改数组,页面无法更新

<script lang="ts">
    import vue from 'vue'
    
    exportt default {
        name:'myApp',
        data(){
            return {
                userMsg:{
                    name:'胖奶奶与胖小伙',
                    age:18
                }
            }
        },
        methods(){
            //在userMsg添加一个学历
            addEdu(){
                //该写发不生效
                this.userMsg.edu = '小学'
                
                //正确写法
                this.$set(this.userMsg,'edu','小学')
                //or
                vue.set(this.userMsg,'edu','小学')
                
            },
            delName(){
                //该写发不生效
                delete this.userMsg.name
                
                //正确写法
                this.$delete('this.userMsg','name')
                //or
                vue.set(this.userMsg,'name','胖奶奶与胖小伙')
            }
        }
       
    }
    
</script>

在vue3中响应式实现的原理,解决了Vue2存在的问题

<script lang="ts">
    //原始数据
    let userMsg = {
        name:'胖奶奶与胖小伙',
        age:18
    }
    
    //vue2响应式模拟,无法捕获添加,删除
    let uMsg = {}
    Object.defineProperty(uMsg,'name',{
        get(){
            return userMsg.name
        },
        set(){
            console.log('数据改变了')
            userMsg.name = ''
        }
    })
    
    //vue3响应式原理
    //映射userMsg,从而代理userMsg,Proxy可以捕获`增、删、改、查`
    
    //Proxy代理对象
    const uMsg = new Proxy(userMsg,{
        //获取
         get(target,propName){
             //可以实现响应式
           // return target[propName]
           
           //vue3底层实现通过反射对象 Reflect修改原对象属性
          return Reflect.get(target,propName)
        },
        
        //修改、添加
        set(target,propName,value){
            console.log('数据改变了')
              //可以实现响应式
            //userMsg.name = ''
            
             //vue3底层实现通过反射对象 Reflect修改原对象属性
            Reflect.set(target,propName,value)
        }
        //删除
        deleteProperty(target,propName){
           //可以实现响应式
           // return delete target[propName] //捕获删除
            
          //vue3底层实现通过反射对象 Reflect修改原对象属性
          return Reflect.deleteProperty(target,propName) //捕获删除
        },
    }) 
    
    
</script>

ref和reactive区别:

ref定义基本类型数据,也可定义对象数组类型数据,但内部会通过reactive转换为代理对象, ref通过Object.definePropertyget()set()实现响应式,操作数据需要.value,模版不需要,可直接使用 reactive只能定义对象、数组类型数据,通过Proxy数据劫持,并通过反射对象 Reflect 修改原对象属性实现响应式,读取操作数据不需要.value

4、计算属性、监听

<script lang="ts">
    //引入ref 、reactive、
    import { ref,  reactive, computed} from 'vue'
    
    exportt default {
        name:'myApp',
        //vue2中,开发中不建议vue2、vue3混用
        computed:{
            changeName(){
                return this.msgList.name + '520'
            }
        },
        setup(){ 
            const msgList = reactive({
                name:'',
                job:'挖矿小伙'
            }) 
            
            //vue3 中计算属性 —— 简写模式 不考虑修改
            msgList.changeName = computed(() => {
                return msgList.name + '520'
            })
            
            //完整模式,读写
            msgList.changeName = computed({
                //获取
                get(){
                  return msgList.name + '520'
                },
                
                //修改
                set(value){
                    msgList.name = value
                }
            })
            
            return {
                msgList
            }
        }
    }
    
</script>

wacth

<script lang="ts">
    import { ref,  reactive, computed, watch, watchEffect} from 'vue'
    
    exportt default {
        name:'myApp',
        
        //vue2中,开发中不建议vue2、vue3混用
        watch:{
             //简写
            total(newValue, oldValue){
                console.log(newValue)
            },
             //完整写法 
            total:{
                deep:true,
                immediate:true,
                handler(newValue, oldValue){
                    console.log(newValue)
                }
            }
        },
        setup(){ 
            const total =ref(0)
            const name = '小胖'
            const msgList = reactive({
                person:{
                    a{
                        name:'小胖'
                    }
                },
                name:'',
                job:'挖矿小伙'
            }) 
            
            /*****vue3中
            *
            *注意,可调用多个 watch**
            *注意,ref 基本数据类型不需要 `.value`
            *
            ******/
            
            //1、vue3 中监视 `ref` 数据
            watch(total,(newValue, oldValue) => {
                 console.log(newValue)
            },{ immediate:true })
            
            //2、vue3 中监视多个 `ref` 数据
            watch([total,name],(newValue, oldValue) => {
                 console.log(newValue)
            },{ immediate:true })
            
            //3、vue3 中监视多个 `reactive` 数据
             watch(msgList,(newValue, oldValue) => {
                 console.log(newValue)
            },{ immediate:true })
            
            //4、vue3 中监视 **多个 `reactive` 某个数据** 强制开启深度监视
            watch(() => msgList.name,(newValue, oldValue) => {
                 console.log(newValue)
            },{ immediate:true })
            
            //5、vue3 中监视 **多个 `reactive` 某些数据**
            watch([() => msgList.name,() => msgList.job],(newValue, oldValue) => {
                 console.log(newValue)
            },{ immediate:true })
            
            //6、vue3 中监视  `reactive` 特殊情况监视某个深度对象  需要开启深度监视
            watch([() => msgList.person,() => msgList.job],(newValue, oldValue) => {
                 console.log(newValue)
            },{ immediate:true ,deep:true})
            
           /******
           *
           * watchEffect 默认开启immediate
           * 可以分别监视需要的属性, 用谁监视谁
           * 有点类似 computed
           * 
           ******/
           watchEffect(() => {
               const a = total.value
               console.log(a )
           })
            
            return {
                total,
                name,
                msgList
            }
        }
    }
    
</script>

5、生命周期

??注意:vue3 提供了组合式API生命周期钩子

1、没有提供beforeCreate() created()组合API钩子,同等于 setup(); 2、更改了两个命名钩子beforeUnmount() 、 unmount();3、使用中需要引入

6、hook函数,作用封装组合式API,组件化

对功能化组件进行抽离,一般以use开头命名,例如在hook下创建 useDataTime.ts

// 时间戳转换
const dataTimes = (result):string => {
	const date = new Date(result);
	let y = date.getFullYear();
	let MM = date.getMonth() + 1;
	MM = MM < 10 ? ('0' + MM) : MM;
	let d = date.getDate();
	d = d < 10 ? ('0' + d) : d;
	let h = date.getHours();
	h = h < 10 ? ('0' + h) : h;
	let m = date.getMinutes();
	m = m < 10 ? ('0' + m) : m;
	let s = date.getSeconds();
	s = s < 10 ? ('0' + s) : s;
	return y + '-' + MM + '-' + d
}

export default dataTimes

7、其他组合API

toRetoRefs,把一个普通数据转换成响应式数据

<script lang="ts">
    import { ref,  reactive, toRe, toRefs} from 'vue'
    
    exportt default {
        name:'myApp',
        setup(){ 
            const msgList = reactive({
                name:'',
                age:20,
                job:'挖矿小伙'
            }) 
            
            return {
                msgList,//是响应式
                msgList.name,//不是响应式
                msgList.age,//不是响应式
                name:ref(msgList,'name'),//转换成ref响应式,但不改变原是数据 
                name:toRef(msgList,'name'),//toRef引用原数据
                ...toRefs(msgList)//toRefs把所有数据变成响应式
            }
        }
    }
    
</script>

shallowRefshallowReactive,浅层响应式,只考虑第一层数据;

readonlyshallowreadonly ,只读;

toRowmarkRow,原始的数据

<script lang="ts">
    import { ref,  reactive,shallowRef,shallowreactive, readonly, shallowReadonly} from 'vue'
    
    exportt default {
        name:'myApp',
        setup(){ 
        
            /******
            *
            * shallowreactive 只处理对象最外层响应式
            * shallowRef 只处理基本类型数据响应式,无法处理对象类型,一般数据只改变一次使用
            *
            ******/
            const msgList = reactive({
                name:'',
                age:20,
                job:{
                    salary:80000,
                    des:''
                },
                list:{}
            }) 
            
            const a = shallowRef(3)
            const a = shallowreactive({
                name:'',
                age:20,
                job:{
                    salary:80000,
                    des:''
                }
            })
            
            //把 `msgList` 响应式改为只读
            msgList = readonly(msgList)
            msgList = shallowReadonly(msgList) //浅层次
            
            //输出最原始数据
            const starts = () => {
                //数据中转,还原原数据,toRow只能处理reactive数据类型
                const a = toRow(msgList) //无法对a进行操作
                console.loog(a)
                
                //markRow 标为普通对象
                let list = {
                    x:1,
                    y:2
                }
                msgList.list = markRow(list)
                
            }
            
            return {
                msgList,
              
            }
        }
    }
    
</script>

customRef自定义响应式

/***
*
*  `customRef()` 预期接收一个工厂函数作为参数,这个工厂函数接受 `track` 和 `trigger`两个函数作为参数,
* 并返回一个带有 `get` 和 `set` 方法的对象。
*
* 一般来说,`track()` 应该在 `get()` 方法中调用,而 `trigger()` 应该在 `set()` 中调用。然而事
* 实上,你对何时调用、是否应该调用他们有完全的控制权。
*
*
***/
import { customRef } from 'vue'

export function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}

组件中使用:

<template>
  <input v-model="text" />
</template>

<script setup lang="ts">
    import { useDebouncedRef } from './debouncedRef'
    const text = useDebouncedRef('hello')
</script>

组件件通讯,provideinject

<------- 父组件 ------->
<template>
 <h3>我是父组件</h3>
 <Child/>
</template>

//父组件 provide 提供
<script lang="ts">
   import { ref,  reactive, toRe, toRefs, provide} from 'vue'
   import 'Child' from './components/Child.vue'
   
   components:{
       Child
   },
   exportt default {
       name:'myApp',
       setup(){ 
           const msgList = reactive({
               name:'',
               age:20,
               job:'挖矿小伙'
           }) 
           provide('msgList',msgList)
           return {
              ..toRefs(msgList)
           }
       }
   }
   
</script>

<------- 子组件 ------->
<template>
 <h3>我是子组件</h3>
  <span></span>
</template>

//子组件 props 提供
<script lang="ts">
   import { ref,  reactive, toRe, toRefs,} from 'vue'
   
   components:{
       son
   },
   exportt default {
       name:'child',
       setup(props,ctx){ 
           console.log(props)
       }
   }
   
</script>

<------- 后代组件 ------->
//后代组件 inject 提供
<script lang="ts">
   import { ref,  reactive, toRe, toRefs, inject} from 'vue'
   
   components:{
       son
   },
   exportt default {
       name:'child',
       setup(){ 
           const msgList = reactive({
               name:'',
               age:20,
               job:'挖矿小伙'
           }) 
          let msgList =  inject('msgList')
           return {
              msgList
           }
       }
   }
   
</script>

判断是否是响应式数据,isRef()isReactive() isReadonly() isProxy()是否为真即可

Fragment虚拟跟组件、Teleport传送门组件、Suspense 异步组件

欢迎收藏、点赞!

相关推荐

Python 操作excel的坑__真实的行和列

大佬给的建议__如何快速处理excelopenpyxl库操作excel的时候,单个表的数据量大一些处理速度还能接受,如果涉及多个表甚至多个excel文件的时候速度会很慢,还是建议用pandas来处理,...

Python os.path模块使用指南:轻松处理文件路径

前言在Python编程中,文件和目录的操作是非常重要的一部分。为了方便用户进行文件和目录的操作,Python标准库提供了os模块。其中,os.path子模块提供了一些处理文件路径的函数和方法。本文主要...

Python常用内置模块介绍——文件与系统操作详解

Python提供了多个强大的内置模块用于文件和系统操作,下面我将详细介绍最常用的几个模块及其核心功能。1.os模块-操作系统交互...

Python Flask 建站框架实操教程(flask框架网页)

下面我将带您从零开始构建一个完整的Flask网站,包含用户认证、数据库操作和前端模板等核心功能。##第一部分:基础项目搭建###1.创建项目环境```bash...

为你的python程序上锁:软件序列号生成器

序列号很多同学可能开发了非常多的程序了,并且进行了...

PO设计模式全攻略,在 UI 自动化中的实践总结(以企业微信为例)

一、什么是PO设计模式?PO(PageObject)设计模式将某个页面的所有元素对象定位和对元素对象的操作封装成一个Page类,即一个py文件,并以页面为单位来写测试用例,实现页面对象和测试用例的...

这种小工具居然也能在某鱼卖钱?我用Python一天能写...

前两天在某鱼闲逛,本来想找个二手机械键盘,结果刷着刷着突然看到有人在卖——Word批量转PDF小工具...

python打包成exe,程序有图标,但是任务栏和窗口都没有显示图标

代码中指定图标信息#设置应用ID,确保任务栏图标正确显示ifsys.platform=="win32":importctypesapp_id=...

使用Python构建电影推荐系统(用python做推荐系统)

在日常数据挖掘工作中,除了会涉及到使用Python处理分类或预测任务,有时候还会涉及推荐系统相关任务。...

python爬取并分析淘宝商品信息(python爬取淘宝商品数据)

python爬取并分析淘宝商品信息背景介绍一、模拟登陆二、爬取商品信息1.定义相关参数2.分析并定义正则3.数据爬取三、简单数据分析1.导入库2.中文显示3.读取数据4.分析价格分布5.分析销售...

OpenCV入门学习基础教程(从小白变大神)

Opencv是用于快速处理图像处理、计算机视觉问题的工具,支持多种语言进行开发如c++、python、java等,下面这篇文章主要给大家介绍了关于openCV入门学习基础教程的相关资料,需要的朋友可以...

python图像处理-一行代码实现灰度图抠图

抠图是ps的最基本技能,利用python可以实现用一行代码实现灰度图抠图。基础算法是...

从头开始学python:如何用Matplotlib绘图表

Matplotlib是一个用于绘制图表的库。如果你有用过python处理数据,那Matplotlib可以更直观的帮你把数据展示出来。直接上代码看例子:importmatplotlib.pyplot...

Python爬取爱奇艺腾讯视频 250,000 条数据分析为什么李诞不值得了

在《Python爬取爱奇艺52432条数据分析谁才是《奇葩说》的焦点人物?》这篇文章中,我们从爱奇艺爬取了5万多条评论数据,并对一些关键数据进行了分析,由此总结出了一些明面上看不到的数据,并...

Python Matplotlib 库使用基本指南

简介Matplotlib是一个广泛使用的Python数据可视化库,它可以创建各种类型的图表、图形和可视化效果。无论是简单的折线图还是复杂的热力图,Matplotlib提供了丰富的功能来满足我们...

取消回复欢迎 发表评论: