vue3入门-基础篇

米阳 2022-3-18 722 3/18

目前公司项目都是vue2,其实真要把公司项目从vue2升级到vue3成本还是挺大的,尤其是公司内部在用的管理后台。后面想着如果有新项目就开始用vue3进行开发。

本篇主要总结一下:组合式api、响应式数据、计算属性、监听、ref、生命周期。

Vue CLI 是官方提供的基于 Webpack 的 Vue 工具链,它现在处于维护模式。我们建议使用 Vite 开始新的项目,除非你依赖特定的 Webpack 的特性。

具体详细介绍vite到这篇文章——vite学习指南

options Api 和 composition Api

Vue 2 使用的是选项式 API,而 Vue 3 引入了组合式 API

虽然 Vue 3 推荐使用组合式 API,但它仍然完全支持 Vue 2 的选项式 API,以保持向下兼容性。所以在 Vue 3 中,你可以自由选择使用选项式 API 或组合式 API 来编写你的组件逻辑。

选项式API有一个缺点:新增一个功能,需要分别在 data、methods、computed、watch等选项中修改代码,如果代码上千,修改或抽取封装这部分功能,有困难。

setup

setup 函数是组合式 API 的入口,用于组合组件的逻辑和功能。

<template>
  <div>
    <p>num: {{ num }}</p>
    <p><button @click="addfn">num+1</button></p>
  </div>
</template>

<script>
//vue2中会这样写
export default {
    name: 'App',
    data() {
        return {
          num: 0,
        }
    },
    methods: {
      addfn() {
        this.num += 1;
      }
    }
}
//vue3中这样写
export default {
    name: 'App',
    setup() {
      let num= 0;

      function addfn(){
        num += 1;
      }
      // 将数据和方法都交出去
      return {num, addfn}
    }
}
</script>

对比一下简单理解就是把vue2 data 和 methods 两个配置去除,改成 setup 就完成了 vue3 示例的重构

setup 是一个方法,平时如何定义变量和方法,这里就怎么写,最后将方法和变量都交出去。

这里其实还有一个问题,点击事件 num在界面没变,但方法却执行了。这是因为 num 变量不是响应式的。

现在我们先说 setup,后面在聊响应式的东西。这里要修复可以使用 ref(这个 ref 和 vue2 中指向元素或组件的ref,不是同一个东西):

<script>
  import {ref} from 'vue'
  export default {
    name: 'App',
    setup() {
      let num= ref(0)
      function addfn(){
        num.value = +=1;
      }
      // 将数据和方法都交出去
      return {num, addfn}
    }
  }
</script>

另外 setup 中的 this 是undefined,vue3 开始弱化 this。

最后说一下 setup 执行时机,比 beforeCreat 还早:

  beforeCreate() {
    console.log(1);
  },
  setup() {
    console.log(2);
  }
//先输出 2 再输出 1

setup语法糖

//方式1
setup() {
  let num = ref(0);

  function addfn() {
    num .value  +=1;
  }
  // 将数据和方法都交出去
  return { num , addfn };
},

//方式2
<script setup>
// 属性和方法自动交出去
let num = ref(0);

function addfn() {
  num.value +=1;
}
</script>

响应式数据

vue2 中放在 data 中的数据都是响应式的,在vue3 中可以通过 ref和reactive 两种方式来处理响应式。

<template>
  <div>
    <!-- 不能写 date.value,这里自动会给 value -->
    <p>ref方式绑定响应式数据</p>
    <p>num: {{ num }}</p>
    <p><button @click="addfn">num+1</button></p>

    <p>reactive方式绑定响应式数据</p>
    <p>person.num: {{ person.num }}</p>
    <p><button @click="addfnReactive">person.num+1</button></p>
  </div>
</template>
<script setup>
import { ref,reactive } from "vue";
// 通过ref包裹后,类型变成 RefImpl。需要通过 .value 来访问和修改实际的值。 let num = ref(0); // 使用 ref 创建变量时,实际上你得到的是一个包含了值的对象,而不是直接的值。因此,在修改这个变量时,你需要通过 .value 来访问和修改实际的值,这样 Vue 才能够正确地追踪变化并进行响应。 // 使用 ref 创建的变量必须通过 .value 来访问和修改其值,这是为了确保 Vue 能够正确捕捉变化并更新视图。 function addfn() { // 通过 value 修改响应式数据。 num.value += 1; } // 通过 reactive 封装后的对象类型变成 Proxy。 const person = reactive({ num: 0 }) function addfnReactive() { person.num += 1; } </script> 

ref vs reactive

1、宏观:

  • ref 能定义基本类型和对象的响应式数据
  • reactive 只能用于对象

写代码时还得记着是 ref 类型,需要增加 .value,好麻烦。这里安利一个 vscode 插件:

vscode 直接安装 Vue - Official(vscode 提示 TypeScript Vue Plugin (Volar) 已弃用,使用 Vue - Official 替代)

通过 vscode 设置,勾选 Auto-complete Ref value with .value,并设置 Applies to all profiles

2、使用场景

reactive 重新分配一个对象,会失去响应式(可使用 Object.assign 整体替换)

由于这些限制,我们建议使用 ref() 作为声明响应式状态的主要 API —— 官网 - reactive 局限性

个人习惯:

  • 需要一个基本类型的响应式数据,只可使用 ref
  • 对象使用 reactive
  • 如果是表单,使用 ref 会出现很多 .value,不好看

toRefs

将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。

不明白请看下面代码。

<template>
  <section>
    <p>name: {{ person.name }}</p>
    <p>age: {{ person.age }}</p>
    <p><button @click="changeAge">change age</button></p>
  </section>
</template>
<script setup>
import { ref, reactive, toRefs  } from "vue";
let person = reactive({
  name: "dami",
  age: 18,
})
//从响应式对象中解构出 age,然后通过方法修改 age 的值,发现页面没更新:
let {age} = person;
function changeAge () {
  age+=1;
}
//这是因为解构出的 age 不在是响应式。可以使用 toRefs,就像这样 这样age就变成了响应式
let {age} = toRefs(person);
function changeAge () {
  age.value+=1;
}
</script>

计算属性

//vue2中这样写
computed: {
  now: function () {
    return Date.now();
  }
}
//vue3中这样写
let now = computed(() => {
  return Date.now()
})

watch

vue3 中说 watch 只能监视4种数据:

  • ref定义的数据
  • reactive 定义的数据
  • 函数返回一个值(getter函数)
  • 一个包含上述内容的数组
<template>
  <section>
    <p>age: {{ age}}</p>
    <p><button @click="age += 1">change age</button></p>
    <p><button @click="stopWatch">停止监听 age 变化</button></p>
  </section>
</template>
<script setup>
import { ref, watch } from "vue";
let age = ref(18) 
let stopWatch = watch(age, (newValue, oldValue) => {
  console.log('年龄从', oldValue, '变为', newValue);
});
</script>
  • watch 监视的ref变量,无需增加 .value。安装好vscode 插件,在这种情况下也不会自动给你加 .value。
  • watch 返回一个函数,执行后将解除监视。就像 vue2 中的 vm.$watch 方法,返回 unwatch。

监视对象中的属性

前面我们监视的都是整个对象,比如现在要监视对象中的某个属性。这里分为基本类型对象类型

// reactive 和 ref 都可以用如下形式
// 利用 getter。如果需要则增加 deep
watch(() => person.car, (new, old) => {
  console.log(new)
}, {deep: true})

生命周期

使用步骤

  1. 先从vue中导入以on打头的生命周期钩子函数
  2. 在setup函数中调用生命周期函数并传入回调函数
  3. 生命周期钩子函数可以调用多次
<template>
  <div>生命周期函数</div>
</template>

<script>
import { onMounted } from 'vue'
export default {
  setup() {
    // 时机成熟 回调函数自动执行
    onMounted(() => {
      console.log('mouted生命周期执行了')
    })
     onMounted(() => {
      console.log('mouted生命周期函数又执行了')
    })
  }
}
</script> 

vue3入门-基础篇

 

 

 

 

 

- THE END -

米阳

3月17日11:45

最后修改:2025年3月17日
0

非特殊说明,本博所有文章均为博主原创。