登录
原创

vue-ref及reactive响应式

发布于 2021-11-29 阅读 551
  • 前端
  • Vue.js
原创

页面渲染后,如果数据发生改变,页面跟着动态更新,可以使用 ref及reactive

ref及reactive都需要先从 Vue 对象中解构赋值,然后使用

ref- - - 操作普通类型数据

// 获取 ref
const { ref } = Vue

// 使用 ref
let 变量名 = ref('变量值')

代码示例:

<!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>ref reactive响应式</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    template: `
    <div>国王排名</div>
    <div>{{ name }}</div>
    `,
    // setup函数 需要返回一个对象
    setup(options, context) {
      const {ref} = Vue
      let name = ref('波吉')
      setTimeout(() => {
        name.value = '卡克'
      }, 3000)
      return {name}
    }
  })
  const vm = app.mount('#root')
</script>
</html>

页面效果:

ref.gif

3秒后名称自动变化

reactive- - -操作对象类型数据

使用方法:

// 获取 reactive 
const { reactive } = Vue

// 使用 reactive 
let 对象名 = reactive({ 属性: '属性值' })

代码示例:

<!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>ref reactive响应式</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    template: `
    <div>国王排名</div>
    <div>{{ nameObj.name }}</div>
    `,
    setup(options, context) {
      const { reactive } = Vue
      let nameObj = reactive({ name: '波吉' })
      setTimeout(() => {
        nameObj.name = '卡克'
      }, 3000)
      return { nameObj }
    }
  })
  const vm = app.mount('#root')
</script>
</html>

页面效果:

reactive.gif

如果是更改数组的数据:

代码示例(数组):

<!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>ref reactive响应式</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    template: `
    <div>国王排名</div>
    <div>{{ num[0] }}</div>
    `,
    setup(options, context) {
      const { reactive } = Vue
      let num = reactive([222])
      setTimeout(() => {
        num[0] = 666
      }, 3000)
      return { num }
    }
  })
  const vm = app.mount('#root')
</script>
</html>

页面效果:

reactive数组.gif

对象解构赋值后,返回变量响应式- - -toRefs

// 获取 toRefs 
const { toRefs } = Vue

// 使用 toRefs 
const { 变量名1, 变量名2 } = toRefs(对象名)

代码示例:

<!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>ref reactive响应式</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    template: `
    <div>国王排名</div>
    <div>{{ name1 }}</div>
    <div>{{ name2 }}</div>
    `,
    // setup函数 需要返回一个对象
    setup(options, context) {
      const { reactive, toRefs } = Vue
      let nameObj = reactive({name1: '波吉', name2: '卡克'})
      setTimeout(() => {
        nameObj.name1 = '波吉王子'
        nameObj.name2 = '卡克侍卫'
      }, 3000);
      // return { name1, name2 } = nameObj
      // 对象解构赋值,要加 toRefs方法才能动态更新 proxy({name1: '波吉', name2: '卡克'})
      // 变成了 name1: proxy({value: '波吉'})   name2: proxy({value: '卡克'})
      const { name1, name2 } = toRefs(nameObj)
      return { name1, name2 }
    }
  })
  const vm = app.mount('#root')
</script>
</html>

页面效果:

reactive结构赋值.gif

设置响应式,不存在该字段的话,创建该字段,值为空- - -toRef

使用toRefs时,如果没有找到字段,则该字段值为 undefined,不可以修改该字段值,会报错

使用toRef的话,如果没有找到字段,会创建该字段,值为 null

代码示例(toRefs):

<!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>toRef</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    template: '<div>{{ name1 }}</div><div>{{ name2 }}</div>',
    setup(options, context) {
      const { reactive, toRefs, toRef } = Vue
      const nameObj = reactive({name1: '波吉'})
      const { name1 } = toRefs(nameObj)
      const { name2 } = toRefs(nameObj)  // 在nameObj里面尝试取 name2 的数据,没有取到的话,是 undefined
      setTimeout(() => {
        nameObj.name1 = '波吉王子'
        name2.value = '卡克侍卫'
      }, 3000);
      return { name1, name2 }
    }
  })
  const vm = app.mount('#root')
</script>
</html>

页面效果:

reactivetoRefs.gif

代码示例(toRef):

<!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>toRef</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  const app = Vue.createApp({
    template: '<div>{{ name1 }}</div><div>{{ name2 }}</div>',
    setup(options, context) {
      const { reactive, toRefs, toRef } = Vue
      const nameObj = reactive({name1: '波吉'})
      const { name1 } = toRefs(nameObj)
      const name2 = toRef(nameObj, 'name2')  // 在nameObj里面尝试取 name2 的数据,没有取到的话给一个 name2 数据为空
      setTimeout(() => {
        nameObj.name1 = '波吉王子'
        name2.value = '卡克侍卫'
      }, 3000);
      return { name1, name2 }
    }
  })
  const vm = app.mount('#root')
</script>
</html>

页面效果:

reactivetoRef.gif

没有报错,正常显示了

小提示:对象中不建议使用没有定义的字段,要使用的话还是先定义

不想页面值被更改- - readonly

  setup(options, context) {
      // 不想值被更改,可以用 readonly
      const { reactive, readonly } = Vue
      let num = reactive([222])
      let numCopy = readonly(num)
      setTimeout(() => {
        num[0] = 666
        numCopy[0] = 666
      }, 3000)
      return { num, numCopy }
    }

尝试更改numCopy,会有提醒- - -不可更改:

image.png?x-oss-process=style/thumb

评论区

零00
7粉丝

时光荏苒,我自清欢

0

0

0

举报