vue3.0基础学习

vue3 中的setup

vue3中所有的属性、方法、生命周期等皆定义在setup函数中,可以说setup是vue3中组合api的入口函数

vue3中使用内置的api需要引入

import { ref } from 'vue'

ref

定义一个响应式的简单数据类型(Number,String)

// 模板
<template>
    <h3>
    {{ name }}
  </h3>
    <button @cilck="changeName">点我改变姓名</button>
</template>
import { ref } from 'vue'
export defaule {
    name: 'App',
    setup() {
        let name = ref('张三') // 定义一个响应式的变量
    
    // 定义方法
    function changeName() {
      name.value = '李四' // ref包装后的值,访问必须通过 .value
    }
    // 在vue3中定义的变量,函数模板中使用setup函数必须返回
    return {
      name,
      changeName
    }
    }
}

reactive

定义一个复杂的响应式数据类型(Object,Array)

// 模板
<template>
    <h3>
    {{ person.name }}
  </h3>
    <button @cilck="changeName">点我改变姓名</button>
</template>
import { reactive } from 'vue'
export defaule {
    name: 'App',
    setup() {
    // 定义一个响应式的person对象
        let person = reactive({
      name: '张三',
      age: 25
    }) 
    
    // 定义方法
    function changeName() {
      person.name = '李四' // reactive包装后的值,可以直接点属性名访问
    }
    // 在vue3中定义的变量,函数模板中使用setup函数必须返回
    return {
     person
    }
    }
}

备注:

ref:用来定义简单类型的响应式数据

reactive: 用来定义复杂的响应式数据,不管嵌套多深vue都可以监测到数据变化

如果用reactive定义简单的数据类型,该数据被改变时将不会触发页面更新,也就是说该数据不是响应式的

vue3 响应式原理

vue3内部借助了Proxy拦截对源对象属性的改变(增删改查)

通过Reflect(反射) 改变源对象的值

// 源对象
let person = {
    name: '张三',
    age: 18
}
// Proxy 接收两个参数,第一个是target代理的目标对象,第二个是实现增删改查的对象
let p = new Proxy(person, {
  // 读取属性值,target目标对象,propName是读取的该对象中属性名
    get(target, propName) {
    // return target[propName]
        return Reflect.get(target,propName)
    },
  // 修改和新增时会触发set方法
  set(target, propName, value) {
    // return target[propName] = value
    return Reflect.set(target, propName, value)
  },
  // 删除时触发
  deleteProperty(target, propName) {
    // return delete target[propName]
    return Reflect.deleteProperty(target, propName)
  }
})

setup函数注意点

1.setup执行的时机是在beforeCreate()之前

2. setup函数接收两个函数

// props,父组件传进来的参数
// context 上下文对象包含了,attrs/emit/slots
props: ['msg']// 子组件必须声明,否则会报警告
setup(props, context) {
  
}

vue3中的computed计算属性

import { reactive, computed } from 'vue'
export default {
  setup() {
    let person = reactive({
      firstName:'张',
      lastName: '三'
    })
    // 简写形式
    let fullName = computed(()=>{
      return person.firstName + person.lastName
    })
    // 完整写法
    let fullName = computed({
      get() {
        return person.firstName + person.lastName 
      },
      set(value) {
        person.firstName = value
        person.lastName  = value
      }
    })
    return {
      fullName
    }
  }
}

vue3中的watch函数

import { ref, watch, reactive } from "vue";
export default {
  setup() {
    let sum = ref(0);
    let msg = ref("你好");
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        address: "长沙",
        hobby: {
          number: "篮球"
        }
      }
    });
    // 以下是监听ref包装的简单数据
    // 情况一,简单监听, vue3中watch是一个函数
    // watch(sum, (newValue, oldValue) => {
    //   console.log(newValue, oldValue);
    // });

    // 情况二 vue3中watch监听多个值
    // watch([sum, msg], (newValue, oldValue) => {

    //   console.log(newValue, oldValue);//[0, "你好!"] [0, "你好"]
    // });

    //情况三, 开启监听的配置项
    // watch(sum, (newValue, oldValue) => {
    //   console.log(newValue, oldValue)
    // }, {
    //   immediate: true, // 监听的值没有改变页面已加载就触发一次
    //   deep: true // 开启深度监听
    // })
    /* 
      watch监听reactive响应式数据
      // 情况1 默认强制开始深度监听deep,无法改变。且监测不到oldValue
    */
    //  watch(person, (newValue, oldValue) => {
    //    console.log(newValue, oldValue)
    //  })
    /* 
      watch监听reactive响应式数据
      // 情况2 想要监听对象中某一个值,第一个参数必须是一个函数且要返回要监听的属性
    */
    // watch(
    //   () => person.name,
    //   (newValue, oldValue) => {
    //     console.log(newValue, oldValue)
    //   }
    // );
    /* 
      watch监听reactive响应式数据
      // 情况3 想要监听对象中某一个属性时,且该属性是又是一个对象,需要开启deep才能生效
    */
    watch(
      () => person.job,
      (newValue, oldValue) => {
        console.log(newValue, oldValue)
      },
      { deep: true }
    );
    return {
      sum,
      msg,
      person
    };
  }
}
  

vue3中的watchEffect函数

  1. 该函数也用于监听,和watch不同的是,该函数参数只有一个回调函数,监听的对象取决于回调函数中所用到的有哪些属性

  2. 该函数和computed属性有些类似,不同点在于computed属性必须有返回值,注重的是返回的结果。watchEffect函数没有返回值,注重的是函数执行时的逻辑过程。

import { reactive,watchEffect } from "vue";
export default {
  setup() {
    let sum = ref(0);
    let msg = ref("你好");
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        address: "长沙",
        hobby: {
          number: "篮球"
        }
      }
    });
    // 只有一个参数回调函数,监听取决于回调函数中用到的属性。sum和hobby改变会被监听到
    watchEffect(() =>{
      const x1 = sum.value
      const x2 = person.job.hobby.number
    })
    return {
      person
    };
  }
}
  

vue3 生命周期

和vue2相比vue3生命周期函数有两个改变

1. beforeDestroy >>> beforeUnmount // 卸载之前

2. destroyed >>> unmounted // 卸载之后

组合API中使用生命周期函数

import {  onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted } from "vue";
export default {
  setup() {
   onBeforeMount(()=>{
    console.log("挂在之前")
   })
   onMounted(()=>{
    console.log("挂在之后")
   })
  }
}

备注:

  1. 在setup函数中使用钩子函数,名称有所改变如上所示。
  2. 之前的配置项写法生命周期依然可用,两种写法同时存在时,组合API中的写法优先级高!但不建议两种写法同时存在!
  3. 组合API中beforeCreate、created => setup()

vue3中的toRef/toRefs

作用:把一个对象或者属性转变为ref响应式数据

语法:toRef(person,'name')

toRefs,批量转换,同时把多个转换为ref类型

语法:toRefs(person),转换后为一个对象,使用时通过 ...toRefs(person)展开

vue3中的shallowReactive/shallowRef

shallowReactive: 定义复杂数据对象时,只有第一层数据是响应式的,里面嵌套的数据改变不会响应。

shallowRef: 定义数字类型数据是响应式的,定义对象数据类型时,不是响应式的,数据改变但页面不会响应。

vue3 中的readonly/shallowReadonly

let person = reactive({
  name: '张三'
  hobby: {
    sports:'篮球'
    }
})

const person1 = readonly(person)
return { person1 }

作用: 把一个响应式的数据变为只读(不可修改)

场景:当一个数据是外部引入的,多个地方要用,但在某个地方只能读不能改时。

provide/inject

作用:用于祖组件和后代组件传递数据

// 祖组件传值
import { provide, reactive} form 'vue'
export default {
    setup() {
        let car = reactive({name:'宝马',price:'40W'})
    provide('car',car) // 传递
  }
}
// 后代组件接收
import { inject } form 'vue'
export default {
    setup() {
        let car = inject('car')
    return {car}
  }
}

备注: provide传递的数据是响应式的数据

teleport

作用:vue3内置组件,可以用来包括一组标签,通过to=“#app”属性,把包括的标签脱离原来的文本流显示在对应位置

<template>
  <div>
    <button @click="isShow = true">点我开启dailog</button>
    <teleport to=".app">
      <div v-if="isShow" class="dailog">
        <div class="content">
          <p>你好,我是弹窗内容哦</p>
          <button @click="isShow = false">点我关闭弹窗</button>
        </div>
      </div>
    </teleport>
  </div>
</template>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容