comelong blog comelong blog
首页
  • html5
  • JavaScript
  • ES6
  • Vue
  • react
  • Node
  • PHP
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

comelong

永远相信技术的力量
首页
  • html5
  • JavaScript
  • ES6
  • Vue
  • react
  • Node
  • PHP
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • ES6

  • vue

    • vue基础详解
    • vue组件与路由
    • 组件通信与插槽
    • MVC与MVVM
    • vuex状态管理
    • TypeScript基础
    • vue进阶
    • Vue3新特性
      • Vue3的新特性
      • 1.Composition (组合) API
      • 2.setup函数
      • 3.ref
      • 4.reactive
      • 5.toRef(obj,key) 、 toRefs(obj)
      • 6.shallowRef、triggerRef 与 shallowReactive
      • 7.readonly 与 shallowReadonly
      • 8.toRaw 、 markRaw
      • 9.isRef 、unref 、 isReactive 、isProxy 、isReadonly
      • 10.customRef
      • 11.computed、watch、watchEffect
      • 12.生命周期
      • 13.provide 、 inject
      • 14.$refs
      • 15.自定义hook函数
      • 16.其他新特性
        • 全局API
        • 2) v-if 与 v-for 的优先级对比
        • 3) v-for 中的 Ref 数组
        • 4) v-bind合并行为
        • 5) v-model
        • 6) $attrs
        • 7) emits选项
        • 7) 事件 API(eventBus)
        • 8) 函数式组件
        • 9) 异步组件 defineAsyncComponent
        • 10) data选项
      • 17.组件传参
      • 新组件
        • 1. setup语法糖
        • 2. style
        • 3. Fragment(片断)
        • 4. Teleport(瞬移)
    • Vue修饰符
    • VueRoute钩子函数
    • history与hash
    • vue中文件导入&导出
  • h5

  • JavaScript

  • React

  • Git

  • webpack

  • js查漏补缺

  • uniapp

  • 组件封装

  • 前端
  • vue
comelong
2023-01-15
目录

Vue3新特性

# Vue3的新特性

官网地址: https://v3.cn.vuejs.org/guide/migration/introduction.html (opens new window)

# 1.Composition (组合) API

Option API:vue2创建组件时,会把数据放到data,计算属性放到computed,事件处理放到methods,监听改变放到watch;共同处理页面逻辑

  • 组件功能越来越多,逻辑功能点分散,不易阅读(新增或修改一个需求,就需要分别在data,methods等...进行修改,功能多时,滚动条来回滚动 )
  • 可以通过Mixins重用逻辑代码,但是数据来源模糊还会有Mixins命名冲突的问题

Composition API:将零散的data,methods代码重新组合,一个功能的代码放一块儿,并且可以单出拆分出函数

  • 兼容Option API,还可继续使用
  • 利于代码重用,没有对this的使用,减少了this指向不明的情况
  • 几乎是函数,编辑器可以帮我们进行类型检查和建议

# 2.setup函数

  • setup函数是一个新的option,在初始化时执行一次,可以理解为使用Composition API 的入口点。
  • 这个函数的返回一个对象,对象里的属性和方法,可以直接在模版中使用
 <template>
    <div>{{msg}}</div>
  </template>

  <script>
  export default {
    setup () {
      const msg = 'hello World'
      return {
        msg
      }
    }
  }
  </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

注意:

  • 在beforeCreate之前创建,因此,这个函数中没有this。因此不能访问data,methods等。但methods中可以访问setup提供的属性和方法
  • return中返回的属性跟data合并,返回的方法跟methods里的方法合并;如有重名,setup优先
  • setup不能是一个async函数,使用async后返回值不是return的对象,而是promise。非要使用,需要使用<suspense>包裹组件
  • setup接收两个参数setup(props, context) || setup(props, {attrs, slots, emit}) 不能解构props,否则会失去响应式

# 3.ref

  • 定义一个基本数据类型的响应式引用

写法一:选项式 API (Options API)

<template>
    <div>{{num}}</div>
    <button @click="addNum">添加</button>
  </template>

  <script>
  import { ref } from 'vue'
  export default {
    setup () {
      const num = ref(1)
      function addNum () {
        num.value = num.value + 1
      }
      return {
        num,
        addNum
      }
    }
  }
  </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

写法二:组合式 API (Composition API)

<template>
    <div>{{num}}</div>
    <button @click="addNum">添加</button>
</template>
<!-- 表示 script标签内所有代码在 setup函数中 -->
<script setup>
import { ref } from 'vue'
const num = ref(1)
function addNum () {
    num.value = num.value + 1
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12

注意:

  • 在setup中使用ref定义的响应式引用需要.value(内部通过给value属性添加getter、setter实现对数据的劫持),在模版中不需要(解析模板时会自动添加.value)
  • ref常用来处理基本数据类型,如果用ref定义引用数据类型, 内部会自动将对象,数组转换为reactive的代理对象

# 4.reactive

  • 定义响应式引用数据类型

写法一:选项式 API (Options API)

<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <button @click="updateObj">修改</button>
</template>

<script>
import { reactive } from 'vue'
export default {
  setup () {
    const obj = reactive({ name: "张三", age: 25 });
    const updateObj = () => {
      obj.name = "王五";
      obj.age = 21;
    };
    return {
      obj,
      updateObj,
    };
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

写法二:组合式 API (Composition API)

<template>
	<div>{{ obj.name }}</div>
  	<div>{{ obj.age }}</div>
	<div>{{ obj.work }}</div>
  	<button @click="updateObj">修改</button>	
</template>

<script setup>
	import { reactive } from 'vue';
	// 创建响应式对象
    const ob = reactive({
        name:'孙悟空',
        age:18,
        work:'降妖除魔'
    })
    const updateObj = ()=>{
        obj.name = '猪八戒',
        obj.age = 21,
        obj.work = '大闹天宫';
    }
	console.log(obj);
</script>
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 5.toRef(obj,key) 、 toRefs(obj)

  • reactive定义的响应式数据,解构后进行使用,数据就不是响应式的,使用toRef或toRefs将解决这个问题
  • toRef跟toRefs都是复制reactive里的属性然后转成ref。因为是浅拷贝,所以修改复制出来的值时原来reactive里的数据也会跟着更新
  • toRef是复制reactive里的单个key转成ref,toRefs复制reactive里的所有key转成ref
  • 也可以用来将props接收的数据进行解构响应式
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <div>{{ name }}</div>
  <div>{{ age }}</div>
  <button @click="updateObj">修改</button>
</template>

<script setup>
	import { reactive, toRefs, toRef } from "vue";
    const obj = reactive({ name: "张三", age: 25 });
    // const name = toRef(obj, "name");
    // const { msg } = toRefs(props)
    const { name, age } = toRefs(obj);
    const updateObj = () => {
      obj.name = "王五";
      obj.age = 21;
    }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 6.shallowRef、triggerRef 与 shallowReactive

  • ref 和 reactive 是把数据变为响应式,无论层级多深,始终都会对数据进行深度监听。shallowRef和shallowReactive可以解决这个
  • shallowRef 只处理了.value的响应式(只监听.value的变化)。因此如果需要修改应该xxx.value={} 或者使用 shallowRef 将数据强制更新到页面
  • 注:shallowReactive 的数据使用shallowRef 强制更新无效
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <div>{{ obj.c.d }}</div>
  <button @click="updateObj">修改</button>
</template>

<script setup>
	import { shallowRef, triggerRef } from "vue";
    const obj = shallowRef({ name: "张三", age: 25, c: { d: 2 } });
    const updateObj = () => {
      // 这些都不会修改成功,obj对象会变,不会更新到模版
      // obj.value.name = "王五";
      // obj.value.age = 21;
      // obj.value.c.d = 4;
      // 调用此方法,上方数据会更新到页面
      // triggerRef(obj);

      // 如要修改,要用此方法
      obj.value={ name: "王五", age: 21, c: { d: 4 } }
    };
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • shallowReactive 只处理对象最外层属性的响应式(浅响应式),默认情况下只能监听第一次的数据。如要修改则需要先改第一层的数据,然后再去更改其他层的数据
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <div>{{ obj.c.d }}</div>
  <button @click="updateObj">修改</button>
</template>

<script>
	import { shallowReactive } from "vue";
    const obj = shallowReactive({ name: "张三", age: 25, c: { d: 2 } });
    const updateObj = () => {
      // 这样不会监听到修改,obj会变,不会更新到模版
      // obj.c.d = 4;
      // 如要修改需要用下面方法,先改第一层
      obj.name = "王五";
      obj.age = 21;
      obj.c.d = 4;
    };
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 7.readonly 与 shallowReadonly

  • readonly 是让一个响应式数据只读,深层只读
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <div>{{ obj.c.d }}</div>
  <button @click="updateObj">修改</button>
</template>

<script>
	import { reactive, readonly } from "vue";
    let obj = reactive({ name: "张三", age: 25, c: { d: 2 } });
    obj = readonly(obj);
    //这里不会修改成功(还是proxy对象,但obj不会修改成功)
    const updateObj = () => {
      obj.name = "王五";
      obj.age = 21;
      obj.c.d = 4;
      console.log(obj)// 这里obj还等于之前定义的值
    };
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • shallowReadonly 是让一个响应式数据只读,浅层只读(响应式对象的最外层只读,但再深一层的属性可以被修改)
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <div>{{ obj.c.d }}</div>
  <button @click="updateObj">修改</button>
</template>

<script>
	import { shallowReadonly, reactive } from "vue";
    let obj = reactive({ name: "张三", age: 25, c: { d: 2 } });
    obj = shallowReadonly(obj);
    const updateObj = () => {
      //这个不会修改
      obj.name = "王五";
      //这个不会修改
      obj.age = 21;
      //这个会被修改
      obj.c.d = 4;
    };
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 8.toRaw 、 markRaw

  • toRaw 将一个响应式对象(由 reactive定义的响应式)转换为普通对象 [即失去响应式]
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <div>{{ obj.c.d }}</div>
  <button @click="updateObj">修改</button>
</template>

<script>
	import { toRaw, reactive } from "vue";
    let obj = reactive({ name: "张三", age: 25, c: { d: 2 } });
    obj = toRaw(obj);// 使用此方法,obj则变为普通对象(非proxy)
    const updateObj = () => {
      obj.name = "王五";
      obj.age = 21;
      obj.c.d = 4;
    };
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • markRaw 标记一个对象,使其不能成为一个响应式对象
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <div>{{ obj.c.d }}</div>
  <button @click="updateObj">修改</button>
</template>

<script>
	import { markRaw, reactive } from "vue";
    let data = { name: "张三", age: 25, c: { d: 2 } };
    // 在此处标记后,之后使用reactive则不生效(不会成为一个proxy对象),markRaw放到reactive之后则无效
    data = markRaw(data);
    let obj = reactive(data);
    const updateObj = () => {
      obj.name = "王五";
      obj.age = 21;
      obj.c.d = 4;
    };
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 9.isRef 、unref 、 isReactive 、isProxy 、isReadonly

  • isRef 检查值是否为一个 ref 对象。 unref 为val = isRef(val) ? val.value : val 的语法糖
<script setup>
// 定义响应式引用类型
const obj = ref({ name: "张三", age: 25, c: { d: 2 } });
console.log(isRef(obj)) //true
console.log(unref(obj))
</script>
1
2
3
4
5
6
  • isReactive 检查值是否为一个 reactive 对象
<script setup>
const obj = reactive({ name: "张三", age: 25, c: { d: 2 } });
console.log(isReactive(obj)) //true
</script>
1
2
3
4
  • isProxy 检查对象是否是由 reactive 或 readonly 创建的 proxy
<script setup>
const obj = reactive({ name: "张三", age: 25, c: { d: 2 } });
console.log(isProxy(obj))
const obj = readonly({ name: "张三", age: 25, c: { d: 2 } });
console.log(isProxy(obj))
</script>
1
2
3
4
5
6
  • isReadonly 检查对象是否是由 readonly 创建的只读代理
<script setup>
const obj = readonly({ name: "张三", age: 25, c: { d: 2 } });
console.log(isReadonly(obj))
</script>
1
2
3
4

# 10.customRef

  • 创建一个自定义的ref,接受一个函数作为参数,这个函数接受两个参数track(通知vue需要追踪后续内容的变化)trigger(通知vue重新解析模版)
<template>
  <input type="text" v-model="inpValue">
  <div>{{inpValue}}</div>
</template>
<script>
import {customRef} from "vue";
    // 自定义一个 myRef
    function myRef(value) {
      return customRef((track, trigger) => {
        return {
          get() {
            track() // 追踪后续数据的变化
            return value
          },
          set(newValue) {
            value = newValue
            trigger() // 重新解析模板
          }
        }
      })
    }
    let inpValue = myRef('hello')
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 11.computed、watch、watchEffect

在setup中也有单独的computed和watch用法基本相同

watchEffect是监视所有回调中使用的数据,因为每次初始化的时候都会执行一次回掉自动获取依赖,并不用手动传需要监听的对象。注:无法获取到oldValue

# 12.生命周期

  • setup中也有新的生命周期onBeforeMount -> onMounted -> onBeforeUpdate -> onUpdated -> onBeforeUnmount -> onUnmounted -> onErrorCaptured跟options api混用时onBeforeMount在beforeMount之前,onMounted在mounted之前。。。之后都是
  • vue中父子顺序 父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted在setup中声明周期也适用

# 13.provide 、 inject

  • provide 、 inject提供依赖注入 ,实现祖孙级组件通信

父组件

<template>
  <h1>父组件</h1>
  <one />
</template>
<script>
import { provide, ref } from 'vue'
import one from './one.vue'
export default {
  components: {
    one
  },
  setup() {
    const msg = ref('red')
    provide('msg', msg)
    return {
      msg
    }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

子组件【one】

<template>
  <div>子组件</div>
  <two />
</template>
<script>
import two from './two.vue'
</script>
1
2
3
4
5
6
7

孙子组件【two】

<script>
	import { inject } from 'vue'
    const msg = inject('msg')
</script>
1
2
3
4

# 14.$refs

  • 在vue2中使用 this.$refs.XXX 获取,vue3中setup函数没有this,所以也有单独的获取ref的方法
<template>
  <input type="text" ref="inputRef" value="这是input的文本"/>
</template>

<script>
	import { onMounted, ref } from "vue";
    const inputRef = ref(null);/// 本质是reactive({value:null})
    onMounted(() => {
      console.log(inputRef.value.value);
    });
    console.log(inputRef.value);// null dom还没形成
</script>
1
2
3
4
5
6
7
8
9
10
11
12

# 15.自定义hook函数

  • 与mixin类似,抽离公共代码

hookTest.js

import { reactive } from "vue";
export default function hookTest() {
  const obj = reactive({ name: "张三", age: 25 });
  return { obj };
}
1
2
3
4
5
<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
</template>

<script>
	import hookTest from './hookTest'
    const {obj} = hookTest()
    return { obj };
</script>
1
2
3
4
5
6
7
8
9
10

# 16.其他新特性

# 全局API

在vue2中的main.js中有以下代码。如果使用全局api则是 Vue.directive、Vue.component、Vue.config、Vue.mixin、Vue.prototype等,都是挂载在Vue原型上

import Vue from 'vue'
import App from './App.vue'

const app = new Vue(App)
app.$mount()
1
2
3
4
5
  • vue3提供的是实例api。通过createApp创建vue实例
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
1
2
3
4

# 2) v-if 与 v-for 的优先级对比

  • 在vue2中:当v-if和v-for同时使用时,v-for的优先级高于v-if(因此我们通常需要计算属性先对数据进行加工处理,以达到性能优化的目的)
  • 在vue3中:当v-if和v-for同时使用时,v-if的优先级高于v-for

# 3) v-for 中的 Ref 数组

  • vue2中,在 v-for 语句中使用ref属性,会生成refs数组插入$refs属性中
<div v-for="item in 5" :key="item" :ref="item">
  {{ item }}
</div>
this.$refs将会是个数组
1
2
3
4
  • vue3中,在v-for中使用ref属性,将不会自动在$refs里创建数组,而是将ref绑定到一个函数中,在函数中可以处理ref
<template>
  <div v-for="item in 5" :key="item" :ref="setItemRef">
    {{ item }}
  </div>
</template>

<script>
import { onMounted } from "vue";
    const refArray = [];
    const setItemRef = (e) => {
      refArray.push(e);
    };
    onMounted(() => {
      console.log(refArray);
    });
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 4) v-bind合并行为

  • vue2如果一个标签同时定义了动态属性和一个相同的单独的属性,那么这个单独的属性总是会覆盖动态属性。说明单独属性优先级高于动态属性
 <div id="red" :id="'blue'"></div>
 <!--这里div只会绑上id等于red-->
1
2
  • vue3将会把动态属性跟单独属性合并
<div id="red" :id="'blue'"></div>
<!--结果为-->
<div id='red blue'></div>
1
2
3

# 5) v-model

  • vue2中,在组件上使用v-model默认prop与event为value和input。如要修改,通过子组件的model选项中的prop值和event值来指定属性名和事件名。
<child v-model="pageTitle" />
<!--等同于-->
<child :value="pageTitle" @input="pageTitle = $event" />
1
2
3
export default {
  model: {
    prop: 'title',
    event: 'change'
  },
  props: {
    title: {
      type: String,
      default: 'Default title'
    }
  },
  methods:{
    handleClick(val) {
      this.$emit('change', val)
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

除了使用上面方法对某一个prop进行 ‘双向绑定’ 还可以通过这种方式 v-bind.sync

vue3中v-bind 的 .sync 修饰符已移除。:title.sync就要替换为v-model:title

<child :title="pageTitle" @update:title="pageTitle = $event" />
<!--等同于-->
<child :title.sync="pageTitle" />
1
2
3
this.$emit('update:title', newValue)
1

vue3默认prop与event为modelValue和update:modelValue。如要修改,直接通过v-model后面参数v-model:title来指定属性名,并且支持绑定多个v-model。

<child v-model="pageTitle" />
<!--等同于-->
<child :modelValue="pageTitle" @update:modelValue="pageTitle = $event" />
1
2
3
  • 如果需要修改model的名称,我们可以为v-model传递一个参数,作为子组件内model选项的代替
<child v-model:title="pageTitle" />
<!--等同于-->
<child :title="pageTitle" @update:title="pageTitle = $event" />
1
2
3

# 6) $attrs

  • vue2中使用 v-bind='$attrs' 进行将父组件不被认为props特性绑定的属性传入子组件(不包含class以及style),配合interitAttrs一起使用,如果为true则将所有attribute添加到子组件的跟标元素上。但如果为false时,因为class以及style不属于$attrs,所以仍会添加到组件的跟元素上
  • vue3中$attrs包含所有传递给子组件的attribute,包含class以及style

# 7) emits选项

  • vue2中子组件触发父亲组件的方法this.$emit(方法名)
  • vue3提供了一个类似props的emits选项,emits选项可以配置校验emit事件,为null的时候不校验。校验时会把参数携带过去,当校验不通过,控制台会发出一个警告,但emit事件还会继续执行
  • 官方建议我们在组件中所有的emit事件都能在组件的emits选项中声明
<template>
  <one @open="open" />
</template>
<script>
import one from "./one.vue";
export default {
  components: {
    one,
  },
  setup() {
    open = () => {
      console.log(1);
    };
    return {
      open,
    };
  },
};
</script>
<!--子组件-->
<template>
  <div @click="open">点击</div>
</template>
<script>
export default {
  emits: {
    //open: null,
    open: (value) => {
      if (typeof value === "string") {
        return true;
      } else {
        return false;
      }
    },
  },
  setup(props, { emit }) {
    open = () => {
      emit("open", 11);
    };
    return {
      open,
    };
  },
};
</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

# 7) 事件 API(eventBus)

  • 移除$on,$off 和 $once 实例方法,组件实例不再实现事件触发接口。

# 8) 函数式组件

  • 函数式组件有两个特性1、Stateless无状态:组件自身没有状态 2.Instanceless无实例:组件自身没有实例,也就是没有this
  • vue2中,函数式组件通常用为性能优化,它的初始化速度比有状态组件快的多
Vue.component('typeButton',typeButton)
const typeButton = {
  functional:true,//标记,无状态无实例
  render(h , { props }){
    const { type } = props
    return <div class={ type }>{type}</div>
  }
}
1
2
3
4
5
6
7
8
  • vue3中不需要functional定义 接收两个参数,props和context。context包含组件的 attrs、slots 和 emit property
import { h } from 'vue'
const DynamicHeading = (props, context) => {
  return h(`h${props.level}`, context.attrs, context.slots)
}
DynamicHeading.props = ['level']
export default DynamicHeading
1
2
3
4
5
6

# 9) 异步组件 defineAsyncComponent

const asyncModal = () => import('./Modal.vue')
//带有选项
const asyncModal = {
  component: () => import('./Modal.vue'),
  delay: 200,
  timeout: 3000,
  error: ErrorComponent,
  loading: LoadingComponent
} 
1
2
3
4
5
6
7
8
9
  • vue3中函数式组件被定义为纯函数,因此异步组件需要包裹在defineAsyncComponent中
import { defineAsyncComponent } from 'vue'
const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))
//带有选项
const asyncModalWithOptions = defineAsyncComponent({
  loader: () => import('./Modal.vue'),
  delay: 200,
  timeout: 3000,
  errorComponent: ErrorComponent,
  loadingComponent: LoadingComponent
})
1
2
3
4
5
6
7
8
9
10

# 10) data选项

  • vue2中,可以通过Object或者function定义data选项
<!-- Object -->
<script>
  const app = new Vue({
    data: {
      num: 1
    }
  })
</script>
<!-- Function -->
<script>
  const app = new Vue({
    data() {
      return {
        num: 2
      }
    }
  })
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • vue3中,data只接受返回object的function
<script>
  import { createApp } from 'vue'

  createApp({
    data() {
      return {
        num: 1
      }
    }
  }).mount('#app')
</script>
1
2
3
4
5
6
7
8
9
10
11

# 17.组件传参

  • 父传子

    
    
    1
  • 子传父

  • 兄弟组件传参

# 新组件

# 1. setup语法糖

setup这个option,暴露变量必须都return出来,模板中才能使用。vue3也提供了相关语法糖,不用export ,也不需要写setup函数

需要将 setup attribute 添加到 <script> 代码块上.变量跟函数都不需要return,即可在模板中使用

引入组件可以直接使用,不需要通过components进行注册

<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
</template>

<script setup>
import { ref } from "vue";
const obj = ref({ name: "张三", age: 25, c: { d: 2 } });
</script>
1
2
3
4
5
6
7
8
9

# 2. style

# 3. Fragment(片断)

  • 在vue2中组件必须要有一个根标签
  • vue3组件里可以没有根标签,vue3内部会把多个标签放在一个Fragment虚拟元素中

# 4. Teleport(瞬移)

  • <teleport> 用于移动dom到指定元素

  • 还可配置disabled属性,禁用teleport的功能,不会移动到任何位置,但他仍会出现在正常位置下(里面的所有元素依然保持正常状态)

    <teleport to="#some-id" />
    <teleport to=".some-class" />
    <teleport to="[data-teleport]" />
    <teleport to="body" disabled=‘true’>
      <div></div>
    </teleport>
    
    
    1
    2
    3
    4
    5
    6
    7

    此片文章均内容来自于:https://www.jianshu.com/p/550fd8c4cde2 (opens new window)

编辑 (opens new window)
上次更新: 2023/11/01, 22:15:03
vue进阶
Vue修饰符

← vue进阶 Vue修饰符→

最近更新
01
Api接口
07-30
02
分页组件
07-06
03
mongodb
05-07
更多文章>
Theme by Vdoing | Copyright © 2019-2023 comelong | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式