前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue3 day03

vue3 day03

作者头像
花花522
发布2023-03-07 16:05:59
2060
发布2023-03-07 16:05:59
举报
文章被收录于专栏:花花爱咖啡

reactive对比ref

  • 从定义角度对比
    • ref用来定义:基本数据类型
    • reactive用来定义: 对象(或数组)类型数据
    • 备注: ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象
  • 从原理角度来对比
    • ref使用了是Object.defineProperty()getset来实现响应式(数据劫持)
    • reactive使用了es6的proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据
  • 从使用角度对比
    • ref定义的数据: 操作数据时需要使用.value,读取数据时模板中直接读取,不需要.value
    • reactive定义的数据: 操作数据与读取数据:均不需要.value

setup的两个注意点

  • setup执行的时机
    • 在beforeCreate之前执行一个,this是undefined
  • setup的参数
    • attrs: 值为对象,包含: 组件外部传递过来的,但是没有props配置中声明的属性,相当于this.$attrs
    • slots: 收到插槽的内容,相当于this.$slots
    • emit:分发自定义事件的函数,相当于this.$emit
    • props: 值为对象 包含:组件外部传递过来,且组件内部声明接收了的属性
    • context: 上下文对象

代码示例‍

代码语言:javascript
复制
<template>

  <demo msg="hello" word="花花" @testEmit="sayHello">
    <template v-slot:testSlot>
      <h2>花花</h2>
    </template>
  </demo>
</template>

<script>


import Demo from "@/components/Demo";

export default {
  name: 'App',
  components: {Demo},
  setup(){
    function sayHello(value) {
      alert(`我是emit的响应,我收到了${value}`)
    }
    return{sayHello

    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
代码语言:javascript
复制
<template>
  <h1>我是setup测试</h1>
  <h1>个人信息</h1>
  <h2>{{ person.name }}</h2>
  <h2>{{ person.age }}</h2>
  <button @click="sayHello">sayHello</button>
  <h2>职业:{{ person.job.jobs }}</h2>
  <h2>薪水:{{ person.job.salary }}</h2>
  <h2>爱好{{ person.hobby }}</h2>
</template>

<script>
import {reactive} from "vue";

export default {
  name: "Demo",
  props: {
    msg:String,
    word:String
  },
  emits:['testEmit'],
  setup(props, context) {
    console.log(`this是${this}`)
    console.log(props)//这里是接收到的属性
    console.log(context.attrs)//这里是未声明接收的属性
    console.log(context.slots) //这里是插槽


    let person = reactive({
      name: "花花",
      age: 18,
      job: {
        jobs: "前端开发工程师",
        salary: '3k'
      },
      hobby: ['游戏', '篮球', '花花']
    });

    function sayHello() {
      context.emit('testEmit','666')
    }

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

<style scoped>

</style>

计算属性与监听器

computed

  • 回顾vue2的计算属性
代码语言:javascript
复制
<template>
  <h1>个人信息</h1>
  <input v-model="person.firstName"/>
  <br>
  <input v-model="person.lastName"/>
  <h2>全名{{fullName}}</h2>
  <input v-model="fullName"/>
</template>

<script>
import {reactive} from "vue";

export default {
  name: "Demo",
    //这里是vue2的计算属性
  computed:{
    fullName:{
      get(){
        return this.person.firstName + '_' + this.person.lastName
      },
      set(value){
        const fullNameArr = value.split('_');
        this.person.firstName = fullNameArr[0];
        this.person.lastName = fullNameArr[1];
      }
    }
  },
  setup(props, context) {
    console.log(`this是${this}`)
    // console.log(props, context)
    console.log(props)//这里是接收到的属性
    console.log(context.attrs)//这里是未声明接收的属性
    console.log(context.slots) //这里是插槽


    let person = reactive({
      firstName: "爱",
      lastName:'花花',
      age: 18
    });


    return {
      person
    }
  }
}
</script>

<style scoped>

</style>
  • vue3使用计算属性
代码语言:javascript
复制
<template>
  <h1>个人信息</h1>
  <input v-model="person.firstName"/>
  <br>
  <input v-model="person.lastName"/>
  <h2>全名{{ person.fullName }}</h2>
  <input v-model="person.fullName"/>
</template>

<script>
import {computed, reactive} from "vue";

export default {
  name: "Demo",
  setup(props, context) {
    console.log(`this是${this}`)
    // console.log(props, context)
    console.log(props)//这里是接收到的属性
    console.log(context.attrs)//这里是未声明接收的属性
    console.log(context.slots) //这里是插槽


    let person = reactive({
      firstName: "爱",
      lastName: '花花',
      age: 18
    });
    //简写
    person.fullName = computed(()=>{
      return person.firstName + '_' + person.lastName

    })
    //完整写法
    person.fullName = computed({
      get(){
          return person.firstName + '_' + person.lastName
      },
      set(value){
        const fullNameArr = value.split('_')
        person.firstName = fullNameArr[0]
        person.lastName = fullNameArr[1]
      }
    })


    return {
      person
    }
  }
}
</script>

<style scoped>

</style>

watch

  • vue2
代码语言:javascript
复制
<template>
  <h1>求和结果是{{ sum }}</h1>
  <button @click="sum++">计算+1</button>
</template>

<script>
import {ref} from "vue";

export default {
  name: "Demo",
  watch: {
     //两种写法 1,完全写法
    sum: {
      immediate: true,
      handler(newValue, oldValue) {
        console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)
      }
    }

      //写法二 简略写法
    /*    sum(newValue, oldValue){
          console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)

        }*/
  },
  setup() {
    let sum = ref(0);

    return {
      sum
    }
  }
}
</script>

<style scoped>

</style>
  • vue3
代码语言:javascript
复制
<template>
  <h1>求和结果是{{ sum }}</h1>
  <button @click="sum++">计算+1</button>
  <br>
  <h3>msg为{{msg}}</h3>
  <button @click="msg+='!'">修改msg</button>
</template>

<script>
import {ref, watch} from "vue";

export default {
  name: "Demo",

  setup() {
    let sum = ref(0);
    let msg = ref("我是msg");

    /*写法一 监听ref定义的单个数据*/
    // watch(sum, (newValue, oldValue) => {
    //   console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)
    // }, {
    //   immediate:true
    // })

    /*写法二 监听ref定影的多个数据,newValue和oldValue是数组*/
    watch([sum,msg], (newValue, oldValue) => {
      console.log(newValue)
      console.log("sum/msg修改了,之前是",newValue,"修改后是",oldValue)
    }, {
      immediate:true
    })

    return {
      sum,msg
    }
  }
}
</script>

<style scoped>

</style>

watch的总结

  • 使用和配置和vue2基本一样
  • 有坑的几个地方
    • 当watch监听的是reactive的响应式对象的时候,获取不到oldValue
    • 当watch监听的是reactive的响应式对象的时候,强制开启deep:true,不能关闭
  • 监视reactive中的某个属性时 deep 有效
代码语言:javascript
复制
<template>
 <h1>求和结果是{{ sum }}</h1>
 <button @click="sum++">计算+1</button>
 <br>
 <h3>msg为{{ msg }}</h3>
 <button @click="msg+='!'">修改msg</button>

 <br>
 <h2>姓名:{{ person.name }}</h2>
 <h2>年龄:{{ person.age }}</h2>
 <h2>薪资:{{ person.job.j1.salary }}</h2>


 <button @click="person.age++">增加年龄</button>
 <button @click="person.name+='~'">增加姓名</button>
 <button @click="person.job.j1.salary++">涨薪</button>
 <button @click="person.job.j1.aaa[0] = 10 ">测试监听reactive中的数组</button>
</template>

<script>
import {reactive, ref, watch} from "vue";

export default {
 name: "Demo",

 setup() {
   let sum = ref(0);
   let msg = ref("我是msg");
   let person = reactive({
     name: '花花',
     age: 20,
     job: {
       j1: {
         salary: 20,
         aaa:[1,2,3,4]
      }
    }
  })

   /*情况一 监听单个数据*/
   // watch(sum, (newValue, oldValue) => {
   //   console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)
   // }, {
   //   immediate:true
   // })

   /*情况二 监听多个数据,newValue和oldValue是数组*/
   /* watch([sum,msg], (newValue, oldValue) => {
      console.log(newValue)
      console.log("sum/msg修改了,之前是",newValue,"修改后是",oldValue)
    }, {
      immediate:true
    })*/

   /*
  * 情况三 检测reactive数据
  *   问题:
  *     1.无法获取到oldValue
  *     2.强制开启了deep:true,并且不能关闭
  * */
   /* watch(person, (newValue, oldValue) => {
      console.log("person修改了,之前是",newValue,"修改后是",oldValue)
    }, {
      immediate:true
    })*/

   /*情况四 想要监听reactive中的,某一个属性*/
   /* watch(()=>person.age, (newValue, oldValue) => {
      console.log("person修改了,之前是",newValue,"修改后是",oldValue)
    }, {
      immediate:true
    })*/

   /*情况5 想要监听reactive中的,某一个对象属性,需要开启deep*/
   watch(() => person.job, (newValue, oldValue) => {
     console.log("person修改了,之前是", newValue, "修改后是", oldValue)
  }, {
     immediate: true,
     deep: true
  })
   return {
     sum, msg, person
  }
}
}
</script>

<style scoped>

</style>
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 花花爱咖啡 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • reactive对比ref
  • setup的两个注意点
  • 计算属性与监听器
    • computed
      • watch
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档