Vue3:ref函数和reactive函数和setup函数

ref基本用法

复制代码
ref函数
作用:定义一个响应式的数据
语法:const xxx = ref(initValue),创建一个包含响应式数据的引用对象(reference对象简称ref对象)
备注:
1. 基本数据类型:响应式依然是靠Object.defineProperty()的get和set完成的
2. 对象数据类型:内部求助了Vue3.0中的一个新函数 ==> reactive函数

处理基本类型和对象类型
<template>
  <div>{{ name }}</div>
  <div>{{ age }}</div>
  <div>{{ job.industry }}</div>
  <div>{{ job.salary }}</div>
  <button @click="change">按钮</button>
</template>

<script>
import { ref } from 'vue'
export default {
  name: 'App',
  setup() {
    let name = ref('张三')
    let age = ref(18)
    let job = ref({
      industry: '前端',
      salary: '30k'
    })
    function change() {
      console.log(name, age);
      name.value = '李四'
      age.value = 28
      job.value.industry = 'UI'
      job.value.salary = '60K'
    }

    return {
      name,
      age,
      job,
      change
    }
  }
}
</script>

reactive基本用法

复制代码
reactive函数
作用:定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
语法:const 代理对象 = reactive(源对象)接收一个对象或数组,返回一个代理对象(proxy对象)
reactive定义的响应式数据是深层次的
内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作

代码:
<template>
  <div>{{ person.name }}</div>
  <div>{{ person.age }}</div>
  <div>{{ person.job.industry }}</div>
  <div>{{ person.job.salary }}</div>
  <button @click="change">按钮</button>
</template>

<script>
import { reactive } from 'vue'
export default {
  name: 'App',
  setup() {
    const person = reactive({
      name: '张三',
      age: 18,
      job: {
        industry: '前端',
        salary: '30k'
      }
    })

    function change() {
      person.name = '李四'
      person.age = 28
      person.job.industry = 'UI'
      person.job.salary = '60K'
    }

    return {
      person,
      change
    }
  }
}
</script>

ref和reactive对比

复制代码
从定义数据角度对比:
1. ref用来定义:基本数据类型
2. reactive用来定义:对象或数字类型数据
3. 备注:ref也可以用来定义对象或数组类型数据,它内部会自动通过reactive转为代理对象

从原理角度对比:
1. ref通过Object.defineProperty()的get和set来实现响应式(数据劫持)
2. reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据

从使用角度对比:
ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
reactive定义的数据:操作数据和读取数据:均不需要.value

setup两个注意点

复制代码
setup的两个注意点:

1. setup执行的时机
在beforeCreate之前执行一次,this是undefined

2. setup的参数:即setup(props, context){}
props:值为对象,包含组件外部传递过来,且组件内部声明接收了的属性
context:上下文对象
    attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs
    slots: 收到的插槽内容,相当于this.$slots
    emit:分发自定义事件的函数,相当于this.$emit





具体案例:

1. App.vue:

<template>
  <DemoComponent @hello="sayHello" sex="男">
    <template v-slot:about>
      <div>关于</div>
    </template>
    <template v-slot:some>
      <div>一些</div>
    </template>
  </DemoComponent>
</template>

<script>
import DemoComponent from './components/DemoComponent'

export default {
  name: 'App',
  components: { DemoComponent },
  setup() {
    function sayHello() {
      console.log('我通过emit触发拉');
    }
    return {
      sayHello
    }
  }
}
</script>


2. DemoComponent.vue:

<template>
  <div>{{ person.name }}</div>
  <div>{{ person.age }}</div>
  <div>{{ sex }}</div>
  <button @click="handleClick">按钮</button>

  <slot name="about" />
  <slot name="some" />
</template>

<script>
import { reactive } from 'vue'

export default {
  name: 'DemoComponent',
  props: ['sex'],
  emits: ['hello'],
  setup(props, context) {
    console.log(props, 'props', context.slots);
    
    const person = reactive({
      name: '张三',
      age: 19,
    })

    function handleClick() {
      context.emit('hello', 1, 2, 3)
    }
    return {
      person,
      handleClick
    }
  }
}
</script>
相关推荐
秃头网友小李3 天前
前端难点:keep-alive 缓存什么?RouterView 的 key 为什么要带 scopeId?
前端·vue.js
徐小夕3 天前
JitWord 3.0 正式发布,高精度Word异构解析+复杂组件兼容,打造web端协同Word编辑器
前端·vue.js·算法
奋斗吧程序媛4 天前
补充一个小知识点:有关@click.native
前端·vue.js
英勇无比的消炎药4 天前
一行命令背后:TinyRobot CLI 如何重构 AI 对话接入的效率范式
vue.js·aigc
jay神4 天前
基于 FastAPI + Vue 的宠物领养管理系统
前端·vue.js·python·毕业设计·fastapi·宠物
一杯奶茶¥4 天前
水果销售网站 CRM客户信息管理系统 超市管理系 酒店管理系统 健身房管理系统 在线音乐网站 校园招聘系统
java·vue.js·spring boot·mysql·spring·java项目
英勇无比的消炎药4 天前
一站式搞定品牌风格:TinyRobot 主题定制从入门到精通
vue.js
尽欢i4 天前
Vue3 customRef 封神教程:防抖、本地存储、自动埋点一套搞定,模板干干净净
前端·javascript·vue.js
因_崔斯汀4 天前
Vue 模板编译:HTML 是怎么变成 JS 的?
前端·vue.js
英勇无比的消炎药4 天前
样式随心定制:TinyRobot 样式覆写与 CSS 变量实战解析
vue.js