vue3 新特性

1、setup

setup是vue3定义的代码实现舞台。需要在模板中使用的变量和方法,需要return。

setup执行顺序在beforeCreat,并且在setup中this为undefined

setUp(props, contex)接受两个参数

props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性(其实就是vue2.0的props功能)
context:上下文对象(其中可以获取到1、attrs组件外部传递过来,但没有在props配置中声明的属性。2、slots:插槽内容3、emit:分发自定义事件的函数,并且以后在setup中不能写this.$emit,要写context.emit)

<template>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <button @click="sayInfo">显示信息</button>
</template>

<script>
export default {
  name: "App",
  setup(){
      //此时的数据不具有双向绑定的功能
    let name:string = "小明"
    let age:number = 18

    // 方法
    function sayInfo(){
      alert(`你好${name},你太厉害了吧`)
    }
    // 想要在模板中使用setup中的方法或者数据,必须return
    return {
      name,age, sayInfo
    }
     // return ()=> h('h1','试试')
  }
};
</script>

setup另外一种写法是直接写到script标签中:<script setup>

2、ref()

定义一个响应式的变量。let name:string = ref(‘test’)

js操作变量的方法是name.value,模板中直接{{name}}

<template>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <button @click="changeInfo">修改信息</button>
</template>

<script>
import { ref } from "vue";
export default {
  name: "App",
  setup() {
    // 数据
    let name:string = ref("小明");
    let age:number = ref(18);
    // 方法
    function changeInfo() {
      name.value = "小明";
      age.value = 48;
    }
    return {
      name,
      age,
      changeInfo,
    };
  },
};
</script>

3、reactive()

用来定义响应式对象:let obj=reactive({a:1,b:2})

js操作方法是obj.a=2(不需要.value)

<template>
  <h2>姓名:{{ yk.name }}</h2>
  <h2>年龄:{{ yk.age }}</h2>
  <h2>爱好:{{ yk.hobby }}</h2>
  <h3>测试数据:{{ yk.job.a.b.c }}</h3>
  <button @click="changeInfo">修改信息</button>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
  setup() {
    // 数据
    let yk = reactive({
      age: 18,
      hobby: ["吃饭", "睡觉", "打豆豆"],
      job: {
        a: {
          b: {
            c: 666,
          },
        },
      },
    });

    // 方法
    function changeInfo() {
      yk.age = 48;
      yk.job.a.b.c = 888;
      // 直接通过数组下标修改,可以触发响应式
      yk.hobby[0] = "打豆豆";
    }
    return {
      yk,
      changeInfo,
    };
  },
};
</script>

4、计算属性computed

功能和vue2一样,写法稍有不同

<template>
  姓:<input v-model="person.firstName"></input>
 名: <input  v-model="person.lastName"></input>
  姓名:<input  v-model="person.fullName"></input>
</template>

<script>
//先引入
import {computed,reactive } from 'vue'
export default {
  name: "App",
  setup() {
      let person = reactive({
        firstName :"小",
        lastName:"明",
        fullName:""
    })
    //计算属性 —— 简写
    //let fullName = computed(()=>{
       // return person.firstName + '-' + person.lastName
    //})
    //计算属性 —— 完整
    person.fullName = computed({
        get(){
            return person.firstName + '-' + person.lastName
        },
        set(value){
            const nameArr = value.split('-')
            person.firstName = nameArr[0]
            person.lastName = nameArr[1]
        }
    })
    return {
     person
    };
  },
};
</script>

5、v-model

之前:v-model="msg" msg.sync=""
现在:v-model:value="msg"

6、计算属性watch

和计算属性差不多,在vue3中和只是语法上上的改变。

注意:

1、监视ref定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)

2、监视reactive定义的响应式数据中某个属性时(这个属性需是对象):deep配置有效

//情况一:监视ref定义的响应式数据
watch(sum,(newValue,oldValue)=>{
    console.log('sum变化了',newValue,oldValue)
})
//如果用ref定义了一个对象
watch(person.value,(newValue,oldValue)=>{
    console.log('person变化了',newValue,oldValue)
})
 
//情况二:监视多个ref定义的响应式数据
watch([sum,msg],(newValue,oldValue)=>{
    console.log('sum或msg变化了',newValue,oldValue)
}) 
//情况三:监视reactive定义的响应式数据
watch(person,(newValue,oldValue)=>{
    console.log('person变化了',newValue,oldValue)
},{immediate:true,deep:false}) //此处的deep配置不再奏效

//情况四:监视reactive定义的响应式数据中的某个属性
watch(()=>person.job,(newValue,oldValue)=>{
    console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true}) 

//情况五:监视多个reactive定义的响应式数据中的某些属性
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
    console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true})

//特殊情况
//person.job中的job也是一个对象
watch(()=>person.job,(newValue,oldValue)=>{
    console.log('person的job变化了',newValue,oldValue)
},{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效

7、watchEffect函数

watch是:既要指明监视的属性,也要指明监视的回调。
watchEffect是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
这个函数的功能和计算属性差不多,但是:

但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。

而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
    const x1 = sum.value
    const x2 = person.age
    console.log('watchEffect配置的回调执行了')
})

8、生命周期

1、vue3.0中可以继续使用vue2.x中的生命周期钩子,但是有两个被更名:

beforeDestroy改成beforUnmount
destroyed改成 unmounted
2、vue3.0也提供了composition API形式的生命周期钩子,与vue2.x钩子对应关系如下:

beforeCreate======>setup()
created==========>setup()
beforeMount======>onBeforeMount
mounted=========>onMounted
beforeUpdate=====>onBeforeUpdate
updated =========>onUpdated
beforeUnmount ===>onBeforeUnmount
unmounted ======>onUnmounted

9、自定义hook函数

自定义hook的优势:复用代码,让setup中的逻辑更清晰。

book函数point.js:

import { reactive, onMounted, onBeforeUnmount } from "vue";
export default function() {
    //实现鼠标“打点”相关的数据
    let point = reactive({
        x: 0,
        y: 0,
    });

    //实现鼠标“打点”相关的方法
    function savePoint(event) {
        point.x = event.pageX;
        point.y = event.pageY;
        console.log(event.pageX, event.pageY);
    }

    //实现鼠标“打点”相关的生命周期钩子
    onMounted(() => {
        window.addEventListener("click", savePoint);
    });

    onBeforeUnmount(() => {
        window.removeEventListener("click", savePoint);
    });

    return point;
}

页面中使用:

<template>
<h2>当前点击时鼠标的坐标为:x:{{point.x}},y:{{point.y}}</h2>
</template>

<script>
  import usePoint from '../hook/point.js'
  export default {
    name:'HelloWorld',
    setup(){
      const point = usePoint()
      return {point}
    }
  }
</script>

10、toRef和toRefs

语法:const name = toRef(person,‘name’)应用: 要将响应式对象中的某个属性单独提供给外部使用时。

扩展:toRefs与toRef功能一致,但可以批量创建多个 ref 对象,

语法:toRefs(person)

<template>
    <h4>{{person}}</h4>
    <h2>姓名:{{name}}</h2>
    <h2>年龄:{{age}}</h2>
    <h2>薪资:{{job.j1.salary}}K</h2>
    <button @click="name+='~'">修改姓名</button>
    <button @click="age++">增长年龄</button>
    <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
    import {ref,reactive,toRef,toRefs} from 'vue'
    export default {
        name: 'HelloWorld',
        setup(){
            let person = reactive({
                name:'张三',
                age:18,
                job:{
                    j1:{
                        salary:20
                    }
                }
            })
            
            // const name1 = person.name
            // console.log('%%%',name1)

            // const name2 = toRef(person,'name')
            // console.log('####',name2)

            const x = toRefs(person)
            console.log('******',x)

            return {
                person,
                // name:toRef(person,'name'),
                // age:toRef(person,'age'),
                // salary:toRef(person.job.j1,'salary'),
                ...toRefs(person)
            }
        }
    }
</script>

 

 

 

参考教程连接:https://blog.csdn.net/webtext/article/details/123061587

 

posted @ 2022-06-06 16:40  JackGIS  阅读(70)  评论(0编辑  收藏  举报