【vue3】基础知识

4 篇文章 0 订阅

一.为什么学vue3(vue3的优点)?

  • 性能更好(运行速度更快)
  • 体积更小(按需编译)
  • 类型推断(支持TS)
  • 高级给予(暴露更底层的API和提供更丰富的组件)
  • 组合性API(能够更好的组织逻辑、封装逻辑、复用逻辑)

二.选项API(vue2)和组合API(vue3)对比

1.选项API写法

  • 代码风格:data选项写数据,methods选项写函数…,一个功能逻辑的代码分散。
  • 优点:易于学习和使用,写代码的位置已经约定好
  • 缺点:代码组织性差,相似的逻辑代码不便于复用,逻辑复杂代码多了不好阅读。

2.组合API写法

  • 代码风格:一个功能逻辑的代码组织在一起(包含数据,函数…)
  • 优点:功能逻辑复杂繁多情况下,各个功能逻辑代码组织再一起,便于阅读和维护
  • 缺点:需要有良好的代码组织能力和拆分逻辑能力
    注意:vue3同样支持选项API写法

三.组合API

1.setup函数

  • setup函数作为组合api的起点
  • 在组件实例创建之前执行(相当于vue2中beforeCreate)
  • 此时this获取不到组件实例(this为undefind)
  • 在模板中使用的数据和函数,需要在setup中返回

2.生命周期

钩子函数触发时机
setup创建实例前
onBeforeMount挂载DOM前
onMounted挂载DOM后
onBeforeUpdate更新组件前
onUpdated更新组件后
onBeforeUnmount卸载销毁前
onUnmounted卸载销毁后

3.reactive函数

作用:reactive是一个函数,用来定义一个复杂数据类型,成为响应式数据,通常是用来定义响应式对象数据。

<template>
  <div class="container">
    <div>{{obj.name}}</div>
    <div>{{obj.age}}</div>
    <button @click="updateName">修改数据</button>
  </div>
</template>
<script>
import { reactive } from 'vue'
export default {
  name: 'App',
  setup () {
    // 普通数据
    // const obj = {
    //   name: 'ls',
    //   age: 18
    // }
    const obj = reactive({
      name: 'ls',
      age: 18
    })

    // 修改名字
    const updateName = () => {
      console.log('updateName')
      obj.name = 'zs'
    }

    return { obj ,updateName}
  }
}
</script>

4.toRef函数

toRef函数是用来转化响应式对象中的某个属性为单独响应式数据
代码示例:

<template>
  <div class="container">
    {{name}} <button @click="updateName">修改数据</button>
  </div>
</template>
<script>
import { reactive, toRef } from 'vue'
export default {
  name: 'App',
  setup () {
    // 1. 响应式数据对象
    const obj = reactive({
      name: 'ls',
      age: 10
    })
    console.log(obj)
    // 2. 模板中只需要使用name数据
    // 注意:从响应式数据对象中解构出的属性数据,不再是响应式数据
    // let { name } = obj 不能直接解构,出来的是一个普通数据
    const name = toRef(obj, 'name')
    // console.log(name)
    const updateName = () => {
      console.log('updateName')
      // toRef转换响应式数据包装成对象,value存放值的位置
      name.value = 'zs'
    }

    return {name, updateName}
  }
}
</script>
<style scoped lang="less"></style>

使用场景:有一个响应式对象数据,但是模版中只需要使用其中一项数据。

5.toRefs函数

toRefs是转化响应式对象中所有属性为单独响应式数据,对象为普通对象
代码示例:

<template>
  <div class="container">
    <div>{{name}}</div>
    <div>{{age}}</div>
    <button @click="updateName">修改数据</button>
  </div>
</template>
<script>
import { reactive, toRef, toRefs } from 'vue'
export default {
  name: 'App',
  setup () {
    // 1. 响应式数据对象
    const obj = reactive({
      name: 'ls',
      age: 10
    })
    console.log(obj)
    // 2. 解构或者展开响应式数据对象
    // const {name,age} = obj
    // console.log(name,age)
    // const obj2 = {...obj}
    // console.log(obj2)
    // 以上方式导致数据就不是响应式数据了
    const obj3 = toRefs(obj)
    console.log(obj3)

    const updateName = () => {
      // obj3.name.value = 'zs'
      obj.name = 'zs'
    }

    return {...obj3, updateName}
  }
}
</script>
<style scoped lang="less"></style>

使用场景:剥离响应式对象(解构|展开),想使用响应式对象中的多个或者所有属性作为响应式数据

6.ref函数

ref函数常用于定义简单数据类型为响应式数据
修改值或获取值时需要用.value
代码演示:

<template>
  <div class="container">
    <div>{{name}}</div>
    <div>{{age}}</div>
    <button @click="updateName">修改数据</button>
  </div>
</template>
<script>
import { ref } from 'vue'
export default {
  name: 'App',
  setup () {
    // 1. name数据
    const name = ref('ls')
    console.log(name)
    const updateName = () => {
      name.value = 'zs'
    }
    // 2. age数据
    const age = ref(10)

    // ref常用定义简单数据类型的响应式数据
    // 其实也可以定义复杂数据类型的响应式数据
    // 对于数据未之的情况下 ref 是最适用的
    // const data = ref(null)
    // setTimeout(()=>{
    //   data.value = res.data
    // },1000)

    return {name, age, updateName}
  }
}
</script>

使用场景:当明确需要使用的是一个响应式数据对象就使用reactive,其他情况使用ref

7.computed函数

computed函数用来定义计算属性
代码演示:(让计算属性双向绑定)

<template>
  <div class="container">
    <div>今年:{{age}}</div>
    <div>后年:{{newAge}}</div>
    <!-- 使用v-model绑定计算属性 -->
    <input type="text" v-model="newAge">
  </div>
</template>
<script>
import { computed, ref } from 'vue'
export default {
  name: 'App',
  setup () {
    // 1. 计算属性:当你需要依赖现有的响应式数据,根据一定逻辑得到一个新的数据。
    const age = ref(16)
    // 得到后年的年龄
    // const newAge = computed(()=>{
    //   // 该函数的返回值就是计算属性的值
    //   return age.value + 2
    // })

    // 计算属性高级用法,传人对象
    const newAge = computed({
      // get函数,获取计算属性的值
      get(){
        return age.value + 2
      },
      // set函数,当你给计算属性设置值的时候触发
      set (value) {
        age.value = value - 2
      }
    })


    return {age, newAge}
  }
}
</script>

总结:计算属性两种用法
1.给computed传入函数,返回值就是计算属性的值
2.给computed传入对象,get()方法获取计算属性的值,set()方法监听计算属性改变,计算属性改变时触发

8.watch函数侦听器

可以侦听ref和reactive定义的响应式数据,还可以监听多个响应式数据
代码示例:

 //  监听多个数据的变化
     watch([count, obj], ()=>{
      console.log('监听多个数据改变了')
     }{
     deep:true, // 是否深度监听
     immediate:true  // 是否默认触发
}) 

9.ref属性

ref属性可以获取DOM元素或组件实例

1.vue2写法

(1)获取单个元素
  • 通过ref属性绑定该元素(ref=“box”)
  • 通过this.$refs.box获取元素
(2)获取v-for遍历的多个元素
  • 通过ref属性绑定被遍历元素
  • 通过this.$refs.li 获取所有遍历元素

2.vue3写法

(1)获取单个元素

先申明ref响应式数据,返回给模版使用,通过ref绑定数据

(2)获取v-for遍历的多个元素
  • 定义一个空数组,接收所有的LI
  • 定义一个函数,往空数组push DOM
    注意:组件更新时会重复设置dom元素给数组,所以需要在组件更新的时候重置接受dom元素的数组,如下:
 onBeforeUpdate(()=>{
      list = []
    })

代码示例:

<template>
  <div class="container">
    <div ref="dom">我是box</div>
    <ul>
      <li v-for="i in 4" :key="i" :ref="setDom">{{i}}LI</li>
    </ul>
  </div>
</template>
<script>
import { onMounted, ref } from 'vue'
export default {
  name: 'App',
  setup () {
    // 1. 获取单个元素
    // 1.1 先定义一个空的响应式数据ref定义的
    // 1.2 setup中返回该数据,你想获取那个dom元素,在该元素上使用ref属性绑定该数据即可。
    const dom = ref(null)
    onMounted(()=>{
       console.log(dom.value)
    })
     // 2. 获取v-for遍历的元素
    // 2.1 定义一个空数组,接收所有的LI
    // 2.2 定义一个函数,往空数组push DOM
    const domList = []
    const setDom = (el) => {
      domList.push(el)
    }
    onMounted(()=>{
      console.log(domList)
    })
    return {dom, setDom}
  }
}
</script>
<style scoped lang="less"></style>

10.父子通讯

1.父传子

首先在父组件中通过自定义属性将数据传给子组件

<div class="container">
    <h1>父组件</h1>
    <p>{{money}}</p>
    <hr>
    <Son :money="money" />
  </div>

然后在子组件中通过props接收父组件传过来的值

export default {
  name: 'Son',
  // 子组件接收父组件数据使用props即可
  props: {
    money: {
      type: Number,
      default: 0
    }
  },

2.子传父

首先在子组件setup函数中通过emit属性将数据传给父组件

+  setup (props, {emit}) {
    // 获取父组件数据money
    console.log(props.money)
    // 向父组件传值
+    const changeMoney = () => {
      // 消费50元
      // 通知父组件,money需要变成50
+      emit('change-money', 50)
+    }
+    return {changeMoney}

然后在父组件中通过自定义事件接收子组件传递过来的值

<template>
  <div class="container">
    <h1>父组件</h1>
    <Son :money="money" @change-money="updateMoney" />
  </div>
</template>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值