setup 定义响应式数据

1.setup定义响应式数据(ref单值)

 <script src="https://unpkg.com/vue@next"></script>
 <body>
   <div id="app">
     <h3>setup-ref响应式</h3>
     <p>希望这里返回的b是响应式的</p>
     a:{{a}} - b: {{b}}
     <button @click="f">f</button>
     <button @click="f1">f1</button>
   </div>
   <script>
     const { createApp, ref } = Vue
     const app = createApp({
       data() {
          return {
            a: 1
          }
       },
       setup() {
        // 希望这里返回的b是响应式的:改了b的值,页面也会更新
        // ref: 会对基础数据进行包装
        // 它其实是用proxy代理了一个对象  `{ value: 0 }`
        const b = ref(0)
        const f1 = () => { b.value = 200}
        return { b , f1  }
       },
       methods: {
         f () {
           // 这里不能写this.b.value
           this.b = 100
         }
       }
      })
     app.mount("#app")
</script>

如果希望在setup中返回具有响应式效果的数据,你可以用ref函数对数据进行处理。具体步骤:

在setup中返回一个ref()处理的数据

在视图中正常用插值{{b}}(不需要加.value)

如果要修改这个值,有两种方式:

1) 在setup中暴露一个函数,直接去修改.value

2) 在methods中定义一个方法,在此方法的内部通过this.XX=新值来修改

2.setup 定义响应式数据(reactive对象)

<script src="https://unpkg.com/vue@next"></script>
 <body>
   <div id="app">
     <h3>setup-reactive响应式</h3>
     <p>希望这里返回的复合数据-obj是响应式的</p>
    obj.b: {{obj.b}},  obj.arr:{{obj.arr}}
     <button @click="f">f</button>
     <button @click="f1">f1</button>
     <button @click="f2">f2</button>
   </div>
   <script>
   const { createApp, reactive } = Vue
   const app = createApp({
     data() {
        return {
        }
     },
     setup() {
      // reactive: 会对对象进行包装
      const obj = reactive({b: 1, arr: [1,2]})
      const f1 = () => { obj.b = 200 }
      const f2 = () => { obj.arr.push(3)}
      return { obj, f1, f2  }
     },
     methods: {
       f () {
         this.obj.b = 100
       }
     }
    })
   app.mount("#app")
</script>
</body>

步骤:

  1. 在setup中返回一个reactive()处理的对象obj

  2. 在视图中正常用插值,但是要加上obj.

  3. 如果要修改这个值,有两种方式:

    1) 在setup中暴露一个函数,直接去修改 

    2) 在methods中定义一个方法,在内部通过this.ojb.XX=新值 来修改

  4. setup 返回响应式数据(reactive对象+toRefs)

    上面的例子,我们需要用{{obj.b}}这种方式在视图中渲染数据,下面我们来优化一下,通过引入toRefs包装一个这个对象,然后再展开,就可以省略obj这个前缀了

    <script src="https://unpkg.com/vue@next"></script>
     <body>
       <div id="app">
         <h3>setup-ref响应式</h3>
         <p>希望这里返回的复合数据-obj是响应式的</p>
        obj.b: {{b}},  obj.arr:{{arr}}
         <button @click="f">f</button>
         <button @click="f1">f1</button>
         <button @click="f2">f2</button>
       </div>
       <script>
        // vue3中提供一个概念:组合api
         const { createApp, reactive, toRefs } = Vue
         const app = createApp({
           data() {
              return {
              }
           },
          //  步骤:
          //  1. 在setup中返回一个reactive()处理的对象obj
          //  2. 在视图中正常用插值,但是要加上obj.
          //  3. 如果要修改这个值,有两种方式:
          //   1) 在setup中暴露一个函数,直接去修改
          //   2) 在methods中定义一个方法,在内部通过this.XX=新值来修改
           setup() {
            // reactive: 会对对象进行包装
            // 它其实是用proxy代理了这个对象,只是第一个级别,所以不能直接解构
            // 如果直接解构,就失去了响应式的特性了
            // 这里再用toRefs来包装一下
            const obj = reactive({b: 1, arr: [1,2]})
            const f1 = () => { obj.b = 200}
            const f2 = () => { obj.arr.push(3)}
            return { ...toRefs(obj), f1, f2  }
           },
           methods: {
             f () {
               this.b = 100
             }
           }
          })
         app.mount("#app")
    </script>
    </body>

     

posted @ 2022-05-11 11:59  青柠~  阅读(271)  评论(0)    收藏  举报