Vue 3.0 入门基础总结

本文详细讲解了Vue3中的setup函数使用、props和context的区别,以及ref、reactive、provide/inject、useStore等核心概念。了解如何在组件间高效传递数据和维护响应性,以及生命周期管理和数据绑定的革新。

setup

组件选项,在组件创建之前执行,一旦 props 被解析,就将作为组合式 API 的入口

参数
  • props
  1. 所有声明了的 prop,不管父组件是否向其传递了,都将出现在 props 对象中。其中未被传入的可选的 prop 的值会是undefined。
  2. setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新,所以不能使用 ES6解构,会消除 prop 的响应性
  3. 如果需要解构 prop,可以在 setup 函数中使用 toRefs 函数来完成此操作
  4. 如果某个属性是可选的 prop,则传入的 props 中可能没有该属性。在这种情况下,toRefs 不适用 。需要使用 toRef 替代。
  • context
  1. context.attrs —— // Attribute (非响应式对象,等同于 $attrs)
  2. context.slots —— // 插槽 (非响应式对象,等同于 $slots)
  3. context.emit —— // 触发事件 (方法,等同于 $emit)
  4. context.expose —— // 暴露公共 property (函数)
使用注意点
  1. setup 的调用发生在 data property、computed property 或 methods 被解析之前,就说在 setup函数中是无法 使用 data 和 methods 中的数据和方法的
  2. 在setup函数中定义的变量和方法最后都是需要 return 出去的,不然无法再模板中使用
  3. setup函数只能是同步的不能是异步的
  4. 生命周期钩子函数只能写在setup中
  5. provide/inject 只能写在setup中

 
 
 
 

ref和reactive

ref
  • 在 Vue 3.0 中,通过ref 函数使任何响应式变量在任何地方起作用。即ref 为我们的值创建了一个响应式引用,访问时需要通过.value进行访问
reactive
  • 返回对象的响应式副本
  • reactive 将解包所有深层的 refs,同时维持 ref 的响应性
const count = ref(1)
const obj = reactive({ count })

// ref 会被解包
console.log(obj.count === count.value) // true
  • 当将 ref 分配给 reactive property 时,ref 将被自动解包
const count = ref(1)
const obj = reactive({})

obj.count = count

console.log(obj.count) // 1
console.log(obj.count === count.value) // true
用法示例
 <script>
   import { ref, reactive } from "vue";
   setup(){
     const str = ref("vue3.0")
     const obj = reactive ({name: '张三', age: 20})
     function changeStr(){
       str.value = "vue3.0牛逼"
     }
     function changeObj(){
       obj.name= "李四"
     }
     return { str, obj, changeStr, changeObj }
   }
 </script>
区别

ref 和 reactive 本质我们可以简单的理解为ref是对reactive的二次包装, ref定义的数据访问的时候要多一个.value

  1. ref定义的数据需要通过.value才能使用,而reactive则不需要
  2. ref返回RefImpl对象(也叫ref对象),reactive返回Proxy对象。
  3. ref可以为基本类型添加响应式,也可以为引用类型添加响应式,reactive只能为引用类型添加响应式。
    ps:只打算修改引用类型的一个属性,那么推荐用reactive,如果你打算变量重赋值(改变整个对象),那么一定要用ref。

原因在于jsonData尽管是响应式的,但是响应式的是它的属性,而不是它自身,重赋值它自身跟重赋值它的属性是两码事。所以,想在组合式API中让数据具备响应式,必须用ref,因为ref又对Proxy包装了一层,修改ref其实是修改它的value,它的value一定是响应式的,因此视图就正常更新了

更多详细讲解 https://www.jianshu.com/p/cfe25e757d0e

 
 
 
 

Provide / Inject

通常当我们需要将数据从父组件传递到子组件时,我们通过props实现。 设想一下这样的一个组件结构,这个结构中有一些嵌套层级很深的组件,我们想在内嵌层级很深的一个子组件中,调用顶层父组件的某些数据。在这种情况下,如果我们仍需要通过prop从父组件到子组件之间的组件链中传递数据,会进行很多次传递,这可能挺烦人的。

为了应对这种情况,我们可以使用provide与inject的组合。父组件可以无视组件层级的深度,作为所有子组件的依赖提供者。这个特性基于两部分:父组件通过provide选项提供数据,并且子组件通过inject选项使用所提供的数据。

provide

使用 provide 时,首先需要从 vue 显式导入 provide 方法
provide 函数定义property接收两个参数:

  • name ( 类型)
  • value
inject

使用 inject 时,也需要从 vue 显式导入
inject函数有两个参数:

  • 要 inject 的 property 的 name
  • 默认值 (可选)

ps:provide/inject 只能写在setup中,即不能写在异步函数和回调函数中,因为那时已经不在setup生命周期中了

用法
父组件
<template>
  <div class="parent">
    <h1>父组件的值:{{ primaryValue }}</h1>
    <button @click="changeFatherValue(88)">父组件的值改变</button>
    <chidCom></chidCom>
  </div>
</template>

<script>
import chidCom from "../components/childCom.vue";
import { ref, reactive, provide } from "vue";
export default {
  components: {
    chidCom,
  },
  setup() {
    let primaryValue = ref(4);
    let objectValue = reactive({
      name: "pzp",
      age: "23",
    });
    provide("primaryValue", primaryValue);
    provide("objectValue", objectValue);

    console.log(primaryValue.value, objectValue.name);

    let changeFatherValue = (val) => {
      primaryValue.value = val;
      objectValue.name = "pzpa";
    };
    provide('changeFatherValue', changeFatherValue)

    return {
      primaryValue,
      objectValue,
      changeFatherValue,
    };
  },
  //   methods: {
  //       changeFatherValue() {
  //           this.primaryValue = 8
  //           this.objectValue.name = 'pzpa'
  //       },
  //   },
};
</script>
子组件
<template>
  <div>
    <h1>父组件注入基础类型值:{{ fatherPrimary }}</h1>
    <h1>父组件注入对象类型值:{{ fatherObject.name }}</h1>
    <button @click="changeFatherValue(66)">子组件改变父组件值</button>
  </div>
</template>

<script>
import { inject } from "vue";
export default {
  setup() {
    let fatherPrimary = inject("primaryValue");
    let fatherObject = inject("objectValue");
    let changeFatherValue = inject('changeFatherValue')

    return {
      fatherPrimary,
      fatherObject,
      changeFatherValue
    };
  },
};
</script>
效果展示

在这里插入图片描述

注意点
  • 若需要provide/inject传递的值有响应性,被传递值的定义必须通过ref/reactive进行定义
  • 当使用响应式 provide / inject 值时,建议尽可能将对响应式 property 的所有修改限制在定义 provide 的组件内部,即尽量在父组件内进行修改。若需要在子组件更新注入的数据,建议 provide 一个方法来负责改变响应式 property,比如上面的changeFatherValue
  • 如果要确保通过 provide 传递的数据不会被 inject 的组件更改,建议对提供者的 property 使用 readonly

 
 
 
 

getCurrentInstance

官文给出的该方法的描述为:getCurrentInstance 支持访问内部组件实例。特别强调了

getCurrentInstance 只暴露给高阶使用场景,典型的比如在库中。强烈反对在应用的代码中使用 getCurrentInstance。请不要把它当作在组合式 API 中获取 this 的替代方案来使用

使用方法详解

 
 
 
 

计算属性-computed

计算属性和方法的区别

接受一个 getter 函数,并根据 getter 的返回值返回一个不可变的响应式 ref 对象

const count = ref(1)
const plusOne = computed(() => count.value + 1)

console.log(plusOne.value) // 2

plusOne.value++ // 错误

或者,接受一个具有 get 和 set 函数的对象,用来创建可写的 ref 对象。

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: val => {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) // 0

 
 
 
 

监听器-watch

侦听器数据源可以是返回值的 getter 函数,也可以直接是 ref

侦听单个数据源
// 侦听一个 getter
const state = reactive({ count: 0 })
watch(
  () => state.count,
  (count, prevCount) => {
    /* ... */
  }
)

// 直接侦听ref
const count = ref(0)
watch(count, (count, prevCount) => {
  /* ... */
})
侦听多个数据源
const firstName = ref('')
const lastName = ref('')

watch([firstName, lastName], (newValues, prevValues) => {
  console.log(newValues, prevValues)
})

firstName.value = 'John' // logs: ["John", ""] ["", ""]
lastName.value = 'Smith' // logs: ["John", "Smith"] ["John", ""]

ps:在同一个函数里同时改变这些被侦听的来源,侦听器仍只会执行一次,即多个同步更改只会触发一次侦听器

侦听响应式对象(深度嵌套对象)

 
 
 
 

useStore

在Vue3中,不能通过this.$store来获取使用vuex中存储的值,并且也不能使用getCurrentInstance来替代this进行使用。
此时若需要获取vuex的实例,就需要用到useStore方法
ps:同理,对于路由的使用也是通过useRouteuseRouter 方法

import { useRoute, useRouter } from "vue-router"
import { useStore } from 'vuex'

setup(props, context) {
     // vue 3.0中vuex的使用
     let store = useStore()
     let storeValue = computed(() => store.state.user)
     
     return {
         storeValue
     }
 }

 
 
 
 

虚拟dom算法更新

  • vue3修改了虚拟dom的算法(即diff算法 - 比对虚拟dom有没有变化)
  • vue2需要diff所有的虚拟dom节点,而vue3参考了SVELTE框架的思想,先分层次-然后找不变化的层-针对变化的层进行diff,更新速度不会再受template大小的影响,而是仅由可变的内容决定。经过尤雨溪自己的测试,大概有6倍的速度提升。

 
 
 
 

数据的双向绑定

关于数据双向绑定的实现,vue2 采用了defineProperty,而vue3则采用了proxy。

优点:

  • 使用proxy不污染源对象,会返回一个新对象,defineProperty是注入型的,会破坏源对象
  • 使用proxy只需要监听整个源对象的属性,不需要循环使用Object.defineProperty监听对象的属性
  • 使用proxy可以获取到对象属性的更多参数,使用defineProperty只能获取到监听属性的新值newvalue
/* vue2.0*/
var a = { b: 123, c: 444 };
Object.defineProperty(a, "b", {
  set: function (newvalue) {
    console.log("i am be set");
  },
}); //只能获取到newvalue这个参数

/* vue3.0 */
var a = { b: 123, c: 444 };
var newa = new Proxy(a, {
  set: function (target, key, newvalue) {
    console.log(target, key, newvalue);
  },
}); //可以获取到target,key,newvalue三个参数

 
 
 
 

生命周期钩子

在这里插入图片描述

### 回答1: Vue3.0是一款前端框架,相比于2.x版本,3.0版本提供了更好的性能和更好的类型支持。那么,如何从零入门Vue3.0呢? 首先,需要了解一些基础概念,例如Vue实例、组件、指令和计算属性等。可以通过阅读Vue官方文档或者相关书籍进行学习。另外,熟练掌握HTML、CSS以及JavaScript基础知识也很重要。 接着,可以通过搭建一个简单的开发环境来完成Vue3.0入门。可以搜索相关的教程或者跟着官方文档进行安装步骤,然后创建一个Vue实例,引入一些组件和指令,最后将它们渲染到页面上。 当了解了Vue3.0的基本用法后,可以通过阅读文档和实际操作来进一步提高自己的技能水平。一些高级的特性,例如Composition API、Teleport和Suspense等,可以帮助我们更加高效地开发应用程序。 最后,通过练习和写一些小项目来巩固学习成果,例如创建一个简单的To-Do-List应用或者一个博客系统等,这样可以更好地掌握Vue3.0的相关知识和技巧。 综上所述,Vue3.0的零基础入门需要掌握一些基础知识、搭建开发环境、了解基本用法、学习高级特性和练习实践等步骤,通过不断地探索和实践,可以更加深入地了解并掌握Vue3.0的技术。 ### 回答2: Vue 3.0 是一个开源的 JavaScript 框架,用于构建现代化的 Web 应用和单页面应用。如果您是一个零基础入门者,现在学习 Vue 3.0 并不会太难,以下是一些入门技巧: 第一步,需要了解 Vue 3.0基础概念和语法。Vue 入门者需要了解 Vue CLI、Vue 组件、Vue 模板、指令、插件等基础概念。同时,需要使用 web 开发技术,如 HTML、CSS 等,并能够熟练使用 JavaScript。 第二步,您可以通过阅读官方文档或参加在线教学平台来进行学习。对于初学者,Vue 3.0 官方文档提供了基础特性、组件、Api、路由、状态管理、插件等信息。此外,优质的教学网站也是一个好的选择。 第三步,您可以开始进行实践项目。这些项目可以是基于 Vue 3.0 的 ToDo 应用程序、新闻客户端、简单的博客等。这些应用可以将概念与实践相结合,以加深您对 Vue 3.0 的理解。 第四步,加入开发社区并与开发者互动交流。开源社区比较活跃,您可以参与到其中,通过问答、发表评论、提出问题等方式得到帮助和学习经验。 最后,Vue 3.0 由于其易于学习和使用而受到了开发者的喜爱。只要您学习基础知识和实践经验,并成为 Vue 3.0 开发社区中的一员,那么在未来的开发实践中,您将会收获很多成果。 ### 回答3Vue.js是一款简单易用、高效灵活的JavaScript框架。它被广泛应用于前端开发,不仅可以用于构建单页应用和复杂的Web应用程序,还可以用于构建管理面板、后台系统等。 Vue.js 3.0Vue.js框架的最新版本,它带来了一些令人兴奋的新特性,包括更少的内存消耗、更快的运行速度和更好的类型推断。下面是一些零基础入门Vue.js 3.0的步骤: 1.准备环境 在开始使用Vue.js 3.0之前,您需要在计算机上安装Node.js和npm。然后,您可以使用npm安装Vue.js 3.0的CLI。 2.创建Vue.js应用程序 使用Vue.js CLI创建一个新的Vue.js应用程序。使用以下命令: vue create my-project 这条命令将创建一个新的Vue.js项目。 3.学习Vue.js基础知识 Vue.js是一种基于组件的框架,它允许您将复杂的应用程序拆分成多个小部件。了解Vue.js基础知识非常重要,包括模板、组件、数据绑定和事件处理程序等。 4.编写组件 编写组件是Vue.js应用程序开发的核心。您可以使用Vue.js的组件系统来创建可重用的组件,并将它们组合成一个完成的应用程序。 5.使用Vue.js的路由器 Vue.js的路由器系统可以帮助您管理应用程序中的不同视图和组件之间的导航。学习使用Vue.js的路由器非常重要。 总之,Vue.js是一款易于学习和使用的前端开发框架。通过学习Vue.js基础知识、编写组件、使用路由器和其他相关技术,您可以轻松地创建可重用的Vue.js应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值