Vue3基础学习

---
theme: smartblue
---

## 创建vue3项目

1.首先node的版本在4.5以上<br/>
2.直接用vue-cli来创建vue3项目vue create project\_name

## 正式学习

### 一、常用Componention(组合式) Api

> setup

1.  组件中所用到的数据,方法,对象中的属性都写在setup中
2.  setup中有两种返回值:对象和函数
3.  **若返回一个对象,则对象中的属性、方法、在模板中均可以直接使用**
4.  若返回一个渲染函数:则可以自定义渲染内容。
        //返回一个对象
         return {
           name,
           age,
           sayHello
         }

         // 返回一个函数
         return ()=>{ // h是渲染哈描述,要是用的花,需要引入
              return h('h1','张三')
         }  ```
5.  setup不是async函数,因为返回值不再是return,而是promise.
6.  setup的参数
*   props:值为对象,包含组件外部传递过来,且组件内部声明接受了的属性
*   context:上下文对象
    *   attrs:值为对象,包含:组件外部传递过来,但没有props配置中声明的属性
    *   slots:接受插槽内容,相当于this.\$slot.
    *   emit:分发自定义事件的函数,相当于this.\$emit
7.  注意点:
*   尽量不要和vue2混用
*   vue2配置(data,methods,computed...)中可以访问到setup中的属性,反之不行
*   如果重名,setup优先级高
*   setup比beforeCreate先执行,this是undefined.

> ref  (实现vue3的响应式)

1.  ref的返回体
 
![img_1.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2287d4bf95054fa58b5899154e4c638b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1236&h=1009&s=116621&e=png&b=ffffff)
2.  ref的代码使用

````angular2html
    <template>
      <div>
        <h1>一个人的信息</h1>
        <h2>名字:{{name}}</h2>
        <h2>年龄:{{age}}</h2>
        <h2>工作:{{job.type}}</h2>
        <h2>薪资:{{job.salary}}</h2>
        <button @click="changeInfo">改变信息</button>
      </div>
    </template>
  
    <script>
    import {ref} from 'vue'
    export default {
      name: 'App',
      props: {
      },
      setup(){
        let name = ref('张三')
        let age = ref(18)
        let job = ref({
          type :'前端开发',
          salary:'30k'
        })
    
    
    
        // 返回一个对象
        function changeInfo(){
          // name.value = '李四'
          // age.value = 38
          console.log(job.value)
          job.value.type = 'java开发'
          job.value.salary = '40k'
        }
        return {
          name,
          age,
          changeInfo,
          job
        }
      }
    }
    </script>
    ```   
3. ref 可以接受基本类型,对象类型
   * 对基数据类型使用数据劫持(object.defineProperty()中的get set )来实现响应式;
   * 对于对象类型的数据(复杂数据类型)使用了新的特性—— reactive函数。  

4. reactive 函数
   * 作用:定义一个**对象类型**的响应式数据(基本类型用ref)
   * 代码使用
   ```vue
    let job = reactive({
      type :'前端开发',
      salary:'30k'
    })
     console.log(job)
    job.type = 'java开发'
    job.salary = '40k'
````

![img_2.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e6e792702d6c4aebb3fb2df6d4ffbc9a~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1239&h=534&s=55539&e=png&b=fefefe)
> Vue3.0中的响应式原理

1.  vue2.0的响应式原理

*   实现原理
    *   对象类型:通过object.defineProperty()对属性的读取、修改进行拦截(**数据劫持**)
    *   数组类型:通过重写更新数组的一系列方法来实现拦截(对数组的变更进行了包裹)

    <!---->

         // 模拟数据
         let person={
         name:'张三',
         age:10
        }
        //模拟vue2中实现响应式
        let p = {}
        Object.defineProperty(p,'name',{
            get(){
                return person.name
            },
            set(value){
                console.log('有人修改了name属性,我去更新')
                return person.name = value
            }
        })
        Object.defineProperty(p,'age',{
            get(){
                return person.age
            },
            set(value){
                console.log('有人修改了age属性,我去更新')
                return person.age = value
            }
        })
 ![img_3.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2f26e4a10eac4261bdf7994c64bcd676~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1204&h=797&s=55718&e=png&b=ffffff)
*   存在的问题:
    *   新增属性、删除属性、界面不会更新(使用$set和$delete解决)
    *   直接通过下标修改数组、界面不会自动更新(\$set,splice)

2.  Vue3.0的响应式

*   实现原理:
    *   通过**proxy(代理)**:拦截对象中任意属性的变化,包括:属性的读写、属性的添加、属性的删除等
    *   通过**Reflect(反射)**: 对代理对象的属性进行操作
    *   **代码**:

```angular2html
     //模拟vue3中实现响应式
    //window.proxy
     const p = new Proxy(person,{
     get(target,propName){
     console.log(`有人读取了p身上的${propName}属性`)
     return Reflect.get(target,propName)
    },
    //修改和追加某个属性时会调用
     set(target,propName,value){
     console.log(`有人修改了p身上的${propName}属性,我要去更新页面`)
     Reflect.set(target,propName,value)
    },
     deleteProperty(target, propName) {
     console.log(`有人删除了p身上的${propName}属性,我要去更新页面`)
     return  Reflect.deleteProperty(target,propName)
     }
    })
```

> vue3.0计算属性与监视

1.  与vue2中computed配置功能一致
2.  代码

<!---->

    setup(){
        let person = reactive({
          firstName : '张',
          lastName :'三',

        })
        //计算属性-简写(没有考虑计算属性被修改的情况)
         person.fullName = computed(()=>{
         return person.firstName + '-' + person.lastName
        })
        //计算属性-完整写法
        let fullName = computed({
          get(){
            return  person.firstName + '-' + person.lastName
          },
          set(value){
            const nameArr = value.split('-')
            person.firstName =  nameArr[0]
            person.lastName = nameArr[1]
          }
        })

> watch函数

1.  与Vue2.x中watch配置功能一致
2.  代码

```vue
 //情况一:监视ref所定义的一个响应式数据
    /* watch(sum,(newValue,oldValue)=>{
    /   console.log('sum或者msg变了',newValue,oldValue)
     },{immediate:true,deep:true})*/

    //情况二:监视ref所定义的多个响应式数据
   /* watch([sum,msg],(newValue,oldValue)=>{
      console.log('sum或者msg变了',newValue,oldValue)
    },{immediate:true,deep:true})
   */

    //情况三:监视reactive所定义的一个响应式数据,
    // 注意:1.此处无法正确的获取oldValue 2.强制开启了深度监视,deep:false无效
    // watch(person,(newValue,oldValue)=>{
    //   console.log('person变化了',newValue,oldValue)
    // })
   //情况四:监视reactive所定义的响应式数据中的某个属性
    watch(()=>person.name,()=>person.age,(newValue,oldValue)=>{
      console.log('person的name变化了',newValue,oldValue)
```

3.注意

*   监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失败)
*   监视reactive定义的响应式数据中的某个属性时:deep配置有效

> watchEffect函数

1.  watch:既要指明监视的属性,也要指明监视的回调
2.  watchEffect:不用指明监视哪个属性,监视的回调用到哪个属性,那就监视哪个属性。
3.  watchEffect有点像computed
4.  代码

```vue
    watchEffect(()=>{
    const x1 = sum.value
    const x2 = person.job.j1.salary
    console.log('watchEffect所指的回调函数执行了')
    })
```

> 生命周期

1.  **beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeUnmount、mounted**
2.  组合式api所对应的名称:**setup(),setup(),onBeforeMount,onMounted,onBeforeUpdate,onUpdate,onBeforeUnmount,onUmounted**
3.  组合式api的优先级更大一点。

> 自定义hook函数

1.  hooks:本质上是一个函数,把setup函数中使用的Composition API进行了封装。
2.  类似于vue2中的mixin
3.  hooks的优势:复用代码,让setup中的逻辑清晰易懂。

> toRef(把什么变成ref)

1.  作用:创建一个ref对象,其value指向另一个对象中的某个属性
2.  语法:const name = toRef(person,'name')
3.  应用将响应式对象中的某个属性单独提供给外部使用
4.  toRefs与toRef功能一致,但可以创建多个ref对象,语法toRefs(person)

### 二、其它Componention(组合式) Api

> shallowReactive 和shallowRef

1.shallowReactive:只能处理对象最外层属性的响应式(浅响应式)
2.shallowRef:只能处理基本数据类型的响应式,不进行对象的响应式处理
3.when to use?

*  如果有一个对象数据,结构比较深,但是变化时只是外部属性变化===》shallowReactive
*  如果有一个对象数据,后续功能不会修改对象中的属性,而是生新的对象来替换===》shallowRef

> readonly 和 shallowReadonly

1.readonly:让一个响应式数据变为只读(深只读)
2.shallowReadonly:让一个响应式数据变为只读(浅只读)

> toRaw 与 markRow

1.  toRaw:
*   作用:将一个由reactive生成的响应式对象转为普通对象
*   使用场景:用于读取响应式对象的普通对象,对这个普通对象的所有操作,不会引起页面更新
2.  markRow:
*   标记一个对象,使其永远不会在成为响应式对象
*   应用场景:
    1.  有些值不应设置为响应式的,例如复杂的第三方类库等
    2.  当渲染具有不可变数据源的大列表时,跳过响应式转换可以调高性能

> customRef

1.  作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制。
2.  实现防抖效果:

```vue
 function  myRef(value,delay){
      let timer
      // console.log('---myRef---',value)
      return customRef((track,trigger)=>{
        return{
          get(){
            console.log(`有人从myRef这个容器中读取数据了,我把${value}给他了`)
            track()//通知vue追踪value的变化
            return value
          },
          set(newValue){
            console.log(`有人把myRef这个容器中数据改为了${newValue}`)
            clearTimeout(timer)
             setTimeout(()=>{
               value = newValue
               trigger()//通知vue重新解析模板
             },delay)
          }
        }
      })
    }

    let keyWord = myRef('hello',500)

    return {
      keyWord
    }
```

> provide与inject

*   作用:实现祖孙组件之间的通信
*   代码

```vue
 //父组件
  setup(){
    let car = reactive({
      name:'奔驰',
      price:'40w'
    })
    provide('car',car)//给自己的后代传入数据
    return{
      ...toRefs(car)
    }
  }
//子组件
 setup(){
    let car = inject('car')
    return {
     car
     }
    }
  }

```

### 三、Componention(组合式) Api 的优势

1.  Option Api存在的问题:使用传统的配置式的api,新增或者修改一个需求,就需要分别在data,methods,computed里修改。
2.  Composition API优势:更加优雅的组织代码,函数。让相关功能的代码更加有序的组织在一起。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值