3

Vue3 中有哪些值得深究的知识点?

 3 years ago
source link: https://www.cnblogs.com/web-learn/p/15655191.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

众所周知,前端技术一直更新很快,这不 vue3 也问世这么久了,今天就来给大家分享下vue3中值得注意的知识点。喜欢的话建议收藏,点个关注!


1、createApp

vue2 和 vue3 在创建实例时,有很大的区别,具体对比如下:

//Vue 2
Vue.use({
 router,
 store,
  render:h=>h(App)
}).$mount("#app")

//Vue 3
createApp(App).use(router).use(store).mount("#app")

vue2 创建实例,使用的是 new Vue() 对应的 router、store 都是其中一部分参数。

而 vue3 中,使用 createApp 创建应用实例,router、store 被当作插件通过链式调用。

在 vue2 中,创建多个实例的话,如果有 mixin、prototype 等时,容易造成实例污染。而 createApp 方法创建的是一个全新的实例,可以有效地避免这个问题。所以在vue3中,可以任意地创建多个实例。

2、setup

vue2 中选项式开发的,而 vue3 采用组合式开发,也可以向下兼容选项式开发。

setup 函数就是 vue3 中 Composition API 的入口,是处于生命周期钩子函数 beforeCreate 和 created 两个函数之间,所以 setup 中的属性和方法无法在外部使用。如果需要使用的话,必须 return 暴露出去。

对比一下 vue2 和 vue3 中 data 和 method 使用区别:

// vue2
export default{
 data(){
  return{
   name:"热爱前端的小姐姐"
  },
  methods:{
   print(){
    console.log("打印")
   }
  }
 }
}

// vue3
export default{
 setup(){
  const name="热爱前端的小姐姐"
  function print(){
   console.log("打印")
  }
  return {  name , print }
 }
}

vue2 中,this 是我们的常客,随处可见它的踪影。我们在 setup 中加入 this 的打印,试着查看下结果,发现运行结果是 undefined。

所以在 setup 内无法使用 this 以及挂载 this 相关的东西。

所以 setup 函数提供了两个参数:

setup(props,context){
 //props 是响应式数据,不能直接解构赋值
 //context 非响应式对象,可以直接解构使用
  
 // Attribute (非响应式对象)
 console.log(context.attrs)
 
 // 插槽 (非响应式对象)
 console.log(context.slots)
 
// 触发事件 (方法)
console.log(context.emit)
}

3、script setup 语法糖

简化上述 setup 组合式 API 的写法,属于 vue3 的新语法糖。

  1. 定义的属性和方法无需 return,可以直接使用。
  2. 自动注册组件,不再需要 components 内注册组件。

大大简化上述 setup() 的代码。

4、钩子函数

vue2 使用生命周期函数时,直接使用就好了。如:

// vue2
export default{
 beforeCreate(){
 },
 mounted(){
  
 }
}

但是在 vue3 组合式 API 中,通过生命周期钩子前面加 on 来访问,使用之前必须引入。如:

// vue3 
<script setup>
 import { onMounted } from "vue"
 onMounted(()=>{
 
 })
</script>

由于 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以在 setup 内不需要这两个钩子函数,剩余的都是一样的。

官方提供生命周期钩子:

Vue3 中有哪些值得深究的知识点?

5、teleport 传送门

teleport 传送门可以把内部的元素绑定到任意父元素上,使用方式简单灵活。

使用方式:

<teleport to="body"></teleport>

to 属性是指定 teleport 中内容加入的 DOM 元素,可以是标签名、类名或 id 。

//标签名  。上述实例就是加入body元素内,使用的是标签名。
<teleport to="body"></teleport>

//类名。如:to=".className"
<teleport to=".className"></teleport>

//id名
<teleport to="#idName"></teleport>

优点:多个组件嵌套层次过多时,样式层级处理麻烦,使用 teleport 可以把元素剥离出来,设置样式方便,同时 vue 控制状态也方便。

6、mixin 混入

mixin 对象会把多个组件公用的选项提取出来,需要的组件内引入,管理方便。在 vue3 中 mixin 使用较少。

使用方式:

<script>
const myMixin = {
 data(){
  return {name:'热爱前端的小姐姐'}
 }
}
export default {
 mixins:[myMixin],
 data(){
  return {
   qdr:"前端人"
  }
 }
}
</script>

使用时,可以引入多个 mixin 对象。使用注意事项:

  1. mixin 对象与组件包含相同选项时,会自动合并。
  2. mixin 对象与组件相同选项内拥有相同属性时,就近原则,优先继承实例内的值。
  3. mixin 和组件包含相同的钩子函数时,会合并执行,优先执行 mixin 中的钩子函数。
  4. mixin 自定义属性与实例中冲突时,可以通过 optionMergeStrategies 定义优先级。

7、自定义指令

全局自定义指令:

vue2 的 directive 挂载到 Vue 对象上。

vue3 的 directive 挂载到 app 上,如:

//Vue 2
Vue.directive('name',opt)

//Vue 3
const app = createApp(App)
app.directive("name",options)
app.mount("#app")

局部自定义指令:与 vue2 写法相同。

在 vue3 中自定义指令生命周期钩子函数有一部分改变,钩子函数分别为:

  • created
  • beforeMounted
  • mounted
  • beforeUpdate
  • updated
  • beforeUnmounted
  • unmounted

8、ref、reactive

ref 作用是让基础类型数据具备响应式。

reactive 让引用数据类型具备响应式能力。

ref 和 reactive 包裹数据,使数据具备响应式,在使用之前需要先引入。

使用方法如:

<script setup>
 import { ref , reactive } from "vue"
 let mood = ref("value")
 let me = reactive({
  str:value,
 })
</script>

setup + ref + reactive 就可以实现 vue2 中 data 的响应式功能,所以 setup 能够替换掉 data 。

9、toRefs、toRef

toRefs 解构 props 传递的数据,由于父向子组件通过 props 传值是响应式的,使用 ES6 解构会消除响应特性,所以使用 toRefs 。

<script setup>
 const props = defineProps({
  selectNum:Number,
  allNum:Number,
 })
 const { selectNum, allNum } = toRefs(props)
</script>

toRef 也是解构数据,主要是对可选参数处理,运行时先检查 解构的数据中是否存在该属性,如果存在就继承,不存在则会创建一个属性,这样就不会报错了。

const str = toRef( props, 'str' )

10、watch、watchEffect 新用法

watch 、watchEffect 都是侦听器。

watch 会监听某个基础类型数据或引用数据类型的某个具体属性。

vue3 使用 watch 之前,必须引入。

//vue2
watch:{
 mood(curVal,preVal){
  console.log('cur',curVal);//最新值
  console.log('pre',preVal);//修改之前的值
 }
}

//vue3
import { watch } from "vue"
watch(
 name ,
 ( curVal , preVal )=>{ //业务处理  },
 options
)

watchEffect 监听的是引用数据类型的所有属性,不需要指定是哪个具体的属性,一旦运行,就会立刻执行。

watchEffect 使用之前也必须引入。

import { watchEffect } from "vue"
let obj = reactive({ name:'qq',sex:'女'})
watchEffect(() => {
 console.log('name',obj.name);
 console.log('sex' , obj.sex);
})

watch 与 watchEffect 对比:

  1. watch 运行的时候不会立刻执行, watchEffect 立即执行。
  2. watch 更加具体,需要指定监听的谁,watchEffect 不要执行具体监听谁,回调函数内直接使用就可以,比较抽象。
  3. watch 回调内可以访问到修改之前的值,watchEffect 只能访问最新的值。
  4. watch 可通过配置实现 watchEffect 的前两个特性。

11、computed 新用法

computed 计算属性

选项式 API 中 vue2 和 vue3 使用相同。

组合式 API 中,使用之前需要引入。

// 选项式
computed:{
 sum(){
  return this.num1+ this.num2
 }
}

//组合式
import { ref, computed } from "vue"
export default{
 setup(){
  const num1 = ref(1)
  const num2 = ref(1)
  let sum = computed(()=>{
   return num1.value + num2.value
  })
 }
}

或者,它可以使用一个带有 get 和 set 函数的对象来创建一个可写的对象。

let mul = computed({
 get:()=>{
  return num1.value *10
 },
 set:(value)=>{
  return num1.value = value/10
 }
})

在vue3.2+内,computed 可接受一个带有 onTrack 和 onTrigger 选项的对象作为第二个参数:

  • onTrack 会在某个响应式 property 或 ref 作为依赖被追踪时调用。
  • onTrigger 会在侦听回调被某个依赖的修改触发时调用。

12、provide / inject

provide/inject 类似于消息的订阅和发布,provide 提供或发送数据或方法, inject 接收数据或方法。

优点:组件嵌套层级较多,父组件向子组件、多个孙组件传值时,传递数据需要一级一级向下传递,比较麻烦,使用 project 和 inject 很方便地解决了这个问题。

//vue2
export default{
 provide:{
  info:"提供数据"
 }
}
//接收数据
export default{
 inject:['info'],
 mounted(){
     console.log("接收数据:", this.info) // 接收数据:提供数据
 }
} 

//vue3
<script setup>
 import { provide } from "vue"
 provide( 'info', "值" )
</script>
//接收数据
<script setup>
 import { inject } from "vue"
 const info = inject( 'info', "设置默认值" )
</script>

13、readonly

readonly 只读函数,使用之后该数据只能使用,不能修改,修改时会有警告。

父子组件之间传值时,如果传递的是响应式数据,子组件修改的时候,父组件的也会更新,这样就容易造成状态混乱,不符合 vue 的单项数据流。

如果使用 readonly ,保证数据在其他组件内只能使用,并不能修改,规避混乱。

14、获取真实DOM

vue2 使用 $ref 获取真实DOM。

vue3 使用 ref 获取真实DOM。与上述的 ref 不同。

<div ref="box" class="test" id="boxtest">获取真实DOM</div>

//vue2
<script>
 export default{
  mounted(){
   console.log('box', this.$refs.box);
  }
 }
</script>

//vue3
<script setup>
 const box = ref(null)
  onMounted(()=>{
  console.log('box',box.value);
 })  
</script>

15、vue3 中的 vuex4

createStore 函数创建新的 store 实例。使用之前需要先引入。

import { createApp } from 'vue'
import App from './App.vue'
import { createStore } from "vuex"

const store = createStore({
 state(){
  return{
   num:1,
  }
 }
})

const app = createApp(App)
app.use(store)
app.mount('#app')

组件内使用 store 时,通过 useStore 引入,使用之前也需要引入。

import { useStore } from "vuex"
const store = useStore()

使用的时候,与低版本都是一样的。使用 state 内数据时,可以通过 toRefs 解构。

16、v-slot

v-slot 指令只能用在 template 或组件上,否则就会报错。

简化 slot、slot-scope 作用域插槽的功能,相比更加强大,代码效率更高。

<child-com>
 <template v-slot:header>
  头部
 </template>
 <template v-slot:body>
  内容
 </template>
</child-com>
<child-com>
 <template #header>
  头部
 </template>
 <template #body>
  内容
 </template>
</child-com>

17、vue3 中的 vue-router4

createRouter 创建 router 实例,之前的 mode 改为 history 。

import { createRouter,createWebHashHistory } from "vue-router";

const routes = []

const router = createRouter({
 history:createWebHashHistory('/'),
 routes
})

export default router

在 main.js 内引入的时候,通过 use 引用。

import { createApp } from 'vue'
import App from './App.vue'
import router from "./router/index"

const app = createApp(App)
app.use(router)
app.mount('#app')

关于 vue-router4 更新挺多的,更多知识请阅读《 vue-router 4 你真的熟练吗?》文章。

18、render

在 vue3 中,render 函数的参数发生了改变,之前的 h 去掉,变成全局引入,虚拟节点具备扁平的属性结构。

vue3中 render 应用

import { h } from "vue"
export default {
 render(){
  return h("div", {}, content)
 }
}

好了小编今天的文章就到此结束了,喜欢我的可以点个关注哦


Recommend

  • 32

    ( 此花无日不春风 ) 其实IdentityServer4的小项目已经基本完结了,但是我总感觉还是有很多东西没有深入挖掘和研究的,这不,二群里有小...

  • 7
    • answerywj.com 4 years ago
    • Cache

    深究strtok系列函数

    深究strtok系列函数 2019-05-21 ...

  • 9

    编者按:本文来自微信公众号 “锋科技”(ID:feng_keji) ,作者:锋科技,编辑:Witkey,36氪经授权发布。 说到近期讨论热烈的互联网大事,QQ一定榜上有名。

  • 9
    • zhuanlan.zhihu.com 4 years ago
    • Cache

    汽车芯片缺货原因深究

    来源:内容由半导体行业观察(ID:icbank)编译自「biz-journal」,笔者:汤之上隆,谢谢。 2020年在全球范围内爆发的新冠肺炎直击汽车行业。汽车需求“蒸发”、全球各车企工厂相继停工。原以为市场需求、汽车生产都会在...

  • 6

    深究AMD R7 3700X,了解大厂英特尔与AMD处理器如何取舍!深究AMD R7 3700X,了解大厂英特尔与AMD处理器如何取舍! 2021-03-16 17:08:54  来源:硬派科技 摘要:很多人盲目奔着华丽的外包装选取产品,但使用...

  • 6
    • blog.fxcdev.com 3 years ago
    • Cache

    AIDL 数据深究

    AIDL 数据深究 Published on Dec 15, 2020 in Program with 0 comment ...

  • 12

    Java动态代理--jdk代理原理深究 祈雨的博客 2016-12-25

  • 8

    Python函数参数默认值的陷阱和原理深究 本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 我们就用实际...

  • 3

    深究Java Hibernate框架下的Deserialization 作者:superLeeH 2022-11-11 10:56:37 对于Hibernate的链子来说,还是要看具体的版本,再次修改POC,自我感觉版本之间的关键方法差异有点大。

  • 3

    依赖注入 (DI) 是.NET中一个非常重要的软件设计模式,它可以帮助我们更好地管理和组织组件,提高代码的可读性,扩展性和可测试性。在日常工作中,我们一定遇见过这些问题或者疑惑。 Singleton服务为什么不能依赖Scoped服务? 多个构造函数的选...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK