vue3+vite+pinia

目录

一、项目准备

1.1、Vite搭建项目

1.2、vue_cli创建项目

二、组合式API(基于setup)

2.1、ref

2.2、reactive

2.3、toRefs

2.4、watch和watchEffect

2.5、computed

2.6、生命周期钩子函数

2.7、setup(子组件)的第一个参数-props

2.8、setup(子组件)的第二个参数-context

2.8.1、context.attrs【$attrs】

2.8.2、context.slots【$slots】

2.8.3、context.emit【$emit】

2.8.4、context.expose

2.9、provide-inject

2.10、在单文件组件(SFC)中使用组合式API的编译时语法糖

三、路由Vue-Router

3.1、引入和安装

3.2、带参数的动态路由匹配

3.3、路由正则与重复参数

3.4、嵌套路由与重定向

3.5、替换页面和堆栈中的前进后退(js跳转)

3.6、路由组件传参

3.7、路由懒加载

四、pinia

4.1、安装

4.2、Option Store与Setup Store的定义与使用

4.3、State的基本使用

4.5、Getter的基本使用

4.6、Action的基本使用

4.7、Pinia与vuex的区别

一、项目准备

1.1、Vite搭建项目

Vue3官网地址:快速上手 | Vue.js

Vite官网地址:开始 | Vite 官方中文文档

检查自己电脑npm -v版本,按照以下命令自己选择合适的命令

node -v检查node版本>14.18,可以在官网自行下载Node.js

# npm 6.x
npm create vite@latest my-vue-app --template vue

# npm 7+, extra double-dash is needed:
npm create vite@latest my-vue-app -- --template vue

# yarn
yarn create vite my-vue-app --template vue

# pnpm
pnpm create vite my-vue-app --template vue

注意:只有Node版本在14.18及以上,Vite搭建项目才能生效

创建好项目以后,可以在依赖包看一下,有没有Vite,没有就npm i一下,然后npm run dev,至此,项目创建成功!

1.2、vue_cli创建项目

先全局安装了CLI,命令:npm install -g @vue/cli

检查版本:vue --version

创建项目:vue create vue_app(项目名)

可以自定义:Manually select features 

选择需要的css、router等,然后一直回车,在项目终端npm run serve即可

二、组合式API(基于setup)

形式区别:Vue3采用组合式API;Vue2采用选项式API 。

组合式API:将同一个逻辑关注点的相关代码收集在一起。

组件被创建之前执行,不需要使用this,this不会指向实例。

2.1、ref

响应式变量:通过引入ref定义响应式变量ref返回带有value属性的对象

在函数里进行修改时要加.value

2.2、reactive

响应式的引用类型:通过引入reactive定义引用类型的数据

2.3、toRefs

因为:ES6扩展运算符进行解构会使得对象中的属性不是响应式

所以:通过引入toRefs(object)函数使解构后的数据重新获得响应式

vue2里是在data里进行定义,而vue3以上内容代码演示如下:

<script>
import { ref, reactive, toRefs } from "vue";
export default {setup() {// 非响应式(msg相关代码)let msg = "hello";console.log(msg);function changeMsg() {msg = "nihao";console.log(msg); //nihao,但是视图上不会改变}// 响应式(counter相关代码)// 通过引入ref定义响应式变量【counter=0】,ref返回带有value属性的对象let counter = ref(0);function changeCounter() {counter.value++; //视图上自加1}// 响应式(obj相关代码)// 通过引入reactive定义引用类型的数据let obj = reactive({name: "张三",age: "19",children: {son: "小宝贝",},});function changeObj() {obj.name = "李四"; //视图改变obj.children.name = "大王"; //视图改变}// ES6扩展运算符进行解构会使得对象中的属性不是响应式// 故:通过引入toRefs(object)使解构后的数据重新获得响应式return {msg,changeMsg,counter,changeCounter,obj,changeObj,...toRefs(obj),};},
};
</script>
<template><div><h1>{{ msg }}</h1><button @click="changeMsg">改变msg</button><hr /><h1>{{ counter }}</h1><button @click="changeCounter">改变counter</button><hr /><h1>{{ obj.name }}</h1><h1>{{ children.name }}</h1>    <!-- 一开始没出现,改变后才出现? --><button @click="changeObj">改变name</button></div>
</template>

2.4、watch和watchEffect

这两个写在setup之内,return之前

watch和watchEffect区别:

(1)语法:

watch(监听的响应式变量,回调函数)

watchEffect(回调函数)

(2)作用:

watch监听响应式变量,无法监听引用类型;

watchEffect监听引用类型,不需要指定监听属性,组件初始化时会自动收集依赖(执行一次回调),只要属性值发生改变,回调就会执行。

import {watch, watchEffect } from "vue";   
watch(counter, (newVal, oldVal) => {console.log("newVal", newVal);console.log("oldVal", oldVal);});
watchEffect(() => {console.log(obj.name);});

2.5、computed

输出响应式变量xxx.value,引用类型不用加.value

import { ref,computed } from "vue";   let Msg = ref("hello");let reverMsg = computed(() => {return Msg.value.split("").reverse().join("");});console.log(reverMsg.value); //olleh

2.6、生命周期钩子函数

在vue2基础上加个on;setup本身就相当于beforeCreate 和created;在页面初始化时,会执行onBeforeMount、onMounted;数据发生变化时,会执行onBeforeUpdate、onUpdated;销毁时执行onBeforeUnmount、onUnmounted

import { onBeforeMount, onBeforeUpdate, onMounted, onUpdated } from "vue";setup() {onBeforeMount(() => {console.log("onBeforeMount");//onBeforeMount});onMounted(() => {console.log("onMounted");//onMounted});onBeforeUpdate(() => {console.log("onBeforeUpdate");});onUpdated(() => {console.log("onUpdated");});},

2.7、setup(子组件)的第一个参数-props

  父组件与子组件的传值和vue2一样,在子组件里面获取父组件传来的值,就是通过setup的第一个参数props获取。值改变了,就在onUpdated里面获取改变后的值。

2.8、setup(子组件)的第二个参数-context

2.8.1、context.attrs【$attrs】

Attribute 非响应式对象

console.log(context.attrs);

//{class: 'classBox', id: 'IdBox', __vInternal: 1}

给组件上添加class/id,在子组件这边可以拿到组件的类名,然后做一些样式操作

2.8.2、context.slots【$slots】

插槽 非响应式对象

比如:context.slots.default() 判断子组件标签类型

2.8.3、context.emit【$emit】

(子组件触发事件,等同于$emit)

2.8.4、context.expose

暴露公共 property,这样子组件本身就是变成暴露的内容,记得引入h

 //通过expose暴露context.expose({counter,sendParent,});//返回渲染函数 没有暴露数据return () => h("div", counter.value);

2.9、provide-inject

provide-inject用于跨组件传值,如果想要响应式改变,就要将值用rer/reactive进行定义

2.10、在单文件组件(SFC)中使用组合式API的编译时语法糖

总结:

<script setup>相当于setup() {}函数【顶层的绑定会被暴露给模板】

优势:引入组件,不需要注册;定义变量、方法不需要暴露

<script setup>
// 顶层的绑定会被暴露给模板
import { ref } from "vue";
// 引入组件,不需要注册
import Hello from "./components/HelloWorld.vue";
// 定义变量、方法不需要暴露
const a = 20;
console.log(a);
const b = ref(10);
function addB() {b.value++;
}
</script>
<template><div><h2>{{ a }}</h2><h2>{{ b }}</h2><button @click="addB">改变B</button><Hello/></div>
</template>

三、路由Vue-Router

路由相关内容地址:入门 | Vue Router

3.1、引入和安装

npm install vue-router@4  或者  yarn add vue-router@4

在src包下新建router文件夹,在index.js里面引入配置的路径

import { createRouter, createWebHashHistory } from 'vue-router'
// 1. 定义路由组件.也可以从其他文件导入
import Home from '../views/HomeView.vue'
import User from '../views/UserView.vue'
// 2. 定义一些路由,每个路由都需要映射到一个组件。
const routes = [{ path: '/', component: Home },{ path: '/user', component: User },
]
// 3. 创建路由实例并传递 `routes` 配置
const router = createRouter({// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。history: createWebHashHistory(),routes, // `routes: routes` 的缩写
})
export default router

main.js中进行挂载

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')

路由跳转运用:

<router-link to="/">Go Home</router-link>
<router-link to="/user">Go User</router-link><!-- 路由出口 占位符 --><!-- 相当于组件 路由匹配到的内容页面将渲染在这里 -->
<router-view></router-view>

3.2、带参数的动态路由匹配

路径参数 用冒号表示     { path: '/user/:id', component: User }

 <router-link to="/user/1234">Go User</router-link>

页面获取参数:

Vue2: 在mounted里面通过 this.$route.params.xx 获取

vue3:引入useRoute,通过useRoute().params.xx获取

<script setup>
import { useRoute } from "vue-router";
console.log(useRoute().params.id);
</script>

3.3、路由正则与重复参数

404页面:

{ path: '/:path(.*)', component: NotFound },//使用正则,匹配任意的路径,一般放最后

参数限制:

(1)动态路由的参数一定是数字:{ path: '/about/:id(\\d+)', component: About };

(2)多个参数:{ path: '/about/:id+', component: About };

(3)参数可有可无,可以重复添加:{ path: '/about/:id*', component: About };

(4)参数可有可无,不可以重复添加:{ path: '/about/:id?', component: About };

3.4、嵌套路由与重定向

children里面写要嵌套的路由。

{path: '/',redirect: '/home'    //重定向。下面肯定有这个路径},

{ path: '/home', component: Home },

3.5、替换页面和堆栈中的前进后退(js跳转)

纯js跳转与带对象跳转:path+query;name+params

页面接收:this.$route.query.name。。。

this.$router.push("/xxx");
this.$router.push({path: "/xxx",query: {name: "zhangsan",},});
this.$router.push({name: "xxx",params: {name: "zhangsan",},});
//replace:true  替换当前页面
this.$router.replace({path: "/xxx",query: {name: "zhangsan",},});

this.$router.go(xx)        //正值为前进,负值为后退;

this.$router.back()        //后退,等于go(-1);

this.$router.forword()   //前进,等于go(1);

3.6、路由组件传参

defineProps

3.7、路由懒加载

路由守卫同vue2

import ShopTwo from '../views/shop/ShopTwo.vue'

替换成const ShopTwo =()=>import("../views/shop/ShopTwo.vue")

达到"用到它时再加载"的效果

四、pinia

4.1、安装

pinia官网地址:Pinia | The intuitive store for Vue.js

下载:npm install pinia

在main.js创建一个pinia实例:

4.2、Option Store与Setup Store的定义与使用

import { defineStore } from 'pinia'
// option store
export const useAgeStore = defineStore('dingding', {state: () => {//相当于data属性return { age: 30 }},getters: {//相当于computed属性gettersAge(state) {return state.age + 5}},actions: {//相当于methods属性addAge() {this.age++;//this指向对应的store仓库}}
})
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
// setup store
export const useCounterStore = defineStore('main', () => {const counter = ref(30);//stateconst gettersCounter = computed(() => {//gettersreturn counter.value + 5})function addCounter() {//actionscounter.value++;}return { counter, gettersCounter, addCounter }
})

使用:

4.3、State的基本使用

  为了完整类似推理,推荐使用箭头函数,在Pinia中,state被定义为一个返回初始状态的函数,这使得Pinia可以同时支持服务端和客户端。data(){return{}}防止数据污染(针对于服务端)。

<button @click="changeAge">修改age值</button>
<script setup>
import { useAgeStore } from "../stores/index.js";
const ageStore = useAgeStore();
// 修改state中的状态
function changeAge() {// 方式一 直接修改ageStore.age++;ageStore.name = "张三丰";// 方式二 批量修改 $patch(对象) 建议使用ageStore.$patch({age: 40,name: "张三丰",arr: [...ageStore.arr, 5],});// 方式三 批量修改 $patch(函数) 强烈推荐ageStore.$patch((state) => {state.age = 40;state.name = "张三丰";state.arr.push(8);});// 方式四:在actions里面进行修改
}
</script>
=============store中的state===================state: () => {//相当于data属性return { age: 30, name: '王富贵', arr: [1, 2, 3] }},

扩展:(1)重置state:  xx.$reset();

           (2)监听state:  xx.$subscribe();

4.5、Getter的基本使用

    getters: {//相当于computed属性gettersAge(state) {return state.age + 5},// 通过this访问其他的getters,注意:不能使用箭头函数gettersName(state) {return this.gettersAge + state.name},// 向getters传递参数,返回函数的方式接收参数,和普通函数一样,没有缓存的作用gettersAge(state) {return (data) => state.age + data},// 访问其他的store中的gettersgettersAge(state) {const counterStore = useCounterStore()return state.age + counterStore.gettersCounter},},

4.6、Action的基本使用

    actions: {//相当于methods属性,既可以处理同步又可以处理异步addAge() {this.age++;//this指向对应的store仓库},// 访问其他store中的actionsasync getList() {const counterStore = useCounterStore()if (counterStore.addCounter()) {let res = await axios.get('http://xxx').then(res => {console.log(res);})console.log(res);}}}

4.7、Pinia与vuex的区别

(1)Pinia搭配TS一起使用时,有非常可靠的类型推断支持;

(2)Pinia没有mutations,而actions的使用不同,在actions中可以处理同步也可以处理异步,getters的使用是一致的,state与vue2中data是相似的;

(3)Pinia没有总入口全是模块化,需要定义模块名称,当多个模块需要协作的时候,需要引入多个模块;vuex是有总入口的,在使用模块化的时候不需要引入多个模块;

(4)Pinia在修改状态的时候不需要通过其他api,vuex需要通过commit、dispatch去修改,所以在语法上比vuex更容易理解和使用,灵活;

(5)Pinia就是更好的vuex,建议在项目中可以直接使用它了,尤其是使用了TS的项目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/38765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 CubeMX (Freertos任务:创建、删除、挂起、恢复)

STM32 CubeMX Freertos STM32 CubeMX &#xff08;Freertos任务&#xff1a;创建、删除、挂起、恢复&#xff09; STM32 CubeMX Freertos前言一、STM32 CubeMX 配置时钟树配置使能串口&#xff0c;用于用于检查实验现象使用STM32 CubeMX 库&#xff0c;配置Freertos创建任务 二…

云计算:新一代的技术革命

云计算&#xff0c;作为21世纪的一项重要技术革命&#xff0c;已在全球范围内引发了深远的影响。它改变了我们存储和处理数据的方式&#xff0c;使得企业无需再建设和维护昂贵的本地服务器和数据中心。本文将深入探讨云计算的基本概念&#xff0c;类型&#xff0c;主要优点&…

开发利器:接口代理和接口模拟工具

前端开发过程往往需要和后端对接接口,而且一般开发都是前后端同步开发,这就难免出现接口提供滞后的问题,从而导致我们前端开发 UI 开发完成而无法调试的问题。面对这种问题,一般我们会有很多种方式处理,比如在代码中写一些模拟数据,或者打断点调试,或者用代理工具 Fidde…

概念解析 | 长尾分布:从无处不在的‘少数派’中挖掘价值

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:长尾分布(Long-Tail Distribution)。 揭秘长尾分布:从无处不在的‘少数派’中挖掘价值 What is a Long Tail Distribution? (Definition & Example) - Statology 一、背…

神经网络基础-神经网络补充概念-02-逻辑回归

概念 逻辑回归是一种用于二分分类问题的统计学习方法&#xff0c;尽管名字中带有"回归"一词&#xff0c;但实际上它用于分类任务。逻辑回归的目标是根据输入特征来预测数据点属于某个类别的概率&#xff0c;然后将概率映射到一个离散的类别标签。 逻辑回归模型的核…

什么叫做云计算?

相信大多数人对云计算或者是云服务的认识还停留在仅仅听过这个名词&#xff0c;但是对其真正的定义或者意义还不甚了解的层面。甚至有些技术人员&#xff0c;如果日常的业务不涉及到云服务&#xff0c;可能对其也只是一知半解的程度。首先云计算准确的讲只是云服务中的一部分&a…

多主题自适应知识变现博客论坛,支持docker一键部署

iblog 给大家推荐一个多主题自适应&#xff0c;支持付费收款的博客论坛系统&#xff0c;支持docker一键部署&#xff0c;支持企业微信通知。 前端 多主题 自适应 个人页 后端 H2 console 运行命令 docker run -d --name iblog --restartalways -p 8080:8080 -e consoletrue …

RabbitMQ简单使用

RabbitMq是一个消息中间件&#xff1a;它接收消息、转发消息。你可以把它理解为一个邮局&#xff1a;当你向邮箱里寄出一封信后&#xff0c;邮递员们就能最终将信送到收信人手中。 RabbitMq、消息相关术语如下&#xff1a; 生产者&#xff1a;生产者只发送消息&#xff0c;发…

Postman接口自动化测试实例

一.实例背景 在实际业务中&#xff0c;经常会出现让用户输入用户密码进行验证的场景。而为了安全&#xff0c;一般都会先请求后台服务器获取一个随机数做为盐值&#xff0c;然后将盐值和用户输入的密码通过前端的加密算法生成加密后串传给后台服务器&#xff0c;后台服务器接到…

【ARM 嵌入式 编译系列 11 -- GCC __attribute__((packed))详细介绍】

文章目录 __attribute__&#xff08;(packed)&#xff09; 介绍 上篇文章&#xff1a;ARM 嵌入式 编译系列 10.3 – GNU elfutils 工具小结 下篇文章&#xff1a;ARM 嵌入式 编译系列 11.1 – GCC attribute((aligned(x)))详细介绍 attribute&#xff08;(packed)&#xff09; …

针对Android项目蓝牙如何学习

一、概述(Overview) 蓝牙是一种专有的开放式无线技术标准,用于在固定和移动设备之间进行短距离数据交换(使用2400–2480 MHz ISM波段的短波长无线电传输),从而创建具有高度安全性的个人局域网(PANs)。由电信供应商爱立信(telecoms vendor Ericsson)于1994年创建,[1…

系统架构设计师---计算机网络基础知识

根据考试大纲,本章知识点会涉及单项选择题,约占2~6分。本章内容属于基础知识范畴,根据以往全国计算机技术与软件专业技术资格(水平)考试的出题规律而言,会在单项选择题中出现,也会在案例分析题中出现。 想成为一名合格的高级架构师,需要在计算机领域中“上知天文,下知地…

【ES】笔记-ES6的函数rest参数用法

es6中引入了rest参数&#xff0c;样式形如…xxx&#xff0c;用于获取函数的多余参数&#xff0c;这样就不需要使用arguments对象了。rest参数搭配的一个变量是一个数组&#xff0c;该变量将多余的参数放入数组中。例如&#xff1a; function add(...value){console.log(value);…

pytest自动生成测试类 demo

一、 pytest自动生成测试类 demo # -*- coding:utf-8 -*- # Author: 喵酱 # time: 2023 - 08 -15 # File: test4.py # desc: import pytest import unittest# 动态生成测试类def create_test_class(class_name:str, test_cases:list) -> type:"""生成测试类…

前端面试的性能优化部分(10)每天10个小知识点

目录 系列文章目录前端面试的性能优化部分&#xff08;1&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;2&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;3&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;4&#xff09;每天…

TiDB数据库从入门到精通系列之一:TiDB数据库的软硬件环境要求和系统配置检查

TiDB数据库从入门到精通系列之一&#xff1a;TiDB数据库的软硬件环境要求和系统配置检查 一、软件和硬件配置要求1.操作系统及平台要求2.服务器建议配置3.网络要求4.磁盘空间要求 二、TiDB 环境与系统配置检查1.在 TiKV 部署目标机器上添加数据盘 EXT4 文件系统挂载参数2.设置 …

RESTAPI简介与DRF使用

RESTAPI 以资源为url&#xff0c;通过不同的请求方式实现不同的行为。 以资源名作为url POST:增 …/student/ GET&#xff1a;查所有 …/student/ GET&#xff1a;查单个 …/student/<pk>/ 获取idpk的学生 DELETE&#xff1a;删 …/student/<pk>/ PUT&#…

轻量级 Spring Task 任务调度可视化管理

Spring Task/Spring Scheduler 傻傻分不清 首先做一下“名词解释”&#xff0c;分清楚这两者的区别&#xff1a; Spring Task Spring Task 是 Spring 框架自带的一个任务调度模块&#xff0c;提供了基本的任务调度功能。它是通过 Java 的 Timer 和 TimerTask 类来实现的&…

python获取音乐文件

浏览器打开音乐地址 http://www.htqyy.com/top/hot 点击第一首歌曲&#xff0c;会打开新的网页并且可以获取 改歌曲的id&#xff0c;就是url中的33 在播放页面点击F12&#xff0c;打开开发者调试功能 如下图所示&#xff0c;在script脚本中可以获取歌曲的下载数据 host&#…

滑模控制器理论推导和matlab/simulink实例分享

滑模控制的运动轨迹主要分为两个方面&#xff1a;(1)系统的任意初始状态向滑模面运动阶段&#xff1b;(2)系统到达滑模面后并且慢慢趋于稳定的阶段。所以&#xff0c;对于滑模变结构控制器的设计&#xff0c;对应于系统运动的两个阶段&#xff0c;可以分为两个部分&#xff1a;…