其他分享
首页 > 其他分享> > vue3技术整理 - 更新完毕

vue3技术整理 - 更新完毕

作者:互联网

0、前言




1、创建vue3项目

官网文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create



1.1、使用vue-cli创建

注意:需要保证自己的vue-cli版本在4.5.0以上


	查看自己@vue/cli版本
	Vue -V

	安装或升级@vue/cli
	npm install -g @vue/cli

	创建Vue3项目
	vue create 项目名

	使用ui可视化界面创建【 ps:会在浏览器中打开一个管理窗口,进行手动创建和配置选项,目前不建议用,学完所有就可以使用了 】
	vue ui

	启动Vue3项目
	cd 进入到创建的项目中
	npm run serve


image

image

image

image




1.2、使用vite创建

官网地址;https://v3.cn.vuejs.org/guide/installation.html#vite

image



vite是另一门技术,是下一代的前端构建工具【 ps:是vue官网打造的,久一代的就是webpack 】。vite官网地址 https://vitejs.cn/



整理vite创建vue3的相关指令


	创建项目
	npm init vite-app 项目名

	进入项目目录
	cd 项目名

	安装依赖
	npm install


	运行项目
	npm run dev

image

image

image

image




2、分析vue-cli创建的vue3项目



2.1、查看整个目录结构

image

image




2.2、分析入口文件main.js

image


其他的东西和vue2中没什么两样


注意点:template中的写法和vue2相比有点变化

image




3、安装vue3的开发者工具

注意:这里安装的测试版( data )


直接使用google进行安装即可,要是无法进入google应用商店的话,那么:去百度chrome插件网就可以了;或者:下载一个佛跳墙 / 极光【 ps:佛跳墙现在的名字貌似改为极光了,下载安装之后,直接链接,然后就可以FQ了,有其他APN代理更好 】


image


注意:vue2和vue3的开发者工具最好别一起开启,开了vue2就别开vue3,开了vue3就别开vue2,很容器出问题




4、认识基本的Composition API / 组合式API

4.1、认识setup函数

setup是Compostition API / 组合式API的地基,setup是一个函数,且必须有返回值,玩vue3,那么就需要提供一个平台,而这个平台就是setup




4.1.1、对setup函数快速上手


	<template>
	  <!-- 这里面能够拿到以下的东西,全靠的是setup的return返回回来的结果 -->
	  <h1>姓名: {{name}}</h1>
	  <h1>性别: {{sex}}</h1>
	  <h1>工种: {{job}}</h1>

	  <br>
	  <br>

	  <button @click="helloword">调用一下vue3的setup中定义的方法</button>
	</template>

	<script>

	export default {
	  name: 'App',

	  // 一、配置setup平台
	  setup(){
		// 这里面的配置和vue2中的差不多,什么数据、方法、计算属性、生命周期.......只是写法有区别

		// 配置数据【 ps:直接定义即可 】
		let name = '紫邪情';
		let sex = '女';
		let job = 'Java';

		// 配置方法
		function helloword(){
		  // 注意点:alert()里面用的是模板字符串 - 飘字符嘛;${name}就是取上面定义的数据
		  alert(`我叫: ${name},性别: ${sex}.工种: ${job}`)
		}

		// setup必须有返回值 return - 就是为了把setup配置的东西交出去嘛,不然别人怎么拿到
		// 但是:return有两种写法

		// 1、对象写法
		return {
		  // 返回数据
		  name,sex,job,

		  // 返回方法
		  helloword
		}
	  }
	}
	</script>

image



补充:setup函数返回值的另一种写法:返回渲染函数写法 - 了解接口【 ps:这是为了自定义渲染内容的 】



		// 2、第二种写法:返回渲染函数 - 了解即可
		// 这种写法:会将下面自定义写的渲染内容 放到 前面template中去渲染
		// 即:template的渲染依赖于下面自定义内容

		// 第一步:需要在本组件中引入渲染函数h
		// 第二步:使用渲染函数 并 返回
		// return ( (h) => h( 'h1', '这是setup中的返回渲染函数用户') )
		// 简写
		return () => h('h1','这是setup中的返回渲染函数用户')

image

image




4.1.2、聊聊setup函数的细节问题

用setup和vue2的写法一起用 - 最好:坚决别用

image

image



image

image



setup()的另外一个注意点 和 其可以接收的两个参数 - 演示自行玩




4.1.3、vue3的setup函数总结



setup()的另外一个注意点 和 其可以接收的两个参数




4.2、ref函数

先做一个实例:修改setup中的数据

    <template>
      <h1>vue3的setup函数得到的操作</h1>
      <h2>姓名: {{name}}</h2>
      <h2>性别: {{sex}}</h2>
      <button @click="changeData">修改setup中的数据</button>
    </template>

    <script>
    export default {
      name: 'App',

      // 一、配置setup平台
      setup(){

        let name = '紫邪情';
        let sex = '女';

        function changeData(){
          name = '紫邪晴'
          sex = '男'
          console.log("修改之后的数据: ",name,sex);
        }

        // 1、对象写法
        return {
          // 返回数据
          name,sex,

          // 返回方法
          changeData
        }
      }
    }
    </script>

image


没实现出来,原因就是:vue不认你的修改,因此:需要借助ref函数来套娃




4.2.1、看看ref函数的真身

    <template>
      <h1>vue3的setup函数得到的操作</h1>
      <h2>姓名: {{name}}</h2>
      <h2>性别: {{sex}}</h2>
      <button @click="changeData">修改setup中的数据</button>
    </template>

    <script>

    import {ref} from 'vue'
    export default {
      name: 'App',

      // 一、配置setup平台
      setup(){

        // 使用ref函数来进行实现,进行套娃,把数据丢给ref函数进行管理
        let name = ref('紫邪情');
        let sex = ref('女');

        function changeData(){
          // console.log("修改之后的数据: ",name,sex);

          // 看一下ref函数的真身
          console.log(name);
        }

        // 1、对象写法
        return {
          // 返回数据
          name,sex,

          // 返回方法
          changeData
        }
      }
    }
    </script>

image



既然知道了ref函数的真身,那么:想要实现数据的改变就变得轻松了

image

image



有个注意点

image




4.2.2、使用ref处理对象类型

4.2.2.1、看一下ref函数中套对象的样子是怎样的
    <template>
      <h2>工种: {{job.type}}</h2>
      <h2>薪资: {{job.salary}}</h2>
      <button @click="changeData">查看一下ref函数中套对象的样子</button>
    </template>

    <script>

    import {ref} from 'vue'
    export default {
      name: 'App',

      // 一、配置setup平台
      setup(){
        // 套对象在ref中
        let job = ref({
          type: 'Java',
          salary: '20k'
        });

        function changeData(){
          // 先看一下ref中套对象的样子是怎样的
          console.log(job.value);
        }

        // 1、对象写法
        return {
          // 返回数据
          job,
          // 返回方法
          changeData
        }
      }
    }
    </script>

image

既然知道了ref函数中套了对象的样子长什么样的,那么:想要修改ref里面套的对象的属性就很好操作了




4.2.2.2、修改ref函数中对象的属性值

image

image


小小总结一下




4.2.3、对ref函数小小总结一波




4.3、认识reactive()函数 - 深度监视



简单玩一下reactive()函数

    <template>
      <h1>ref托管的数据</h1>
      <h2>{{name}}</h2>

      <br>
      <br>

      <h1>reactive托管的数据</h1>
      <h2>{{job.type}}</h2>
      <h2>{{job.salary}}</h2>

      <br>
      <br>

      <button @click="changeData">修改ref和reactive托管的数据</button>
    </template>

    <script>

    import {ref,reactive} from 'vue'
    export default {
      name: 'App',

      // 一、配置setup平台
      setup(){
        // 配置基本类型数据 - 通过ref实现
        let name = ref('紫邪情');
        // 使用reactive来管理数据
        let job = reactive({
          type: 'Java',
          salary: '20k'
        })
        // 修改基本类型数据
        function changeData(){
          // 修改ref管理的数据类型
          name.value = '紫邪晴';

          // 修改reactive托管的数据 - 相比ref,不再跟value了
          job.type = 'C';
          job.salary = '3毛';
        }

        return {
          // 返回基本类型数据 - ref托管
          name,

          // 返回reactive托管的数据
          job,

          // 返回函数
          changeData,
        }
      }
    }
    </script>

image



了解reactive的细节问题

image

image


image

image


image

image


image

image




4.3.1、对reactive()函数总结一波




4.4、vue3中数据监视的原理

4.4.1、Proxy数据监视原理

vue2中数据监视如果是对象类型的,那么是通过Object.defineProperty()的getter和setter来做到数据监视的;如果是数组类型那么就是通过那7个API做到数据监视,但是这种方式有弊端,如下:


但是:vue3中就不会出现上面的几种情况



先来看一下Proxy长什么样子

image

image



使用Proxy进行修改数据



    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>研究Proxy监视数据原理</title>
    </head>
    <body>
        <script>
            // 定义一个对象
            let person = {
                name: '紫邪情',
                sex: '女'
            }

            // 利用Window.Proxy()来进行修改person

            // 先看一下Proxy的样子
            // console.log( new Proxy(person,{} ) );

            // 使用Proxy进行数据修改
            /* 
                people 就是代理对象 它代理的就是person
                new Proxy()就是创建一个代理对象嘛 - 后端的人太熟悉不过了
            */
            const people = new Proxy( person, {
                // 获取对象的属性时调用
                /* 
                target 就是源对象 即:person
                propName  就是对象中的属性名  如:name、sex.....
                */
                get(target,propName){
                    console.log( "target,propName这两个参数为: ", target,propName);
                    console.log(`有人获取person中的${propName}属性`);
                    return target[propName];
                },

                // 修改对象中的属性时调用【 ps:修改含增、改、删除是另一个配置 】
                // value就是修改之后的值
                set( target,propName,value ){
                    console.log( "target,propName,value这三个参数为: ", target,propName,value);
                    console.log( `有人修改person中的${propName}属性` );
                    return target[propName] = value;
                },

                // 删除对象中的属性时调用
                deleteProperty(target,propName){
                    console.log( "target,propName这两个参数为: ", target,propName);
                    return delete target[propName];
                }
            })
        </script>
    </body>
    </html>


image




4.4.2、Reflect数据监视原理

在vue3中数据监视不止用了window的Proxy对象,还用了window的Reflect对象

Reflect就是反射的意思,这个东西对于玩Java的人来说再熟悉不过了,所以不再过多介绍,在前段中这个是ES6的特性



认识Reflect对象

		// 先看看Reflect长什么样
        console.log(window.Reflect);

image



经过上图的查看之后,其实也就知道Reflect改怎么玩了,调对应的API就可以了【 ps:ECMA组织正打算把常用的一些API放到Reflect对象身上,如:目前把Object.defineProperty()就放在Reflect中了 - vue2的数据代理原理的API 】



使用Reflect实现数据监视

        let person = {
            name: '紫邪情',
            sex: '女'
        }

        // 先看看Reflect长什么样
        // console.log(window.Reflect);

        // 使用Reflect实现数据监视

        // 1、获取对象的属性 - key-value的形式
        /* 
            key 就是对象名
            value 就是对象的属性名
        */
		Reflect.get( person,'name' );


        // 2、修改对象的属性 
		Reflect.set( person,'sex','男');
		Reflect.set( person,'age', '18');

        // 3、删除对象的属性
		Reflect.deleteProperty( person,'sex');

image



注意:使用Reflect做对应的操作之后是有返回值的,如:Reflect.set( person,'age',18 ),返回值是true,所以:就可以利用这个返回值做很多事情,如:进行封装,而Object.defineProperty()并没有返回值
同时:Reflect支持属性名重复,即:若用set()这个API对同一个对象的同一个属性做多次相同的操作,则:不会返回异常,而是返回true / false,因此:才说可以用这个返回值做很多事情;若用Object.defineProperty()来进行相同的操作,则:会直接抛异常,甚至想要后续的代码还能运行,就只能使用try......catch....来对该部分的代码进行包裹了



vue3真正做到数据监视的原理 - 使用Proxy和Reflect对象进行套娃


	<!DOCTYPE html>
	<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>vue3实现数据监视的真正原理</title>
	</head>
	<body>
		<script>
			let person = {
				name: '紫邪情',
				sex: '女'
			}

			const people = new Proxy( person, {
				// 获取对象的属性时调用
				get(target,propName){
					console.log( "target,propName这两个参数为: ", target,propName);
					console.log(`有人获取person中的${propName}属性`);
					// 此处进行了Reflect套娃
					// return target[propName];
					return Reflect.get(target,propName);
				},

				// 修改对象中的属性时调用【 ps:修改含增、改、删除是另一个配置 】
				set( target,propName,value ){
					console.log( "target,propName,value这三个参数为: ", target,propName,value);
					console.log( `有人修改person中的${propName}属性` );
					// 此处进行了Reflect套娃
					// return target[propName] = value;
					return Reflect.set(target,propName,value);
				},

				// 删除对象中的属性时调用
				deleteProperty(target,propName){
					console.log( "target,propName这两个参数为: ", target,propName);
					// 此处进行了Reflect套娃
					// return delete target[propName];
					return Reflect.defineProperty(target,propName);
				}
			})
		</script>
	</body>
	</html>





4.4.3、vue3中数据监视原理总结

image




4.5、reactive() 和 ref()的对比




4.6、Vue3中的Computed 计算属性函数

    <template>
      姓;<input type="text" v-model="person.firstName">

      <br>

      名: <input type="text" v-model="person.lastName">

      <br>

      <span>全名: {{person.fullName}}</span>
    </template>

    <script>
    import { reactive } from '@vue/reactivity'

    // 1、引入computed计算属性函数
    import { computed } from '@vue/runtime-core'

    export default {
      name: 'App',

      setup(){

        // 数据
        let person = reactive({
          firstName: '紫',
          lastName: '邪情'
        })

        // 2、使用计算属性函数 setup中this无效,所以computed()中使用兰姆达和正常写法都无所谓
        // 简写形式 - 只考虑读的问题
        person.fullName = computed( ()=>{
          return person.firstName + "-" + person.lastName;
        })

        // 完整写法 - 考虑读和改的问题
       /*  person.fullName = computed({
          get(){
            return person.firstName + "-" + person.lastName;
          },

          set(value){
            const nameDataArr = value.split('-')
            person.firstName = nameDataArr[0]
            person.lastName = nameDataArr[1]
          }
        }) */

        // 返回数据
        return {
          person,
        }
      }
    }
    </script>




4.7、vue3中的watch 监视属性函数



4.7.1、监视ref()定义的数据


简单写法:监视ref托管的单个响应式数据

    <template>
      <h1>当前值为: {{num}}</h1>
      <button @click="num ++ ">num++</button>
    </template>

    <script>

    // 1、引入watch函数
    import { ref, watch } from '@vue/runtime-core'


    export default {
      name: 'App',

      setup(){

        // 准备数据 - 用ref托管
        let num = ref(0)


        // 一、简单写法
        // 2、使用watch函数
        /* 
          可以接受三个参数
              第一个:监视的是谁?
              第二个:回调函数 - 新值 和 旧值
              第三个:配置项 - deep深度监视也可以配置
        */
        watch( num , (newValue,oldValue)=>{
          console.log("num的值发生改变了",newValue,oldValue);
        },{immediate:true})


        return {
          num,
        }
      }
    }
    </script>

image



监视多个属性:监视ref托管的多个响应式数据【 ps:数组写法 】

    <template>
      <span>当前名字为: {{name}}</span>
      <br>
      <button @click="name += '!'">改变name</button>
    </template>

    <script>

    // 1、引入watch函数
    import { ref, watch } from '@vue/runtime-core'


    export default {
      name: 'App',

      setup(){

        // 准备数据 - 用ref托管
        let num = ref(0)

        let name = ref('紫邪情')

        // 监视ref托管的多个响应式数据 - 变化就在这里 监事的是谁?采用数组写法即可
        watch( [num,name],(newValue,oldValue)=>{
          console.log("num 和 name的值发生改变了",newValue,oldValue);
        },{immediate:true})
        return {
          num,name
        }
      }
    }
    </script>




4.7.2、监视reactive()定义的数据

监视reactive托管的一个响应式数据中的全部属性

    <template>
      姓名: <input type="text" v-model="person.name"> <br>
      性别: <input type="text" v-model="person.sex"> <br>
      地址: <input type="text" v-model="person.address.detailed.value">

      <br>
      <br>

      <span>姓名: {{person.name}}</span> <br>
      <span>性别: {{person.sex}}</span> <br>
      <span>地址: {{person.address.detailed.value}}</span>
    </template>

    <script>
    import { reactive } from '@vue/reactivity'
    import { watch } from '@vue/runtime-core'

    export default {
      name: 'App',

      setup(){

        // 准备数据 - 用reactive托管
        let person = reactive({
          name: '紫邪情',
          sex: '女',
          address: {
            detailed: {
              value: '浙江省杭州市'
            }
          }
        })

        // 监视reactive托管的一个响应式数据中的全部属性
        watch( person,(newValue,oldValue)=>{
          console.log( "person被修改了", newValue,oldValue);
        })

        return {
          person,
        }
      }
    }
    </script>

image


上面这种坑就是在监视此种reactive托管的一个响应式数据的全部属性时,并不能获得旧值oldValue,因为:旧值oldValue和新值newValue一样



但是:还有一种坑,就是:此种类型是强制开启了深度监视,即:配置deep:false不顶用

image

image



监视reactive托管的一个响应式数据中的某一个属性

    // 类型二、监视reactive托管的一个响应式数据中的某一个属性
    /* 
      奇葩的地方:
          1、要监视的这个属性需要写成函数式 ()=> person.name
          2、可以争取获取newValue、oldValue
    */
    watch( ()=> person.name , (newValue,oldValue)=>{
      console.log("person中的name属性被修改了",newValue,oldValue);
    })

image



监视reactive托管的一个响应式数据中的某些属性 - 函数式数组写法

    // 类型三、监视reactive托管的一个响应式数据中的某些属性
    /* 
      奇葩的地方:
          1、监视的多个属性需要使用数组套起来
          2、数组中的每一个属性需要写成函数式
    */
    watch( [ ()=> person.name , ()=> person.sex ] , (newValue,oldValue)=>{
      console.log("person中的name和sex属性被修改了",newValue,oldValue);
    })

image



特殊情况:监视reactive托管的一个响应式数据中的某一个属性【 ps:此属性套娃了,又是一个对象 】

    // 类型四、监视reactive托管的一个响应式数据中的某个属性,但:此属性又套娃了
    /* 
      奇葩的地方:
          1、需要开启深度监视 即:deep:true 又生效了
          2、不加 deep:true配置,代码会无效
    */
    watch( ()=> person.address , (newValue,oldValue)=>{
      console.log("person中的address属性被修改了",newValue,oldValue);
    },{deep:true})

image


但是:如果不加deep:true配置呢?

image

image




4.7.2.1、监视reactive托管的一个响应式数据的各种类型总结

    // 准备数据 - 用reactive托管
    let person = reactive({
      name: '紫邪情',
      sex: '女',
      address: {
        detailed: {
          value: '浙江省杭州市'
        }
      }
    })

    // 类型一、监视reactive托管的一个响应式数据中的全部属性
    /* 
      此种类型的坑:
          1、无法正确获得oldValue的值【 ps:因newValue和oldValue的值一样 】
          2、简直强制开启了深度监视 【 ps:即deep:false配置无效 】
    */
    watch( person,(newValue,oldValue)=>{
      console.log( "person被修改了", newValue,oldValue);
    },{deep:false})
    /* 
      如:这里关闭深度监视 理论上:应该监视不到address.detailed.value
          但是:天真
    */


    // 类型二、监视reactive托管的一个响应式数据中的某一个属性
    /* 
      奇葩的地方:
          1、要监视的这个属性需要写成函数式 ()=> person.name
          2、可以争取获取newValue、oldValue
    */
    watch( ()=> person.name , (newValue,oldValue)=>{
      console.log("person中的name属性被修改了",newValue,oldValue);
    })


    // 类型三、监视reactive托管的一个响应式数据中的某些属性
    /* 
      奇葩的地方:
          1、监视的多个属性需要使用数组套起来
          2、数组中的每一个属性需要写成函数式
    */
    watch( [ ()=> person.name , ()=> person.sex ] , (newValue,oldValue)=>{
      console.log("person中的name和sex属性被修改了",newValue,oldValue);
    })

    // 类型四、监视reactive托管的一个响应式数据中的某个属性,但:此属性又套娃了
    /* 
      奇葩的地方:
          1、需要开启深度监视 即:deep:true 又生效了
          2、不加 deep:true配置,代码会无效
    */
    watch( ()=> person.address , (newValue,oldValue)=>{
      console.log("person中的address属性被修改了",newValue,oldValue);
    },{deep:true})

    return {
      person,
    }




4.8、vue3中的watchEffect 智能监视函数


    <template>
      姓名: <input type="text" v-model="person.name"> <br>
      性别: <input type="text" v-model="person.sex"> <br>
      地址: <input type="text" v-model="person.address.detailed.value">

      <br>
      <br>

      <span>姓名: {{person.name}}</span> <br>
      <span>性别: {{person.sex}}</span> <br>
      <span>地址: {{person.address.detailed.value}}</span>
    </template>

    <script>
    import { reactive } from '@vue/reactivity'

    // 1、引入watchEffect函数
    import { watchEffect } from '@vue/runtime-core'

    export default {
      name: 'App',

      setup(){

        let person = reactive({
          name: '紫邪情',
          sex: '女',
          address: {
            detailed: {
              value: '浙江省杭州市'
            }
          }
        })

        // 2、使用watchEffect函数对响应式数据进行智能监视
        /* 
          1、不需要指名要监视谁
          2、不需要newValue 和 oldValue【 ps:因为都不知道要监视谁 】
        */
        watchEffect( ()=>{
          // 所谓智能:就体现在这里面的函数体中
          //          要监视谁,取决于这个函数体里面用到了谁,那就监视谁

          // 如:要监视person中的name,那就直接写改写的代码即可,此函数会自动判定,从而监视
          const personName = person.name

          // 如:要监视person中的sex,那就用它就可以了
          const personSex = person.sex

          console.log("watchEffect智能监视函数被调用了");

          // 而此函数体中没有用到的,那么:就不会去监视它
        })

        return {
          person,
        }
      }
    }
    </script>

image

image

image

image




4.9、vue3中的watch函数 和 watchEffect函数的对比




4.10、vue3中的生命周期图

image


上面这种图官网中有

image




4.10.1、vue3中生命周期的注意项

对比vue2中的生命周期,vue3中改动的地方,如下所示

image

image



2、vue3中生命周期的写法问题

    <script>

        export default {
          name: 'App',

          setup() {},

          // vue3中的生命周期 - 配置项写法 【 ps:和name、setup保持平级即可 】
          beforeCreate(){ console.log("------beforeCreate-----"); },
          created(){ console.log("------created-----"); },
          beforeMount(){ console.log("------beforeMount-----"); },
          mounted(){ console.log("------mounted-----"); },
          beforeUpdate(){ console.log("------beforeUpdate-----"); },
          updated(){ console.log("------updated-----"); },
          beforeUnmount(){ console.log("------beforeUnmount-----"); },
          unmounted(){ console.log("------unmounted-----"); },

        }
    </script>



另一种写法:组合式API写法 - 万事引入对应函数嘛 - 不过此种方式名字有点区别

<script>
// 1、引入对应的钩子函数
import { onBeforeMount, onMounted } from '@vue/runtime-core'

export default {
  name: 'App',

  setup() {

    // 另一种写法 - 组合式API写法 - 万事引入对应的函数嘛
    /* 
      只是注意:setup()就相当于beforeCreate() 和 created()
    */

    // 2、使用对应的钩子函数
    onBeforeMount( ()=>{
      console.log("------beforeMount-----");
    })

    onMounted( ()=>{
      console.log("------onMounted-----");
    })

    // 其他的都是一样的,就不写了,注意名字即可
  },

</script>



需要注意一个点:配置项写法和组合式API写法同时存在同一个钩子函数时

则:setup()中所用的组合式API写法比配置项写法优先执行




4.12、vue3中的 toRef 和 toRefs 数据拆分函数



1、使用toRef()函数交出单个数据

    <template>
      <h2>姓名: {{person.name}}</h2>
      <h2>性别: {{person.sex}}</h2>
      <h2>地址: {{person.address.value}}</h2>
      <!-- 上面这种方式并不好,简化 -->
      <br>
      <br>
      <h1>使用toRef和toRefs函数进行简化</h1> <br>
      <!-- 下面就可以直接简写了 -->
      <h2>姓名: {{name}}</h2>
      <h2>性别: {{sex}}</h2>
      <h2>地址: {{address}}</h2>
    </template>

    <script>
    // 1、组合式还是逃不开引入的问题
    import { reactive, toRef } from '@vue/reactivity'


    export default {
      name: 'App',

      setup() {
        let person = reactive({
          name: '紫邪情',
          sex: '女',
          address: {
            value: '浙江杭州'
          }
        })

        return {
          person,
          // 2、使用toRef()函数
          // 使用toRef函数交出单个数据
          /* 
            第一个参数: 交出的数据是哪个对象中的
            第二个参数: 要交出的是对象中的哪个属性
          */
          name: toRef(person,'name'),
          sex: toRef(person,'sex'),
          // 这里需要注意一下:要交出的对象里面又套娃了,那么:第一个参数需要再进一步
          address: toRef(person.address,'value'),
        }
      },
    }
    </script>

image



2、使用toRefs()函数

    <template>
      <h2>姓名: {{person.name}}</h2>
      <h2>性别: {{person.sex}}</h2>
      <h2>地址: {{person.address.value}}</h2>
      <!-- 上面这种方式并不好,简化 -->
      <br>
      <br>
      <h1>使用toRefs函数进行简化</h1> <br>
      <!-- 下面就可以直接简写了 -->
      <h2>姓名: {{name}}</h2>
      <h2>性别: {{sex}}</h2>
      <!-- 但是:美中不足就是,这里是里面套的娃,所以还得需要xxx.xxx一下 -->
      <h2>地址: {{address.value}}</h2>
    </template>

    <script>
    // 1、组合式还是逃不开引入的问题
    import { reactive, toRefs } from '@vue/reactivity'


    export default {
      name: 'App',

      setup() {
        let person = reactive({
          name: '紫邪情',
          sex: '女',
          address: {
            value: '浙江杭州'
          }
        })

        return {
          person,
          // 利用toRef()交出数据,需要写多次toRef,所以还是不喜欢,那就用toRefs()函数
          /* 
            直接说要交出哪个对象即可
            注意点:return{}是一个对象,所以:使用toRefs就是对象中套对象,因此注意写法
          */
          ...toRefs(person)
        }
      },
    }
    </script>

image



现在回过来看一下,为什么通过toRef() 和 toRefs()函数可以做到数据简化

使用toRef()举例,去看一下它长什么样子? - toRefs()函数是一样的原理

	console.log( toRef(person,'name') );

image



4.12.1、vue3的toRef() 和 toRefs()函数总结

标签:name,reactive,setup,更新,person,完毕,vue3,ref,函数
来源: https://www.cnblogs.com/xiegongzi/p/15875530.html