Vue3学习笔记

Vue2使用Vue CLI学习笔记
Vue3官方文档

创建项目

官方最新的脚手架工具create-vue,底层将构建工具webpack换成了vite

构建项目速度很快

安装create-vue:node版本16及以上

bash 复制代码
npm init vue@latest
# 安装一下vite
npm install

提供create函数创建对象(工厂模式)

组合式 API :核心思想是直接在函数作用域内定义响应式状态变量

template中可以不必根节点

setup

关于setup函数

  • beforeCreate方法之前自动执行,实例还没有被创建,this属于undefined
  • 内部代码规则:定义需要的变量和函数,使用组合式API,最后以封装成对象return
  • 可使用setup语法糖简化<script setup>

由上图的生命周期可以看出,之前写在beforeCreate和created都放在setup 函数中执行

之前写在distory中的现在是beforeUnmount和unmounted

声明式渲染和响应式ref

声明式渲染:框架封装了一些常用的DOM操作,直接使用提供的API或者指令就能实现需要的效果

响应式:当 JavaScript 中的数据变化时,HTML 视图自动更新

默认声明的数据是不响应式的

javascript 复制代码
<script setup>
import { ref } from 'vue'
 
let count = 1 //  定义了一个普通变量
const add = ()=> {
  count++
}
</script>

<template>
  <h1>{{count}}</h1>
  <button @click="add">
    +1
  </button>
</template>

效果:视图上的数据并没有发生改变

vue2实现响应式,通过监听data中的对象和属性,触发dom操作如innerHTML

vue3实现响应式提供两个函数创建响应式对象:

  • reactive():把一个对象传进去变成一个响应式对象,不能传普通类型
  • ref():可以传普通类型,因为会裹一层对象,使用.value暴露值,在template中不写.value

使用reactive获得一个响应式对象

javascript 复制代码
<script setup>
import { reactive } from 'vue'

const counter = reactive({
  count: 0
})

const add = () => {
	counter.count++
}

</script>

<template>
  <h1>{{counter}}</h1>
  <button @click="add">
    +1
  </button>
</template>

使用ref实现相同的功能

javascript 复制代码
<script setup>
import { ref } from 'vue'

const counter = ref({
  count: 0
})

const add = () => {
	counter.value.count++ // 需要使用.value获得数据
}

</script>

<template>
  <h1>{{counter}}</h1>
  <button @click="add">
    +1
  </button>
</template>

组件传值

都遵循单向数据流原则

父子

父传子:

给子组件添加属性,父组件通过v-bind:属性名传值

vue2使用props选项,vue3使用组合函数defineProps(),数组或者是对象注册

传递函数:defineEmits注册函数名,返回一个emit对象,需要传递一个函数名数组声明函数属性

原来vue2中this.$emit('函数名',参数)干了两件事,注册并调用

vue3把注册和调用分开了

js 复制代码
// 子组件注册
const emit = defineEmits(['事件名'])

// 子组件调用事件
emit('事件名', 参数)

下面有个简单案例

父组件:

javascript 复制代码
<script setup>
import { ref } from 'vue';
import SonCom from './SonCom.vue';

const money = ref(100)
</script>

<template>
  <div class="parentCom">
    我是老父亲,家底:{{ money }}
    <div>
        <button @click="money++">挣钱 +1</button>
    </div>
    <SonCom @earn="money++" @spend="money--" :money="money"></SonCom>
  </div>
</template>

<style>
    .parentCom {
        height: 200px;
        width: 300px;
        padding: 10px;
        border: 1px black solid;
    }
</style>

子组件:

javascript 复制代码
<template>
    <div class="son">
        我是子组件,余额:{{ money }}
        <div>
            <button @click="emit('spend')" >挥霍 +1</button>
            <button @click="emit('earn')" >打工 +1</button>
        </div>
    </div>
</template>

<script setup>
    defineProps(['money'])
    const emit = defineEmits(['spend','earn']) // 注册了两个事件
</script>

<style>
.son {
    height: 100px;
    width: 150px;
    margin-top: 10px;
    border: 1px black solid;
}
</style>

跨层级

多层嵌套

vue2中的provide&inject使用方式较为复杂,一般都直接使用vuex了

vue3中的provide&inject使用极为方便

js 复制代码
provide(key,value) // 提供数据
inject(key) // 获得数据

key是字符串,value可以是变量,响应式变量,或者修改函数

模版引用ref

就是给dom元素对象或者是组件对象添加唯一标识

类似于id,作用范围在当前组件中

1 声明一个 ref 来存放该元素的引用,规则就是要用ref()

javascript 复制代码
const 引用名 = ref(null)

2 给dom元素(组件)添加ref属性

html 复制代码
<div ref="引用名" .../>

3 在onMounted函数中操作获得的元素对象,要等对象挂载完成才能获取得到

关于引用现象

子组件:

javascript 复制代码
<template>
    <div>
        我是B组件
    </div>
</template>

<script setup>

let count = 100 // 普通变量
const sayHi = function() {
    console.log('hi'+ count);
}

defineExpose({
    count,
    sayHi
})

</script>

父组件:

javascript 复制代码
<script setup>
import { onMounted, ref } from 'vue';
import BCom from './BCom.vue';

const bcom = ref(null)

onMounted(()=> {
    console.log(bcom.value.count); // 外部访问
    bcom.value.count = 10 // 修改了值
    bcom.value.sayHi()
    console.log(bcom.value.count);
})

</script>

结果:子组件中的count没变

暴露一个响应式变量,外部组件正常访问,不要.value

javascript 复制代码
<template>
    <div>
        我是B组件
    </div>
</template>

<script setup>
import { ref } from 'vue';

const count = ref(100) // 响应式变量,外面裹了一层对象
const sayHi = function() {
    console.log('hi'+count.value);
}

defineExpose({ // 暴露属性
    count,
    sayHi
})

</script>

结果:子组件中的值被修改了

Vue3.3新特性

1、defineOptions

可以在setup函数中添加平级属性,如name

js 复制代码
defineOptions({
	name: 'Index'
})

2、defineModel 实验性的父子组件的双向绑定

Pinia

状态管理,vuex的vue3官方替代方案
pinia官方文档

bash 复制代码
# 使用 npm
npm install pinia

组合式API使用就正常定义需要共享的数据,包括同步异步的方法

js 复制代码
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment } // 直接暴露
})

pinia的响应式是通过reactive实现的

即维护的状态发生改变,组件中引用的状态也会跟着改变

为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()

方法的话就直接解构

js 复制代码
<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name` 和 `doubleCount` 是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store
</script>

pinia自动持久化插件

官方文档

安装插件:

bash 复制代码
npm i pinia-plugin-persistedstate

将插件注入到pinia对象中

javascript 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'
// 导入插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import App from './App.vue'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) // 注入pinia
const app = createApp(App)

app.use(pinia)
app.mount('#app')

在store中添加新参数,开启持久化

默认保存整个store,方式是localStorage

js 复制代码
import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useStore = defineStore(
  'main',
  () => {
    const someState = ref('hello pinia')
    return { someState }
  },
  {
    persist: true, // 开启持久化
  },
)

可以配置key修改键名,配置path保存指定数据

相关推荐
leegong2311120 分钟前
学习PostgreSQL专家认证
数据库·学习·postgresql
敲敲敲-敲代码23 分钟前
【SQL实验】触发器
数据库·笔记·sql
Moonnnn.1 小时前
51单片机学习——动态数码管显示
笔记·嵌入式硬件·学习·51单片机
南宫生2 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
技术小齐2 小时前
网络运维学习笔记 016网工初级(HCIA-Datacom与CCNA-EI)PPP点对点协议和PPPoE以太网上的点对点协议(此处只讲华为)
运维·网络·学习
竹言笙熙2 小时前
代码审计初探
学习·web安全
日记成书2 小时前
物联网智能项目
物联网·学习
虾球xz3 小时前
游戏引擎学习第118天
学习·游戏引擎
gz927cool3 小时前
大模型做导师之开源项目学习(lightRAG)
学习·开源·mfc
电棍2334 小时前
verilog笔记
笔记·fpga开发