• vue3基础语法


    2020年9月18日发布

    2022年2月7日称为默认版本,意味vue3是现在也是未来

    Ant Design Pc端组件库

    Element Plus Pc端组件库

    Vant 移动端

    VueUse 基于composition 组合式api的常用函数集合

    vue3中文文档:https://cn.vuejs.org/guide/introduction.html

    1. vue3特点

    • Composition API 组合API
    • 首次渲染更快
    • diff算法更快
    • 内存占用更小
    • 打包体积更小
    • 更好的TypeScript支持

    2. vue3项目的创建

    • vue-cli脚手架创建—webpack

    需要查找依赖,打包所有的模块,然后才能提供服务,更新速度会随着代码体积增加越来越慢
    在这里插入图片描述

    vue create xxx
    
    • 1
    • vite构建工具

      vite 意为 ‘快速的’,是一种新型的前端构建工具

      使用原生ESModule通过script标签动态导入,访问页面的时候加载到对应模块编译并响应
      在这里插入图片描述
      注明:项目打包的时候最终还是需要打包成静态资源,打包工具Rollup

    3.vite创建项目

    npm create vite@latest
    
    yarn create vite
    
    pnpm create vite
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.代码分析

    vue3组件代码和vue2不一样,使用的语法提示和高亮插件也是不一样

    vetur插件禁用 安装Vue Language Features (Volar)插件

    vue3写法不同

    • 组件一个根节点非必需

    • 创建应用挂载到根容器

    • 入口页面,ESM加载资源

      <body>
          <div id="app"></div>
          <script type="module" src="/src/main.ts"></script>
        </body>
      
      • 1
      • 2
      • 3
      • 4

    组合式API

    在这里插入图片描述
    vue3提供了两种组织代码逻辑的写法:

    • 通过data,methods,watch等配置选项组织代码逻辑 是选项API的写法
    • 所有逻辑在setup函数中,使用ref,reactive等函数组织代码 是 组合式API写法

    option api

    <template>
      <div>
        <button @click="toggle">显示隐藏</button>
        <img v-if="show" src="./assets/logo.png" />
        <div @click="increment">{{ count }}</div>
      </div>
    </template>
    <script>
     export default {
      data(){
        return {
          show:true,
          count:0
        }
      },
      methods:{
        toggle(){
          this.show=!this.show
        },
        increment(){
          this.count++
        }
      }
     }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    组合式api

    <template>
      <div>
        <button @click="toggle">显示隐藏</button>
        <img v-if="show" src="./assets/logo.png" />
        <div @click="increment">{{ count }}</div>
      </div>
    </template>
    <script setup>
    import {ref} from 'vue'
    let show =ref(true)
    const toggle=()=>{
      show.value =!show.value
    }
    let count = ref(0)
    const increment=()=>{
      count.value++
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    setup

    • setup函数是vue3特有的选项,作为组合式api的起点
    • 从组件生命周期来看,setup在beforeCreate之前执行
    • 函数中this不是组件实例 是undefined
    • 如果数据或者函数在模板中使用,需要在setup中返回
    <script>
    import {ref} from 'vue'
    export default{
      setup(){
        console.log("setup")
        let show =ref(true)
        const toggle=()=>{
          show.value =!show.value
        }
        let count = ref(0)
        const increment=()=>{
          count.value++
          console.log(this)
        }
    
       return {show,toggle,count,increment}
      },
      beforeCreate(){
        console.log("beforeCreate")
      }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    setup语法糖

    <script setup>
    import {ref} from 'vue'
        let show =ref(true)
        const toggle=()=>{
          show.value =!show.value
        }
        let count = ref(0)
        const increment=()=>{
          count.value++
          console.log(this)
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    reactive

    • 使用reactive函数传入一个普通对象,返回一个响应式数据对象
    • 可以转换简单数据吗?? 不能
    <template>
      <div>
         <p>姓名:{{ state.name }}</p>
         <p>年龄{{ state.age }}</p>
         <button @click="change">更改</button>
      </div>
    </template>
    
    <script setup>
    // 1.vue中导出reactive函数
    import {reactive} from 'vue'
    
    // 使用reactive函数,传入一个普通对象,返回一个响应式数据对象
    const state =reactive({name:"lucy",age:23})
    
    const change = ()=>{
      state.age=34
      state.name ="牛牛"
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ref

    • 使用ref函数,传入普通数据 or 复杂 ,返回一个响应式数据
    • 注意,使用ref创建的数据,js中需要.value ,template中可省略
    <template>
      <div>
         <p>姓名:{{ state.name }}</p>
         <p>{{count}}</p>
         <button @click="change">更改</button>
      </div>
    </template>
    
    <script setup>
    // 1.vue中导出ref函数
    import {reactive,ref} from 'vue'
    // 2.使用ref函数 传入普通数据 or 复杂  返回一个响应式数据
    let count = ref(0)
    let state = ref({name:'lucy'})
    
    const change = ()=>{
      // js中使用需要.value
      count.value += 3
      state.value.name ='zs'
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    reactive可以转换对象为响应式数据,但是不支持简单数据类型
    ref可以转换简单数据类型为响应式数据,也支持复杂数据类型 但是操作的时候需要.value
    【推荐】如果能确定数据是对象且字段名称也确定,使用reactive,其他使用ref

    案例

    <template>
     <button @click="toggle">显示隐藏图片</button>
     <img src="./assets/vue.svg" alt="" v-show="show">
     <hr/>
     计数器{{ count }} <button @click="change">累加</button>
    </template>
    <script setup>
    import {ref} from 'vue'
    
    let count = ref(0)
    let show = ref(true)
    
    const toggle = ()=>{
      show.value = !show.value
    }
    const change = ()=>{
      count.value ++
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    computed

    <template>
      <div>
        <p>{{ scoreList }}</p>
        <p>{{ betterList }}</p>
    
        <input type="checkbox" v-model="allCheck" />
        <ul>
          <li v-for="item in arr" :key="item.id">
            <input type="checkbox" v-model="item.flag" />{{ item.name }}
          </li>
        </ul>
      </div>
    </template>
    <script setup>
     import {ref,reactive,computed} from 'vue'
     const scoreList = ref([12,80,100,90,70,60])
    //  计算属性
    const betterList = computed(()=>scoreList.value.filter(item=>item>90))
    
    const arr = ref([
      {id:1,name:'aaa',flag:true},
      {id:2,name:'bbb',flag:true},
      {id:3,name:'ccc',flag:false},
      {id:4,name:'ddd',flag:true}
    ])
    // 完整写法
    const allCheck=computed({
        get(){
          return arr.value.every(item=>item.flag==true)
        },
        set(v){
          arr.value.forEach(item=>{
            item.flag=v
          })
        }
    })
    
    // 改变数据  计算属性改变
    // setInterval(()=>{
    //   scoreList.value.push(90,92)
    // },1000)
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    watch

    <template>
      <div>
     {{ count }}---{{ user.info.age}}---{{ user.name }}
      </div>
    </template>
    <script setup>
    import {ref,watch,reactive} from 'vue'
    const count =ref(0)
    const user=reactive({
      name:'tom',
      info:{
        gender:"男",
        age:14
      }
    })
    
    // 1.监听一个响应式数据
    // watch(数据,改变后回调函数)
    
    // watch(count,()=>{
    //   console.log("count改变了")
    // })
    
    
    
    // 2.监听多个响应式数据
    // watch([数据1,数据2...],回调函数)
    
    // watch([count,user],()=>{
    //   console.log("数据改变了")
    // })
    
    // setTimeout(()=>{
    //   count.value++
    // },1000)
    
    // 3.监听响应式对象数据的一个属性  简单类型
    
    watch(
      ()=>user.name,
      ()=>{
      console.log("数据改变")
    },
    {
      immediate:true   //默认执行一次
    }
    )
    
    
    
    // 4.监听响应式对象数据的一个属性  复杂类型
    
    watch(
      ()=>user.info,
      ()=>{
        console.log("数据改变了")
      },
      {
        // 开启深度监听
        deep:true
      }
    )
    
    // watch(需要监听的数据,数据改变的函数,配置对象)
    
    
    // setTimeout(()=>{
    //   // user.info.age++
    //   user.name = 'zs'
    // },3000)
    
    setTimeout(()=>{
      user.info.age++
      // user.name = 'zs'
    },2000)
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    生命周期函数

    • vue3中生命周期钩子函数可以调用多次

    对比

    选项式API组合式API
    beforeCreate不需要 (直接写到setup函数中)
    created不需要 (直接写到setup函数中)
    beforeMountonBeforeMount
    mountedonMounted
    beforeUpdateonBeforeUpdate
    updatedonUpdated
    beforeDestroyedonBeforeUnmount
    destroyedonUnmounted
    activatedonActivated
    deactivatedonDeactivated
    <template>
      <div>
        生命周期
      </div>
    </template>
    <script setup>
     import {onMounted} from 'vue'
    
     onMounted(()=>{
        console.log(1)
     })
     onMounted(()=>{
      console.log(2)
    })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    ref获取Dom元素

    • 1.创建ref const hRef = ref(null)
    • 2.模板中建立关联 <组件 ref = “hRef”/>
    • 3.使用 hRef.value
    <template>
      <div>
         <h1 ref="hRef">我是标题</h1>
         <HelloWorld ref="myRef"></HelloWorld>
      </div>
    </template>
    <script setup>
    import HelloWorld from './components/HelloWorld.vue';
     import {ref,onMounted} from 'vue'
     
    //  1创建
     const  hRef = ref(null)
    const myRef = ref(null)
    
    onMounted(()=>{
      console.log(myRef.value)
    })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    子传父

    • 子组件通过defineEmits获取emit函数(因为没有this)
    • 子组件通过emit触发事件,并且传递数据
    • 父组件提供方法
    • 父组件通过自定义事件的方式给子组件注册事件
      在这里插入图片描述

    跨级组件通信

    在这里插入图片描述

    • provide和inject是解决跨级组件通讯的方案
      • provide 提供后代组件需要依赖的数据或函数
      • inject注入(获取)provide提供的数据或函数

    在这里插入图片描述

    保持响应式-toRefs

    在使用reactive创建的响应式数据被展开或解构的时候使用toRefs保持响应式

    • 解构响应式数据
    • 使用toRefs处理响应式数据
    • toRefs函数的使用

    旧代码

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    解构代码,没有响应式

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    使用toRefs处理响应式数据

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    toRefs函数的作用:

    把对象中的每一个属性做一次包装(解构)成为响应式数据

    响应式数据展开的时候使用,解构响应式数据的时候使用

  • 相关阅读:
    【日常记录】Connection reset
    谈谈Java/Kotlin中接口回调
    LeetCode 137. 只出现一次的数字 II
    基于Caffe ResNet-50网络实现图片分类(仅推理)的实验复现
    【Prometheus】Prometheus 集群与高可用
    【k8s管理--可视化界面】
    二叉树的基本运算
    通信原理学习笔记5-2:数字调制——连续相位和恒包络问题(非线性功放、连续相位CP FSK信号、最小频移键控MSK、GMSK)
    封装一个中间大两头小的轮播图(vue-awesome-swiper、vue2)
    基于github上erlang版本的LoraWAN Server安装
  • 原文地址:https://blog.csdn.net/ioncannontic/article/details/133443082