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保存指定数据

相关推荐
架构文摘JGWZ1 分钟前
Kafka 消息丢失如何处理?
学习
LHNC14 分钟前
9.18 微信小程序开发笔记
笔记
LJ小番茄1 小时前
Vue 常见的几种通信方式(总结)
前端·javascript·vue.js·html
waterHBO1 小时前
R语言 基础笔记
开发语言·笔记·r语言
GEEKVIP1 小时前
如何在没有备份的情况下恢复 Mac 上丢失的数据
经验分享·笔记·安全·macos·电脑·笔记本电脑·改行学it
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS在线文档管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
linly12193 小时前
python学习笔记目录
笔记·学习
pan_junbiao3 小时前
Vue组件:模板引用ref属性的使用
前端·javascript·vue.js
LvManBa4 小时前
Vue学习记录之四(computed的用法)
前端·vue.js·学习
Li小李同学Li4 小时前
git学习【持续更新中。。。】
git·学习·elasticsearch