首页 前端知识 Vue2过渡Vue3

Vue2过渡Vue3

2024-08-21 22:08:03 前端知识 前端哥 21 98 我要收藏

Vue3

vue2为选项是(options)API,Vue3为组合是API

相比于Vue2优势:

在这里插入图片描述

1. 创建Vue3项目

前置条件:必须保证node的版本高于16.0

创建vue3项目:

npm init vue@latest

2. setup

setup本质:需要将数据和方法return才能给模板使用

<script>
  export default {
    setup(){
      const message = 'this is message'
      const logMessage = ()=>{
        console.log(message)
      }
      // 必须return才可以
      return {
        message,
        logMessage
      }
    }
  }
</script>

语法糖:直接在script标签上加上setup

<script setup>
  const message = 'this is message'
  const logMessage = ()=>{
    console.log(message)
  }
</script>

3. 响应式数据 - reactive和ref函数

3.1 reactive()

接受对象类型数据的参数传入并返回一个响应式的对象,不接受简单数据类型

<script setup>
import { reactive } from 'vue'
// 响应式数据
 // 1. 使用reactive()包装,只能包装对象类型数据
const state = reactive({
  count: 1
})

const add = () => {
  state.count++
}
</script>

<template>
  <div>
    <!-- reactive() -->
    {{ state.count }} <br>
    <button @click="add">+1</button>
  </div>
</template>

3.2 ref()

接收简单类型或者对象类型的数据传入并返回一个响应式的对象

在js中访问得加.value,在模板中直接使用

<script setup>
import {  ref } from 'vue'
// 响应式数据

// ref() 可以包装基本类型数据, 也可以包装对象类型数据
// 在js中获取数据需要.value获取,在模板中不需要
let count = ref(1)
const addTwo = () => {
  // js中需要.value获取
  count.value += 2
}
</script>

<template>
  <div>
    <!--  ref()-->
    <!--  模板中使用直接使用-->
    {{ count }}
    <button @click="addTwo">+2</button>
  </div>
</template>

4. computed

用法和vue2一样,只是写法上发生了改变,computed() 为函数,在函数里面写回调函数,计算要计算的数据

<script setup>
import { computed, ref } from "vue";

const arr = ref([0, 1, 2, 3, 4, 5])
// computed函数里写箭头函数
const computedArr = computed(() => arr.value.filter((item) => item > 2))
let num = 6

const timer = setInterval(() => {
  num += 2
  arr.value.push(num)
  if (num > 10) {
    clearInterval(timer)
  }
}, 2000)

</script>

<template>
<div>
  初始数组:{{ arr }}
  <br>
  computed: {{ computedArr }}
</div>
</template>

<style scoped>

</style>

5. watch

侦听一个或者多个数据的变化,数据变化时执行回调函数,俩个额外参数 immediate控制立刻执行,deep开启深度侦听

watch()函数第一个参数为监听的ref对象,第二个参数为监听的回调函数,可以监听到新值和旧值,第三个参数为额外参数的对象

  1. 监听单个数据
  2. 监听多个,watch函数中要监听的数据写成数组的形式
  3. 深度监听deep:watch默认为浅层监听,只能监听到基本数据类型的数据的改变,复杂类型只能监听到对应的地址
  4. 监听器创建时立即执行一次,发生改变时继续执行immediate
  5. 监听复杂数据类型中指定的数据,第一个参数为回调函数的写法,函数体内写要监听的数据
<script setup>
import { ref, watch } from "vue";

const count = ref(1)
const message = ref("Hello")
const user = ref({
  age: 18,
  name: 'zs'
})
// watch第一个参数为ref对象,第二个参数为回调函数,可以监听新值和旧值,第三个参数为高级属性对象

// 1. 监听单个
watch(count, (newValue, oldValue) => {
  console.log(newValue, oldValue)
})

// 2. 监听多个, 监听的数据写成数组的形式
watch([count, message], (newValue, oldValue) => {
  // 只要有一个数据发生改变都会的所有监听数据的新值和旧值
  console.log(newValue, oldValue)
})

// 3. 深度监听 deep
watch(user, (newValue, oldValue) => {
  console.log('深度监听:', newValue, oldValue)
}, {
  // 第三个参数中可以开启深度监听
  deep: true
})

// 4. 监听器创建时立即执行一次,发生改变时继续执行 immediate
watch(count, (newValue, oldValue) => {
  console.log('immediate:', newValue, oldValue)
})

// 5. 监听复杂类型中的特定数据
watch(()=> user.value.age, (newValue, oldValue) => {
  console.log('特定数据age:', newValue, oldValue)
})
const changeCount = () => count.value++
const changeMessage = () => message.value = 'world'
const changeUserAge = () => user.value.age = 20
const changeUserName = () => user.value.name = 'ls'
</script>

<template>
<div>1</div>
  <button @click="changeCount">count+1</button>
  <button @click="changeMessage">changeMessage</button>
  <button @click="changeUserAge">changeUserAge</button>
  <button @click="changeUserName">changeUserName</button>
</template>

<style scoped>
button {
  margin: 5px;
}
</style>

6. 生命周期函数

在这里插入图片描述

导入对应的生命周期函数,在对应的生命周期函数中传入回调函数即可使用,如狗有多个相同的生命周期函数,会按顺序依次执行

<script setup>
// 生命周期
// vue2中的beforeCreate和created相当于vue3组合式API中的setup
// 因此在script标签上加了setup语法糖的可以直接写直接调用
import { onMounted } from "vue";

const getList = () => {
  console.log('getList')
}
// 直接调用, 相当于创建vue实例的时候
getList()

// 其他生命周期函数需要写在对应的函数里
onMounted(() => {
  console.log('onMounted1')
})

// 相同的生命周期按书写的顺序调用
onMounted(() => {
  console.log('onMounted2')
})
</script>

<template>

</template>

<style scoped>

</style>

7. 组件通信

  1. 父传子

    • 父组件给子组件绑定自定义属性传值
    • 子组件通过defineProps编译器宏创建props选项接收数据
  2. 子传父

    • 父组件给子组件绑定事件
    • 子组件内部通过defineProps编译器宏创建emit方法出发事件

    在这里插入图片描述

8. 模板引用 - 获取节点

  • 可以获取DOM对象或者组件实例对象

  • 调用ref函数传null生成一个ref对象,通过ref属性绑定到标签上即可获取

  • setup环境中不能直接使用,因为还没创建完,可以在onMounted或者等元素渲染完成之后调用

  • 获取组件实例得通过defineExpose指定哪些属性或者方法允许外部访问外部才能访问到

在这里插入图片描述

9. 跨层级传递数据

  1. 顶层使用provide()函数提供数据
  2. 底层使用inject()函数接收数据
  3. 可以传递基本数据类型、复杂数据类型也可以传递方法

语法:

// 传递信息
provide('key', 数据、方法)

// 接收数据
const message = inject('key')

在这里插入图片描述

10. Vue3.3新特性

10.1 defineOptions

<script setup> 之前,如果要定义 props, emits 可以轻而易举地添加一个与 setup 平级的属性。

但是用了 <script setup> 后,就没法这么干了 setup 属性已经没有了,自然无法添加与其平级的属性。

简而言之,defineOptions中可以定义选项式的一些属性

<script setup>
import {defineOptions} from 'vue'
defineOptions({
  name: 'loginIndex'
})
</script>

10.2 defineModel

可以实现在组件上使用v-model可以自由修改并响应数据

vue3.3需要开启额外配置,3.4以上版本不需要

<script setup>
import { defineModel } from 'vue'
// 使用defineModel接收父组件绑定的v-model可以简单的实现数据的双向绑定,可以直接修改父组件中的值
const modelVal = defineModel()

const changeFatherMeg = () => {modelVal.value = 'sonMessage'}
</script>

vue3.3 需要额外在vite.config.js开启配置

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue({
      script: {
        defineModel: true
      }
    }),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

在这里插入图片描述

11. pinia

pinia是Vue最新的状态管理工具,是Vuex的替代品,提供更简单的API,对ts支持更好

11. 1. 开始使用

按照官方文档安装完成之后即可使用,也可以在创建项目的时候直接勾选上

  1. 定义
    • 在模块中定义pinia直接使用内置函数definStore()进行创建
    • 创建的ref()对象就是store数据
    • 创建的function就是action,可以发送异步请求
    • 创建的computed就是getters
    • 最后需要将定义的数据或方法返回才能够使用
import { defineStore } from "pinia";
import { computed, ref } from "vue";

export const useCounterStore = defineStore('唯一标识', {
    // 核心内容,store, actions, getters
    
    // store
    const count = ref(1)

	// actions
	const changeCount = () => {}
    
    // getters
    const computedCount = computed(() => count.value * 2)
    
    // 返回数据使用
    return {
        count,
        changeCount,
        computedCount
    }
})
  1. 使用

    • 导入定义的store
    • 执行方法得到对象
    • 根据对象使用里面的方法
    • 直接解构的话数据将不是响应式数据,需要使用storeToRefs()包装
    <script setup>
    // 导入store
    import { useCounterStore } from "@/store/counter.js";
    // 执行方法得到store对象
    const counterStore = useCounterStore()
    // 解构使用storeToRefs包装保持响应式
    const { count } = storeToRefs(counterStore)
    </script>
    
    <template>
    	<div>
            <!-- 使用 -->
            count - {{ counterStore.count }}
            <!-- 解构数据使用-->
            解构count:-- {{ count }}
        </div>
    </template>
    
  2. 在这里插入图片描述

11.2 持久化插件

官方文档:https://prazdevs.github.io/pinia-plugin-persistedstate/zh/

  1. 安装插件 pinia-plugin-persistedstate
npm i pinia-plugin-persistedstate
  1. 使用 main.js
import persist from 'pinia-plugin-persistedstate'
...
app.use(createPinia().use(persist))
  1. 配置开启持久化
    • persist: true 默认将所有数据进行持久化,key为唯一标识

      import { defineStore } from 'pinia'
      import { computed, ref } from 'vue'
      
      export const useCounterStore = defineStore('counter', () => {
        ...
        return {
          count,
          changeCount,
          computedCount
        }
      }, {
        persist: true // 开启持久化,默认将所有数据进行持久化,key为唯一标识
      })
      
    • 自定义配置

      import { defineStore } from 'pinia'
      import { computed, ref } from 'vue'
      
      export const useCounterStore = defineStore('counter', () => {
        ...
        return {
          count,
          changeCount,
          computedCount
        }
      }, {
        persist: { // 写成对象形式可以配置更多选项
          key: 'startCounter', // 配置自定义key
          paths: ['count'] // 指定哪些属性进行持久化
          ...其他自定义配置
        }
      })
      
转载请注明出处或者链接地址:https://www.qianduange.cn//article/16411.html
标签
评论
发布的文章

HTML5入门基础

2024-06-16 09:06:50

HTML(二) 元素分类

2024-08-30 20:08:11

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!