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

相关推荐
十一吖i2 分钟前
前端将后端返回的文件下载到本地
vue.js·elementplus
光影少年3 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_4 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
ajsbxi7 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Rattenking8 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
TeYiToKu28 分钟前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws30 分钟前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
道法自然040231 分钟前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器
爱吃生蚝的于勒38 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
熊的猫1 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js