Vue3,Pinia

一. Vue3的优势

1. 更容易维护

组合式API,更好的TypeScript支持

2. 更快的速度

1. 重写diff算法;2. 模板编译优化;3. 更高效的组件初始化

3. 更小的体积

1. 良好的TreeShaking;2. 按需引入

4. 更优的数据响应式

Proxy

二. Vue2 vs Vue3

Vue3,Pinia_第1张图片

Vue2选项式API

整个配置项中,有着一个一个的选项,data是一个选项,methods是一个选项,computed是一个选项等等。如果我们要实现一个功能,需要分散式的将代码散落到各个配置项当中。例如我们实现一个功能A,我们需要在data里面提供功能A的数据,在methods里面写功能A相关的方法,再加个计算属性computed。当要实现的功能越来越多,写的代码越来越多的时候,它们之间的互相对应就会使得将来项目非常难以维护。

选项式API(Options API)

export default {

        data() {

                return {

                        功能A

                        功能B

                }

        },

        methods: {

                功能A

                功能B

        },

        computed: {

                功能A

        },

        watch: {

                功能B

        }

}

Vue3组合式API

直接将同功能相关的所有内容进行集中式的管理

组合式API(Composition API)

功能A相关的数据的声明

功能A相关的方法的提供

功能A相关的计算属性

功能B相关的数据的声明

功能B相关的方法的提供

功能B相关的计算属性

举例:需求:点击按钮,让数字+1

// vue2中的写法


// vue3中的写法

三. create-vue搭建Vue3项目

create-vue是Vue官方新的脚手架工具,底层切换到了vite(下一代构建工具),为开发提供极速响应。

以前用Vue-cli创建项目,它的底层是webpack。

现在用create-vue创建项目,它的底层是vite。

1. 前提环境

已安装16.0或更高版本的Node.js

node -v

2. 创建一个Vue应用

npm init vue@latest

这一指令将会安装并执行create-vue 

四. 项目目录和关键文件

Vue3,Pinia_第2张图片

关键文件:

1. vite.config.js -项目的配置文件 基于vite的配置

2. package.json-项目包文件 核心依赖变成了3.x和vite

3. main.js-入口文件createApp函数创建应用实例

3. app.vue-根组件

        变化一:脚本script和模板template顺序调整

        变化二:模板template不再要求唯一根元素

        变化三:脚本script添加setup标识支持组合式API

5. index.html-单页入口,提供id为app的挂载点

main.js文件 

//1. 从vue中按需导入createApp函数
// createApp函数的作用:创建vue的“单页面应用程序实例”
import { createApp } from ‘vue’

//2. 导入待渲染的App组件
import App from ‘./App.vue’

//3. 调用createApp()函数,返回值是“单页面应用程序的实例”,用常量spa_app接收
//同时把App组件作为参数传给createApp函数,表示把App渲染到index.htnl页面上
const spa_app = createApp(App)

//4. 调用spa_app实例的mount方法,用来指定vue实际要控制的区域
spa_app.mount(‘#app’)

五. setup选项 

1. setup的执行时机,比beforeCreate还要早

2. 也正是因为执行时机太早,setup函数中拿不到this(this是undefined)

setup选项中写代码的特点 :提供的任何数据或函数,想要在模板中应用,必须return



如果每次都要return,会很麻烦,所以提供了

setup语法糖原理 

Vue3,Pinia_第3张图片

六. reactive和ref函数

reactive()

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




// 举例

ref()

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

ref()它其实是在原有传入数据的基础上,外层包了一层对象,包成了复杂类型,底层包成复杂类型之后,再借助reactive实现的响应式。

Vue3,Pinia_第4张图片

在脚本中通过.value访问数据 

在template中不需要加.value就可以访问数据 



Vue3,Pinia_第5张图片

对数据进行加一操作



七. computed

计算属性基本思想和Vue2的完全一致,组合式API下的计算属性只是修改了写法



Vue3,Pinia_第6张图片

当修改数据时,计算属性动态更新 



Vue3,Pinia_第7张图片

注意:

1. 计算属性当中不应该有副作用:计算属性它整个函数当中应该只包含关于数据的计算过程,不应该包括其他的,比如异步请求,比如操作dom等等

2. 避免直接修改计算属性的值

八. watch

侦听一个或者多个数据的变化,数据变化时执行回调函数 

监听单个数据的变化 

监听多个数据的变化 

举个例子:同时监听count和nickname的变化 



Vue3,Pinia_第8张图片

额外参数1:immediate(立即执行)

在侦听器创建时立即触发回调,响应式数据变化之后继续执行回调

const count = ref(0)
watch(count,()=>{
  console.log('count发生了变化')
},{
  immediate: true
})

额外参数2:deep(深度监听),默认watch进行的是浅层监视

const ref1 = ref(简单类型)→可以直接监视

const ref2 = ref(复杂类型)→监视不到复杂类型内部数据的变化



Vue3,Pinia_第9张图片

精确监听对象的某个属性

// 需求:在不开启deep的前提下,监听age的变化,只有age变化时,才执行回调
const info = ref({
    name: 'cp',
    age: 18
})

// 第一个参数写成函数的写法,返回要监听的具体属性
watch( () => info.value.age, (newVal, oldVal) => console.log('age发送变化了') )

九. Vue3的生命周期API

选项式API 组合式API
beforeCreate/created setup
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUnmount
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted

以前往created里面写的,现在都写到setup里面

vue3中销毁阶段就不叫destoryed了,就叫onUnmounted了

十. 父子通信

组合式API下的父传子

基本思想:父组件中给子组件绑定属性,子组件内部通过props选项接收

对于局部组件,导入进来就能用 

// 父组件




// 子组件

defineProps原理:就是编译阶段的一个标识,实际编译器解析时,遇到后会进行编译转换

Vue3,Pinia_第10张图片

组合式API下的子传父

基本思想:父组件中,给子组件标签通过@绑定事件,子组件内部通过emit方法触发事件。

// 父组件





//子组件

十一. 模板引用

通过ref标识获取真实的dom对象或者组件实例对象

模板引用的时机是组件挂载完毕

如何使用:以获取dom为例



例如点击按钮让光标聚焦 



defineExpose()

默认情况下,

十二. provide和inject

顶层组件向任意的底层组件传递数据和方法,实现跨层级组件通信

1. 顶层组件通过provide函数提供数据

provide('key', 顶层组件中的数据)

2. 底层组件通过inject函数获取数据

const message = inject('key') 

跨层传递响应式数据 

// 顶层组件
provide('app-key', ref对象)

// 底层组件
const message = inject('app-key')

跨层传递方法 

顶层组件可以向底层组件传递方法,底层组件调用方法修改顶层组件中的数据

// 顶层组件
const setCount = () =>{
    count.value++
}
provide('setCount-key', setCount)

// 底层组件
const setCount = inject('setCount-key')

十三. Vue3.3新特性defineOptions

defineOptions宏,主要用来定义Options API的选项。

可以用defineOptions定义任意的选项,props,emits,expose,slots除外,因为这些可以用defineXXX来做到。

十四. Vue3中的v-model和defineModel

在Vue3中,自定义组件上使用v-model,相当于传递一个modalValue属性,同时触发update:modelValue事件.


// 相当于
// 父组件



// 子组件


defineModal(试验性质的特性)



// 使用defineModal需要在vite.config.js中配置
plugins:[
  vue({
    script:{
      defineModal: true
    }
  }),
]
// 开完记得重启项目

十五. Pinia

Pinia是Vue的最新状态管理工具,是Vuex的替代品

1. 提供更简单的API(去掉了mutation)

2. 提供符合,组合式的API(和Vue3新语法统一)

3. 去掉了modules的概念,每一个store都是一个独立的模块

4. 配合TypeScript更加友好,提供可靠的类型推断 

手动添加Pinia到Vue项目

// 1. 使用Vite创建一个空的Vue3项目
npm create vue@latest

// 2. 按照官方文档安装pinia到项目中
import { createApp } from 'vue'
import {createPinia} from 'pinia'
import App from './App.vue'
// 创建pinia实例
const pinia = createPinia()

// 可以这样写
// createApp(App).use(pinia).mount('#app')

// 也可以这样写
const app = createApp(App)
app.use(pinia).mount('#app')

Pinia基础使用-计数器案例

1. 定义store

2. 组件使用store 

// 这里是store文件夹下的counter.js
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

// 定义store defineStore(仓库的唯一标识,()=>{...})
export const useCounterStore=defineStore('counter', () => {
    // 声明数据 state-count
    const count =ref(0)
    // 声明操作数据的方法 action
    const addCount = () => count.value++
    const subCount=()=>count.value--
    //声明基于数据派生的计算属性getters
    const double=computed(()=>count.value*2)
    // 声明数据state-msg
    const msg = ref('hello pinia')
    return {
        count,
        addCount,
        subCount,
        double,
        msg
    }
})

// 这里是components文件夹下的Son1Com.vue组件


 Pinia-action异步实现

// 这里是store文件夹下的channel.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
import axios from 'axios'
export const useChannelStore = defineStore('channel', () => {
    // 声明数据state
    const channerList = ref([])
    // 声明操作数据的方法action
    const getList = async () => {
        const {data:{data}} = await axios.get('http://geek.itheima.net/v1_0/channels')
        channerList.value=data.channels
    }
    //声明基于数据派生的计算数据getters
    return {
        channerList,
        getList
    }
})

Pinia-storeToRefs方法 

import { storeToRefs } from 'pinia'

// 使用storeToRefs()为每一个响应式属性创建引用
const { count , msg } = storeToRefs(counterStore)
const { channelList } = storeToRefs(channelStore)

// action可以直接解构
const { getList } = channelStore

Pinia持久化插件

// 使用前确保自己已经安装了Pinia

// 1. 安装插件 
npm i pinia-plugin-persistedstate

// 2. main.js使用
import persist from 'pinia-plugin-persistedstate'

...
app.use(createPinia().use(persist))

// 3. store仓库中,开启
// 在第三个参数里面加上 (第一个参数是唯一标识,第二个参数是里面的核心逻辑)
persist: true
// 可以自己配key
persist:{
    key:'xiaoxiong-counter'
}
// 可以自己配存储
persist:{
    storage: sessionstorage
}
// 用path 指定哪些state中的哪些数据持久化
persist :{
    paths:['count']
}

十六. 路由语法的不同

vue-Router3路由的初始化 

import VueRouter from 'vue-router'

// 初始化vue-router3.x(Vue2)
const router = new VueRouter({
    mode:'history',
    routes: [],
})
export default router

vue-Router4路由的初始化

import { createRouter, createWebHistory } from 'vue-router'
// 初始化 vue-router4.x(Vue3)
const router = createRouter({
  // 1. history模式:createWebHistory 地址栏不带#
  // 2. hash模式:createWebHashHistory 地址栏带#
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: []
})

export default router

在Vue3的CompositionAPI中

1. 获取路由对象router useRouter

        const router = useRouter()

2. 获取路由参数route useRoute

        const route = useRoute()



Vue3,Pinia_第11张图片

Vue3,Pinia_第12张图片

Vue3,Pinia_第13张图片 

 

 

你可能感兴趣的:(vue.js,javascript,vue)