Vue3笔记

一、常用Composition API(常用组合式API)

1. man.js文件

// 引入一个工厂函数 createApp
import { createApp } from 'vue'
import App from './App.vue'

// 创建应用实例对象 app --- 类似于vue2中的vm,但app比vm更'轻'
const app = createApp(App)
console.log('app', app)
app.mount('#app')

2. setup函数

  是vue3中一个新的配置,值是一个函数。组件中所用到的数据,方法等等,均要配置在setup中。setup有两种返回值,若返回对象,则对象中的属性,方法,在模板中均可以直接使用。若返回一个渲染函数,则可以自定义渲染内容。一般不推荐vue2和vue3混用,若data和setup混用,则data可以访问setup中的属性,方法,setup不能访问data中的内容,如果有重名,setup的值优先使用。setup不能用async修饰。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)。

3. ref函数

作用:定义响应式数据。

语法:const xxx = ref(initValue)

  创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。

  js中操作数据:xxx.value;。

  模板中读取数据:不需要.value, 直接 <div>{{xxx}}</div>

备注:

  接收的数据可以是:基本类型、也可以是对象类型。

  基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的。

  对象类型的数据:内部使用了vue3.0中的一个新函数reactive函数。

3. reactive函数 

  作用:定义一个对象类型的响应数据(基本类型不要用它,要用ref函数)。

  语法:const 代理对象 = reactive(源对象)接收一个对象或 数组,返回一个代理对象(Proxy的实例对象,简称proxy对象)。

  reactive定义的响应式数据是“深层次的”。

  内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作。

4. vue3.0 中的响应式原理

  vue2.0响应式的实现原理:

  对象类型:通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)。

  数组类型:通过 重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

  存在问题:新增属性,删除属性,界面不会更新。直接通过下标修改数组,界面不会自动更新。

     vue3.0响应式实现原理:

  通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等。

  通过Reflect(反射):对被代理对象的属性进行操作。

6. setup的两个注意点

  setup执行的时机:在beforeCreate之前执行一次,this是undefined。

  setup的参数

    props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。

    context:上下文对象。

      attrs:值为对象,包含:组织外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs。

      slots:收到的插槽内容,相当于this.$slots。

      emit:分发自定义事件的函数,相当于this.$emit。

7. 计算属性与监听

computed函数(与vue2.0配置功能一致)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import {computed} from 'vue'
export default {
  setup() {
    // 计算属性---简写(没有考虑计算属性被修改的情况)
    /*person.fullName = computed(() => {
      return person.firstName + '-' + person.lastName
    })*/
 
    // 计算属性---完整写法,考虑读和写
    person.fullName = computed({
      get(){
        return person.firstName + '-' + person.lastName
      },
      set(val){
        const nameArr = val.split('-')
        person.firstName = nameArr[0]
        person.lastName = nameArr[1]
      }
    })
  }
}

watch函数

  监视reactive定义的响应式数据时:oldValue无法正确获取,强制开启了深度监视(deep无效)。

  监视reactive定义的响应式数据中某个属性时:deep配置有效。

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
// 情况一:监视ref所定义的一个响应式数据
watch(sum, (newVal, oldVal) => {
  console.log(`sum的值变化了${newVal}, ${oldVal}`)
}, {immediate: true, deep: true})
 
// 情况二:监视ref所定义的多个响应式数据
watch([sum, msg], (newVal, oldVal) => {
  console.log(newVal);
  console.log(oldVal);
  console.log(`sum的值变化了${newVal}, ${oldVal}`)
}, {immediate: true, deep: true})
 
// 情况三:监视reactive所定义的一个响应式数据
// 注意:无法正确获取oldValue
// 注意:强制开启了深度监听(deep配置无法关闭)
watch(person, (newVal, oldVal) => {
  console.log('person变化了',newVal, oldVal)
}, {deep: false})
 
 
// 情况四:监视reactive所定义的一个响应式数据中的某个属性
watch(() => person.age, (newVal, oldVal) => {
  console.log('person的age变化了',newVal, oldVal)
})
 
// 情况五:监视reactive所定义的一个响应式数据中的某些属性
watch([() => person.age, () => person.name], (newVal, oldVal) => {
  console.log('person的age或name变化了',newVal, oldVal)
})
 
// 特殊情况 (监听对象中的某个属性对象,需要开启deep:true配置)
watch(() => person.job, (newVal, oldVal) => {
  console.log('person的job变化了',newVal, oldVal)
}, {deep:true})
watchEffect函数
  watchEffect不用指定监视哪一个属性,监视的回调中用到哪个属性,就监视哪个属性。
8. 生命周期函数
  配置形式的生命周期钩子。

  组合式api形式的生命周期钩子,放在setup中执行。两种形式同时写的话,组合式api的形式执行早于配置式。

 

9. 自定义hook函数

  把setup函数中使用的Composition API进行了封装。

  类似vue2.x中的mixin。

  自定义hook的优势:复用代码,让setup中的逻辑更清除易懂。

10. toRef

  作用:创建一个ref对象,其value值指向另一个对象中的某个属性。

  语法:const name = toRef(person,'name');。

  应用:要将响应式对象中的某个属性单独提供给外部使用时。

  扩展:toRefs与toRef功能一致,但可以批量创建多个ref对象,语法:toRefs(person);。

三、其他Composition API(其他组合式api,不常用,但需要了解)

1. shallowReactive与shallowRef

  shallowReactive:只处理对象最外层属性的响应式(浅响应式)。

  shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。

  什么时候使用?

    如果有一个对象数据,结构比较深,但变化时只是外层属性变化===>shallowReactive。

    如果有一个对象数据,后续功能不会修改该对象中的属性,而是新的对象来替换===>shallowRef。

2. readonly与shallowReadonly

  readonly:让一个响应式数据变为只读的(深只读),内层属性和外层属性都只读。

  shallowReadonly:让一个响应式数据变为只读的(浅只读),外层属性只读,内层属性可以编辑。

  应用场景:不希望数据被修改时。

3. toRaw与markRaw

  toRaw

    作用:将一个由reactive生成的响应式对象转为普通对象。

    使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。

  markRaw

    作用:标记一个对象,使其永远不会再成为响应式对象。

    应用场景:

      1. 有些值不应该被设置为响应式,例如复杂的第三方类库等。

      2. 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

4. customRef

  作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制。

5. provide与inject

  作用:实现祖孙组件通信。

  套路:父组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据。

  具体写法:

    祖组件:provide('car', car);

     后代组件:let car = inject('car');

6. 响应式数据的判断

  isRef:检查一个值是否为一个ref对象。

  isReactive:检查一个对象是否是由reactive创建的响应式代理。

  isReadonly:检查一个对象是否由readonly创建的只读代理。

  isProxy:检查一个对象是否由reacitve或者readonly方法创建的代理。

四、Composition API的优势

1. Options API 存在的问题

  使用传统OptionsAPI中,新增或修改一个需求,就需要分别再data,methods,computed里修改。

2. Composition API的优势

  我们可以更加优雅的组织我们的代码,函数。让相关功能的代码更加有序的组织在一起。

五、新的组件

1. Fragment

  在vue2中:组件中必须有一个根标签。

  在vue3中:组件可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中。

  好处:减少标签层级,减小内存占用。

2. Teleport

  Teleport是一种能够将我们的组件html结构移动到指定位置的技术。

3. Suspense

  等待异步组件时渲染一些额外内容,让应用有更好的用户体验。

1
2
3
4
5
6
7
8
9
10
11
12
13
  <Suspense>
    <template v-slot:default>
      <Child/>
    </template>
    <template v-slot:fallback>
      <h3>加载中...</h3>
    </template>
  </Suspense>
 
 
import {defineAsyncComponent} from 'vue'
// 异步引入组件
const Child = defineAsyncComponent(()=>import('./components/Child'))

六、其他

1. 全局API的转移

  vue2.x有许多全局API和配置。例如:注册全局组件、注册全局指令等。

  vue3.x中对这些API做出了调整:将全局API,即Vue.xxx调整到应用实例(app)上。

2. 其他改变

  data选项应该始终被声明为一个函数。

  过渡类名的修改。

  移除keyCode作为v-on的修饰符,同时也不再支持config.keyCodes。

  移除v-on.native修饰符。

  移除过滤器(filter)。

posted @   record-100  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示