目录
视频学习参考:【2024最新版】Vue3从入门到精通,零基础小白也能听得懂,写得出,web前端快速入门教程_哔哩哔哩_bilibili
视频学习参考:【2024最新版】Vue3从入门到精通,零基础小白也能听得懂,写得出,web前端快速入门教程_哔哩哔哩_bilibili
一、vue的了解
1.vue的两个核心功能
-
声明式渲染:Vue 基于标准 HTML 拓展了一套模板语法,使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。
-
响应性:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM
2.API 风格
Vue 的组件可以按两种不同的风格书写:选项式 API (vue2)和组合式 API(vue3)。
二、创建一个vue项目
1.安装node.js
2.win+R
3.进入到要创建vue的目录下
4.npm create vue@latest
5.cd <your-project-name>
6.npm install
遇到问题:一直卡在这个位置
csdn查找问题结果:
1)设置淘宝源:npm config set registry https://registry.npm.taobao.org 仍然无效;
2)将npm registry更改为另一个镜像源,例如使用华为云镜像:
npm config set registry https://mirrors.huaweicloud.com/repository/npm/
重新打开cmd创建发现成功了!!!
7.npm run dev
现在已经运行起来了第一个 Vue 项目,打开浏览器输入http://localhost:5173/看看吧!
三、环境搭建
1.下载安装Visual Studio Code
2.将vscode设置为中文版
使用快捷键组合【Ctrl+Shift+p】,在搜索框中输入“configure display language”,点击确定
3.安装插件
四、文件说明
.vscode vscode工具的配置文件夹(工具不同文件夹名字不同)
node_modules vue项目的运行环境依赖
public 资源文件夹(浏览器图标)
src 源码文件夹
.gitignore git忽略文件
index.html 入口html文件
package.json 信息描述文件
README.md 注释文件
vite.config.js vue配置文件
五、第一个程序:Hello World!
在“查看”-“终端”进入到项目中运行项目npm run dev
写下我的第一个程序(注意编辑完之后记得ctrl+s保存才会有):
复制地址查看浏览器:
自此,第一个程序完成了!!
tmplate下多个标签时爆红原因:该标签下只允许存在一个根标签!!
六、使用
1.使用Javascript表达式
每个绑定仅支持单一表达式(单行),也就是一段能够被求值的JavaScript代码(最好为返回结果)。
2.原始html
双大括号会将数据插值为纯文本,而不是html。若想插入html,则需要使用v-html指令
3.属性绑定
1)单个属性值
双大括号不能在Html attributes中使用。想要响应式的绑定一个attribute,应使用v-bind指令
2)简略写法
由于v-bind非常常用,因此提供了特定的简写语法(省略v-bind):
3)动态绑定多个属性值
使用v-bind="对象"
4.条件渲染
1)v-if指令由于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染
2)也可以使用v-else为v-if添加一个“else区块”
<template> <div> <hr> <h3>条件渲染</h3> <p v-if="flag1">可以看见吗111</p> <p v-if="flag2">可以看见吗222</p> <p v-if="flag1">我今天吃饭了</p> <p v-else>我今天没吃饭</p> </div> </template> <script> export default{ data(){ return{ flag1:true, flag2:false, } } }
3)也可以使用v-else-if
<template> <div> <p v-if="name=='小张'">我是小张</p> <p v-else-if="name=='小李'">我是小李</p> <p v-else-if="name=='小王'">我是小王</p> <p v-else-if="name=='小刘'">我是小刘</p> <p v-else>我是谁呀</p> </div> </template> <script> export default{ data(){ return{ name:'小刘' } } }
前端显示:
我是小刘
4)v-show 用于判定自己本身是否被渲染
<template> <div> <p v-show="flag">看到了吗</p> </div> </template> <script> export default{ data(){ return{ flag:true, } } }
5)v-if与v-show相比较
v-if | v-show |
---|---|
“真实的”按条件渲染,因为它确保了在切换时,<br />条件区块内的事件监听器和子组件都会被销毁与重建。 | 简单许多,元素无论初始条件如何,始终会被渲染,<br />只有 CSS display 属性会被切换 |
惰性的:如果在初次渲染时条件值为 false,则不会做任何事。<br />条件区块只有当条件首次变为 true 时才被渲染。 | |
有更高的切换开销 | 有更高的初始渲染开销 |
如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则v-if会更合适。
5.列表渲染
使用v-for (item为元素值,index为元素所在数组中的下标)(item、index非固定,也可更换为其他名字)
item in names 或为item of names
(item,index) in students 或为(item,index) of students
也可用于遍历单个对象属性值:
<template> <div> <p v-for="(value,key,index) of user">{{ index }}--{{ key }}--{{ value }}</p> <!-- (属性值,属性名,下标) --> </div> </template> <script> export default{ data(){ return{ user:{ id:'0005', name:'root', password:'123456', } } } } </script>
前端:
0--id--0005 1--name--root 2--password--123456
通过key管理状态:
Vue 默认按照“就地更新”的策略来更新通过 v-for 渲染的元素列表。当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的 key attribute:(最好为id)
6.事件处理
我们可以使用v-on指令(简写为@)来监听DOM事件,并在触发时执行对应的JavaScript
用法:v-on:click="methodName"或@click="methodName"
1)内联事件处理器:事件被触发时执行的内联JavaScript语句
通常用于简单场景
<template> <div> <p>内联事件处理器</p> <button v-on:click="count++">add</button> <p>{{ count }}</p> </div> </template> <script> export default { data() { return{ count:1, } } } </script>
2)方法事件处理器:一个指向组件上定义的方法的属性名或是路径
以下代码效果与上图相同
<template> <div> <p>方法事件处理器</p> <button @click="addCount">add</button> <p>{{ count }}</p> </div> </template> <script> export default { data() { return{ count:1, } }, methods:{ addCount(){ this.count++; //读取到data里面的数据方案:this.count } } } </script>
7.事件参数
事件参数可以获取event对象和通过事件传递数据
1)获取event对象
2)传递参数
简单使用:
用于列表中的一项:
传递参数时获取event对象时写法:
@click="getName(item,$event)"
8.事件修饰符
1)阻止默认事件 @click.prevent=""
传统写法:
<template> <div> <p>事件修饰符</p> <a href="https://www.csdn.net" @click="clickHandle">csdn官网</a> </div> </template> <script> export default { methods:{ clickHandle(e){ e.preventDefault(); //会将原来的事件阻止 console.log("点击了链接!!!!"); } } } </script>
使用事件修饰符:
<template> <div> <p>事件修饰符</p> <a href="https://www.csdn.net" @click.prevent="clickHandle">csdn官网</a> </div> //@click.prevent 仍会阻止事件 </template> <script> export default { methods:{ clickHandle(e){ console.log("点击了链接!!!!"); } } } </script>
2)阻止事件冒泡 @click.stop=""
<template> <div> <p>事件冒泡</p> <div @click="clickDiv"> <p @click="clickP">p标签</p> </div> </div> </template> <script> export default { methods:{ clickDiv(e){ console.log("Div!!!!"); }, clickP(e){ e.stopPropagation(); //点击p标签时,父标签的函数不会被调用 console.log("P!!!!"); } } } </script>
使用修饰符:
<template> <div> <p>事件冒泡</p> <div @click="clickDiv"> <p @click.stop="clickP">p标签</p> //@click.stop 点击p标签时,父标签的函数不会被调用 </div> </div> </template> <script> export default { methods:{ clickDiv(e){ console.log("Div!!!!"); }, clickP(e){ console.log("P!!!!"); } } } </script>
9.数组变化侦测
1)变更方法:vue能够侦听响应式数组的变更方法,并在它们被调用时触发相关的更新。该数组已经更新,无需返回新数组
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
2)替换方法:对调用它们的原数组进行变更,需要返回一个新数组。
filter()
concat()
slice()
10.计算属性
计算属性:计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。
方法:方法调用总会在重渲染发生时再次执行函数。
所以,计算属性在某些场景使用时更合适。
11.Class绑定
1)对象绑定
2)使用数组
3)使用三木运算符(效果与上图相同)
<style> .active{ color: red; } .text-danger{ font-size: 40px; } </style> <template> <div> <p :class="[isActive?'active':'',isDanger?'text-danger':'']"> Class样式绑定5 </p> </div> </template> export default{ data(){ return{ isActive:true, isDanger:true, } } } </script>
4)数组和对象混用(只能数组里面嵌套对象)
12.Style绑定
与Class绑定差不多,一般也是使用对象/数组进行绑定
13.侦听器
我们可以使用watch选项在每次响应式属性发生变化时触发一个函数
14.表单输入绑定
在前端处理表单时,我们常常需要将表单输入框的内容同步给JavaScript中响应的变量,手动连接值绑定和更改监听器可能会很麻烦,
v-model指令把我们简化了这一步骤
v-model也提供了修饰符:.lazy、.number、.trim
使用:
<input type="text" v-model.lazy="massage"/> <-- .lazy不会立即给massage更新数据,输入框失去焦点后更新, .number属性值将实时更新成相同的字符串,即使后面输入数字,也将被视作字符串 .trim去掉首尾的空格 -->
15.模板引用
使用ref="",this.$refs获取dom
16.组件
1.组件组成
组件的最大优势就是可复用性
App.vue基本结构
<template> <div> <!-- 第三步.显示组件 --> <MyComponent /> </div> </template> <script> // 第一步.引入组件 import MyComponent from "./components/MyComponent.vue"; export default{ //第二步.注入组件 components:{ MyComponent } } </script> <!-- scoped:让当前样式只在当前组件中生效(若不需要可不加该属性,为全局生效) --> <style scoped> </style>
2.组件嵌套关系
组件之间可以相互嵌套
3.组件注册方式
一个vue组件在使用前需要先被注册,这样vue才能在渲染模板时找到其对应的实现
注册组件有两种方式:全局注册和局部注册
1)全局注册:
全局注册虽然很方便,但有以下几个问题:
(1)并没有被使用的组件无法在生产打包时被自动移除(也叫“tree-shaking”)。如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的JS文件中
(2)全局注册在大型项目中使项目的依赖关系变得不那么明确。在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的维护性
2)局部注册:
需要使用components选项(推荐使用局部注册方式)
17.组件传递数据_props
props传递数据,只能从父级传递到子级,不能反其道而行之
注:props传递过来的数据是只读的,不允许修改
(1)父组件静态传递多个数据到子组件
(2)动态传递
18.组件传递多种数据类型
//传递任何数据类型均可:字符串,数字,布尔型,数组,对象,对象数组...... massage:"今天我吃饭了哦", massage2:"今天很开心~", massages:["asd","qwe","zxc"], user:{ username:"李明", password:"zxc123", sex:"男", age:18 }, users:[{username:"李明", password:"zxc123", sex:"男", age:18}, { username:"张强", password:"123456", sex:"男", age:23}, { username:"王宏", password:"qwerew", sex:"女", age:20},], //子组件接收数组时,可以使用v-for(不使用也可) <ul> <li v-for="(item,index) in massages" :key="index">{{ item }}</li> </ul> <ul> <li v-for="(item,index) in users" :key="index">{{ item.age }}</li> </ul>
19.组件传递props校验
type,default,required
props:{ name:{ type:[String,Number,Array,Object], //传递数据的类型,不符合会警告 required:true //必选项设置,true为必选 }, age:{ type:Number, default:0 //传递数据的默认值,未传递时将为该值0 }, sex:{ type:String, default:"男" }, // 数字和字符串可以直接设置default,但是如果是数组和对象,必须通过工厂函数返回默认值 names:{ type:Array, default(){ return ["aaa","bbb"] //数组和对象,必须通过工厂函数返回默认值 } } }
20.组件事件
在组件的模板表达式中,可以直接使用$emit方法触发自定义事件
触发自定义事件的目的是组件之间传递数据
组件之间传递数据的方案: (1)父传子:props (2)子传父:自定义事件 this.$emit
21.组件事件配合v-model使用
案例:监听子组件的数据并传递到父组件
22.组件数据传递
props使用函数将数据从子组件传递到父组件
23.透传
属性继承
在父组件引用子组件时添加属性
24.插槽Slot
(1)slot元素
slot元素是一个插槽出口,标示了父元素提供的插槽内容将在哪里被渲染
(2)渲染作用域
插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的
(3)默认内容
在外部没有提供任何内容的情况下,可以为插槽指定默认内容,直接在<slot></slot>元素内部指定默认内容即可
提供了内容则显示内容
(4)具名插槽
在父组件指定插槽的名称:
<template> <div> <SlotComponentB > <template v-slot:名称> <-- 其中v-slot:可简写为#,即为“#名称” --> <-- 插槽内容 --> </template> </SlotComponentB > <div> <template>
(5)数据传递
将子组件的数据通过插槽传递给父组件
具名插槽写法如下:
25.组件的生命周期
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码
组件的生命周期:
-
生命周期函数:
-
创建期:beforeCreate created
-
挂载期:beforeMount mounted
-
更新期:beforeUpdate updated
-
销毁期:beforeUnmount unmounted
<template> <div> <p>组件生命周期</p> <p>{{ hello() }}</p> <p>{{ massage }}</p> <button @click="changeMassage">更新数据</button> </div> </template> <script> /** * 组件的生命周期 * 生命周期函数 * 创建期:beforeCreate created * 挂载期:beforeMount mounted * 更新期:beforeUpdate updated * 销毁期:beforeUnmount unmounted * */ export default{ data(){ return{ massage:"hello", } }, methods:{ hello(){ console.log("hello world!!!"); }, changeMassage(){ this.massage="world"; console.log("数据更新了"); } }, beforeCreate(){ console.log("组件创建之前"); }, created(){ console.log("组件创建之后"); }, beforeMount(){ console.log("组件渲染之前"); }, mounted(){ console.log("组件渲染之后"); }, beforeUpdate(){ console.log("组件更新之前"); }, updated(){ console.log("组件更新之后"); }, beforeUnmount(){ console.log("组件销毁之前"); }, unmounted(){ console.log("组件销毁之后"); }, } </script>
26.生命周期应用
(1)通过ref获取元素dom结构
使用ref="",this.$refs获取dom
(2)模拟网络请求渲染数据
组件渲染后加载网络请求的数据
27.动态组件
在两个组件ComponentA和ComponentB之间来回切换
使用<component :is=""></component>
<template> <div> <component :is="tabComponent"></component> <button @click="changeComponent">切换组件</button> </div> </template> <script> import ComponentA from './components/ComponentA.vue'; import ComponentB from './components/ComponentB.vue'; export default{ data(){ return{ tabComponent:"ComponentA", } }, components:{ ComponentA, ComponentB, }, methods:{ changeComponent(){ this.tabComponent=(this.tabComponent=="ComponentA"?"ComponentB":"ComponentA"); } }, } </script>
28.组件保持存活
当使用<component :is="tabComponent"></component>在多个组件之间来回切换时,被切换掉的组件会被卸载,
我们可以通过<keep-alive>组件强制被切换掉的组件仍然保持“存活”的状态
<keep-alive> <component :is="tabComponent"></component> </keep-alive> <button @click="changeComponent">切换组件</button>
29.异步组件
在使用组件时加载该组件
import {defineAsyncComponent} from 'vue'; // 异步加载ComponentB组件 const ComponentB = defineAsyncComponent(() => import("./components/ComponentB.vue") )
30.依赖注入
通常情况下,当我们需要从父组件向子组件传递数据时,会使用props。
想象一下这样的结构:有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。
在这种情况下,如果仅使用props则必须将其沿着组件链逐级传递下去,这会非常麻烦。
这一问题被称为“prop逐级透析”。
provide 和 inject 可以帮助我们解决这一问题。一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
*注:provide 和 inject只能由上到下的传递,不能反向传递
(1)传递静态数据
(2)传递静态和动态数据均可
(3)全局数据
任何组件使用 inject:["数据名称"] 接收即可
31.ajax函数库axios的使用
介绍:axios对原生的Ajax进行了封装,简化书写,快速开发
使用步骤:
-
到项目目录下安装axios:npm install axios
-
引入axios的js文件
-
使用axios发送请求,并获取相应结果(注意:后端要设置支持跨域,在controller类上添加注释:@CrossOrigin)
<script> import axios from 'axios' // 发送请求 axios({ method:'get', // 请求方式 url:'http://localhost:8080/test', // url }).then(result=>{ // 成功的回调 // result代表服务器响应的所有的数据,包含了响应头、响应体,result.data代表的是接口响应的核心数据 alert(result.data.name); }).catch(err=>{ // 失败的回调 alert(err); alert("fail"); }); </script>