嘎嘎学习之Vue2到Vue3的转变 | 青训营笔记

98 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第十七天

前端技术正在飞速发展,在做青训营大项目的时候才发现Vue2+Javascript已经完完全全是过去式了,现在最新的技术都是基于Vue3+Typescript+vite,所以为了紧跟前端技术发展,会将之后的学习重点由Vue2转向Vue3,其中Vue3最大的特点就是组合式API即setup语法糖,这对于我们维护一个大型的组件有者很大的帮助,显然Vue2的选项式API已经难以适应大型项目了。

1.使用vite创建vue3项目

  1. 执行以下命令创建vue3项目
 # npm 6.x
 npm init vite@latest my-vue-app --template vue
 ​
 # npm 7+, 需要额外的双横线:
 npm init vite@latest my-vue-app -- --template vue
 ​
 # yarn
 yarn create vite my-vue-app --template vue
 ​
 # pnpm
 pnpm create vite my-vue-app -- --template vue

注:这里的my-vue-app是项目名可以自定义,后面表示使用vue模板

2. Vue的一些知识

2.1 watch深度监听

正常watch监听只能监听一个变量,当变量是一个对象的时候,无法监听到这个对象内部的属性,这个时候就需要用到深度监听

 <script>
     export default{
         data(){
             return{
                 // 这里的user就是一个对象
                 user:{
                     name:'jiajia',
                     age:'18',
                     sex:'man'
                 }
             }
         },
         watch:{
             // 这个监听的是user对象的变化,就是user对象内所有属性变化都会触发
             user:{
                 handler(newVal){
 ​
                 }
                 // 深度监听
                 deep:true
                 // immediate 属性用来声明此侦听器,是否在页面初次加载完毕的时候立即调用
                 immediate: true
             },
             // 如果只想监听user下的某一个属性可以使用字符串的形式,这样的话可以不需要深度监听
             "user.name":{
                 handler(newVal){
 ​
                 }
                 // 深度监听(可以去掉)
                 // deep:true
             }
         }
     }
 </script>

2.2 class的绑定

1. 对象语法(不常用)

active是要设置的类名,后面的Boolean值是用来判断是否加上这个值

 <p :class="{active:boolean}"></p>

由于是一个对象,所以可以同时给多个类名

 <p :class="{active:boolean1,helloworld:boolean2}"></p>

并且可以和普通类同时存在,不会冲突

还可以与计算属性 computed 组合使用

 <template>
 <!-- classObject是一个计算属性-->
 <p :class="classObject"></p>
 </template>
 <script>
     export default{
         data(){
             return{
                 isActive:true,
                 error:{}
             }
         },
         computed:{
             classObject(){
                 return{
                     // 当页面不报错的时候展示active,报错的时候展示helloWorld
                     active:this.isActive && !this.error,
                     helloWorld:this.error
                 }
             }
         }
     }
 </script>

2. 数组语法(不常用)

 <template>
     <!-- 这里的message实际展示的是data里的message的值-->
     <p :class="[message,detail]"></p>
 </template>
 <script>
     export default{
         data(){
             return{
                 message:'active',
                 deatil:'jiajia'
             }
         },
     }
 </script>

3. 还可以结合使用,就不多说了

3. Vue3新特性

3.1 支持多个根节点

在vue2中template下只能有一个根节点,但是在vue3中没有这个限制

 <template>
 <div>这是第一个根节点</div>
 <div>这是第二个根节点</div>
 </template>

注:但是由于vscode插件尚未更新,使用多个根节点eslint会报错,所以还是建议使用一个根节点

3.2 组合式api

选项式api在一个大型的组件内会变得难以维护,这时候就可以使用组合式api

怎么个组合法呢,就是把数据和数据相关的方法放在一起,使其相关联起来

 <script setup>
 import { ref, onMounted } from 'vue'
 ​
 // 响应式状态
 const count = ref(0)
 // 用来修改状态、触发更新的函数
 function increment() {
   count.value++
 }
 ​
 // 生命周期钩子
 onMounted(() => {
   console.log(`The initial count is ${count.value}.`)
 })
 </script>
 ​
 <template>
   <button @click="increment">Count is: {{ count }}</button>
 </template>

1. 生命周期钩子的变化

在vue3中setup函数的执行是在组件被创建之前

setup函数取代了beforecreatecerated,在这两个钩子函数内的方法都应该写在setup里

2. setup中无法再使用this来指向组件实例

由于setup的调用发生在组件创建之前,所以data,property,computed、methods等都无法被this获取

3. 使用ref()来定义响应式变量

在setup中的数据并不是响应式的,这意味着我们修改的状态并不会在页面更新,如果我们需要一个变量变为响应式,那么就要使用到 ref

 <template>
 <!--这里的count不需要加上 .value, 因为模板会自动浅解析一层 -->
 <button @click="increment">Count is: {{ count }}</button>
 </template>
 <script setup>
     //导入ref
     import { ref } from 'vue'
 ​
     // 通过ref定义响应式状态,里面的0表示count定义的初始值为0 
     const count = ref(0)
     function increment(){
         // 由于是通过ref定义的,会返回一个带有value 的property对象,所以要通过.value获取值
         count.value++
     }
 </script>

4. 使用 reactive()来定义一个响应式的对象或者数组(少用)

 <template>
 <div>{{ state.count }}</div>
 </template>
 <script setup>
     //导入reactive
     import { reactive } from 'vue'
 ​
     // 通过reactive来定义响应式对象或者数组
     const obj = reactive({ 
         name:"张三",
         age:"18"
     })
 </script>

注:实际上使用ref()也可以定义响应式对象,看自己喜欢进行使用

注意:由于对象的解构(传播操作符... )实际上是一层拷贝,所以结构通过ref或者reactive定义的变量会使其失去响应式,如果想让结构之后的对象维持响应式就要加入 toRefs