参考
- 前端最新Vue2+Vue3基础入门到实战项目全套教程,自学前端vue就选黑马程序员,一套全通关!
- 个人参照网页
- 项目课 | Vue.js 开发印象云笔记 | Zkeq の Coding 日志 (icodeq.com)
JavaScript高级起步
- 【黑马程序员前端JavaScript入门到精通全套视频教程,javascript核心进阶ES6语法、API、js高级等基础知识和实战教程】https://www.bilibili.com/video/BV1Y84y1L7Nn?p=157
1.APIs -133数组
1.1 数组map和join的方法
map
可以遍历数组处理数据,并且返回新的数组。map
重点在于有返回值,forEach
没有返回值
const arr = [20,30,40]
const newArr =arr.map(function(ele,index){
console.log(ele,index); // 数组元素 数组索引号
return ele+'岁'
})
console.log(newArr); // ['20岁', '30岁', '40岁']
join()
方法用于把数组中所有元素转换成一个字符串
数组元素是通过参数里面指定的分隔符进行分隔的,空字符串(”),则所有元素之间都没有任何字符。
const arr = [20,30,40]
console.log(arr.join('')); //203040
2.2函数参数
2.2.1动态参数
1、arguments
是函数内部内置的伪数组变量,包含了调用函数时所传入的所有实参
2、注意:它是个伪数组,它只存在于函数中
function getSum(){
let sum = 0
for(let i = 0; i<arguments.length; i++){
sum += arguments[i]
}
return sum
}
2.2.2剩余参数
1、...
是语法符号,置于最末形参之前,用于获取多余的实参(没错,这个...
就是剩余参数)
2、借助...
获取剩余的实参,是个真数组
3、开发中用于获取多余的实参
如 funtion sum(...arr){}
开发中,提倡多使用剩余参数。
这里补充一个 展开运算符
展开运算符是可以运用在数组
它的作用是用来展开数组的,并不会修改原数组
典型运用场景:求数组最大值,最小值
2.3箭头函数(重要)
// 之前写法
const sum = function(x){
return x+x
}
console.log(sum(1))
// 箭头函数
const sum = (x) => x+x
console.log(sum(1))
const sum = x => x+x
console.log(sum(1))
// 箭头函数可以直接返回一个对象。当然,正如下面所说,只有一个实参时,这里(uname)中的()也是可以省略的
// 属性名:属性值
const fn = (uname) => ({name:uname})
console.log(fn('张三'));
可以看到,省略了花括号{}
,并且也无需return
,甚至当只有一个实参时,(x)
中的()
也是可以省略的,只留下x
。
注意这里仍然没有使用花括号{}
,因此无需return
const fn = (uname,gender) => (
{ name:uname,
gender:gender,
}
)
console.log(fn('张三','男'));
// 控制台输出 {name: '张三', gender: '男'}
1、箭头函数属于表达式函数,因此不存在函数提升
2、箭头函数只有一个参数时可以省略圆括号
3、箭头函数函数日只有一行代码时可以省略花括号,并自动为返回值被返回
4、加括号的函数体返回对象字面量表达式
学到这里你可能想用剩余参数加上箭头函数,这是可以的。但注意,箭头函数并没有arguments,所以只能使用剩余参数
接着是this
;this
是谁调用的this就指向谁;但是在这里,箭头函数没有自己的this
,它只会从自己的作用域链的上一层沿用this
。
const obj = {
uname:'pink老师',
sayHi: function(){
console.log(this);
}
}
obj.sayHi()
// 这两个的this指向是不一样的上面指向obj 下面指向window
const obj = {
uname:'pink老师',
sayHi: () => {
console.log(this);
}
}
obj.sayHi()
只有函数里面才会有this
。
// 普通函数,此时this指向DOM对象
btn.addEventListener('click', function(){
console.log(this);
})
// 箭头函数,此时this对象指向window
btn.addEventListener('click',() =>{
console.log(this);
})
在DOM事件回调函数为了方便,还是不太推荐使用箭头函数。更多this问题,我们后面再详细说说。P157
3解构赋值
3.3 数组对象解构
单一数组对象解构
const obj = [
{
name: '张三',
age: 18
}
];
// 数组对象解构
[{name,age}] = obj
console.log(name);
// 对解构的变量名进行重命名
// 旧名:新名
[{name:username,age: ages}] = obj
console.log(username);
多级对象解构
const pig= {
name: '小猪佩奇',
family : {
father: '猪爸爸',
mother: '猪妈妈'
},
age: 5
}
// 对象解构
const {name, family, family: {father, mother}, age} = pig
console.log(name);
console.log(family);
console.log(father);
console.log(mother);
console.log(age);
多级对象数组解构
const msg={
"code": 200,
"msg": "success",
"data":[
{
"id": 1,
"title": "5G商用,三大运营商收入下降",
"count": 100
},
{
"id": 2,
"title": "突发,美国宣布对华为实施新制裁",
"count": 510
},
{
"id": 3,
"title": "俄乌战争持续冲突",
"count": 1669
}
]
}
// 取出data
// 1.const { data } = msg;
// 或
// function render(msg) {
// const {data} = msg
// console.log(data);
// }
// 上面这种写法显然麻烦,让我们换一种写法
function render({data}){
// 相当于 const {data} = msg,这里只接受data
console.log(data);
}
// 当然,也可以重命名
function render({data:myData}){
console.log(myData);
}
render(msg)
4.遍历数组 forEach 方法(重点)
forEach()
方法用于调用数组的而每一个元素,并将元素传递给回调函数
主要使用场景:遍历数组的每个元素,不返回值
//语法(加强版的 for 循环):
被遍历的数组.forEach(function (当前数组元素,当前元素索引号){函数体}
//例如:
// forEach 就是遍历 加强版的for循环 适合于遍历数组对象
const arr = ['red', 'green', 'pink']
const result = arr.forEach(function (item, index) {
console.log(item) // 数组元素 red green pink
console.log(index) // 索引号 0 1 2
})
// console.log(result) // undefined
注意:forEach
主要是遍历数组
参数当前数组元素必须要写,索引号可选
5.筛选数组 filter 方法(重点)
filter()
方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
主要使用场景:筛选数组符合条件的元素,并返回筛选之后元素的新数组
// 语法
被遍历的数组.filter(function(currentValue,index){
// 返回值为true,保留,false,删除
return 筛选条件
})
// 例如
// 遍历数组,返回一个指定条件新数组
const arr = [20,30,40]
const newArr = arr.filter(item => {
// console.log(item);
return item > 20
})
console.log(newArr); // (2) [30, 40]
静态方法(内置构造函数)
Object
const o = {name:'pink',age:18}
const oo = {}
console.log(Object.keys(o)); // ['name','age']
console.log(Object.values(o)); // ['pink',18]
console.log(Object.assign(oo,o)); // oo ={name:'pink',age:18}
console.log((Object.assign(o,{gender:'女'}))) // {name: 'pink', age: 18, gender: '女'}
Array
方法 | 作用 | 说明 |
---|---|---|
forEach | 遍历数组 | 不返回数组,经常用于查找遍历数组元素 |
filter | 过滤数组 | 返回新数组,返回的是筛选满足条件的数组元素 |
map | 迭代数组 | 返回新数组,返回的是处理之后的数组元素,想要使用返回的新数组 |
reduce | 累计器 | 返回累计处理的结果,经常用于求和等 |
arr = [1,2,3,4,5]
// arr.reduce(function(上一次值,当前值,当前索引,当前数组){
// return 上一次值 + 当前值
// },初始值)
// 初始值可选,不传默认为0,上一次值默认为初始值。
// arr.reduce(function(上一次值,当前值){},初始值)
// 简单写法 arr.reduce(function(pre,cur){return pre + cur},0)
const sum = arr.reduce(function(pre,cur,index,arr){
console.log(pre,cur,index,arr);
return pre + cur
},0)
console.log(sum); // 15
//箭头函数
const totals = arr.reduce((prev,cur) => prev+cur,0)
console.log(totals); // 15
接下来是其他方法(部分已经讲过)
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array
- 实例方法
join
数组元素拼接字符串,返回字符串(重点) - 实例方法
find
查找元素,返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回undefined
(重点) - 实例方法
every
检测数组所有元素是否都符合指定条件,如果所有元素都通过检测返回true
,否则返回false
(重点)
String
实例方法 split
把字符串转数组
const strs = 'pink,red'
const arrs = strs.split(',')
console.log(arrs); // ['pink', 'red']
本地存储数据
持久化:
// 存储
watch:{
list:{
deep:true,
handler(newVlaue){
localStorage.setItem('list',JSON.stringify(newVlaue))
}
}
}
// 取出
list:JSON.parse(localStorage.getItem('list')) || {}
起步
- Node.js — Run JavaScript Everywhere (nodejs.org)(必要下载)
- Visual Studio Code – Code Editing. Redefined(必要下载,代码编辑器)
- 安徽省职业院校技能大赛
- Home | Vue CLI (vuejs.org)(通过NodeJS安装)
- HBuilderX-高效极客技巧 (dcloud.io)(代码编辑器)
NodeJS
安装完成后,可使用在命令行输入 node -v
查看nodejs版本号
安装完nodejs后,防止因网络原因 拉取/下载 项目失败,请务必使用国内镜像源。
命令如下(镜像源由npmmirror 镜像站提供)
npm config set registry https://registry.npmmirror.com
Vue-Cli
在命令提示符中输入
npm install -g @vue/cli
vue-cli版本号:在命令行输入 vue -V
即可查看
vue版本号:需要在Vue项目目录内,使用 npm list vue
即可查看
Vue2
创建基于Vue-Cli项目的架子
在命令行内输入
vue create project-name
// 稍等片刻你将看到
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, Linter
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) No
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
Vue CLI v5.0.8
✨ Creating project in D:\Filedata\web\project\anjnds_project\ah.
🗃 Initializing git repository...
⚙️ Installing CLI plugins. This might take a while...
added 872 packages in 19s
100 packages are looking for funding
run `npm fund` for details
🚀 Invoking generators...
📦 Installing additional dependencies...
added 90 packages in 3s
112 packages are looking for funding
run `npm fund` for details
⚓ Running completion hooks...
📄 Generating README.md...
🎉 Successfully created project ah.
👉 Get started with the following commands:
$ cd ah
$ npm run serve
参考视频:088-基于VueCli自定义创建项目_哔哩哔哩_bilibili
使用 cd
命令进入你的项目目录
使用 npm run server
启动Vue项目,打开浏览器访问 http://localhost:8080/ 欢迎页面
至此你已完成Vue项目的创建
050组件通信
父子关系
props和$emit
- 父组件通过props将数据传递给子组件
- 子组件利用$emit通知父组件修改更新
父→子
// App.vue
<div>
<son-view :title="SonTitle"/>
</div>
<script>
import SonView from '@/views/SonView.vue'
export default {
components: {
SonView,
},
data () {
return {
SonTitle: 'Welcome to Your itheima'
}
},
}
</script>
// SonView.vue
<template>
<div>
<h1>SonView</h1>
<h2>{{ title }}</h2>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
// required: true
}
}
}
</script>
子→父
// App.vue
<son-view :title="SonTitle" @changeTitle="changeFn"/>
methods: {
//
changeFn(newTitle){
this.SonTitle = newTitle
}
}
// SonView.vue
<template>
<div>
<h1>SonView</h1>
<h2>{{ title }}</h2>
<button @click="handleClick">向父组件通知</button>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
// required: true
}
},
methods: {
handleClick () {
// 告诉父组件,修改成啥
this.$emit('changeTitle','子组件通知父组件')
}
}
}
</script>
父子通信方案的核心流程
父传子:props:
1、父中给子添加属性传值 2、子props接收 3、使用
子传父$emit:
1、子$emit发送消息 2、父中给子添加消息监听 3、父中实现处理函数
// 数组可使用join(”)完成转换
props校验
// 完整写法(类型、非空、默认、自定义)
props:
校验的属性名: {
type: 类型,// Number String Boolean
required: true,// 是否必填
default: 默认值,// 默认值
validator (value){
// 自定义校验逻辑
return 是否通过校验
}
}
},
完整代码如下
// Vue.app
<template>
<div id="app">
<div>
<!-- 事件名 父组件处理函数 -->
<son-view :title="SonTitle" @changeTitle="changeFn"
:username="name"
:userage="age"
:issingle="isSingle"
:car="car"
:hobby="hobby"
/>
</div>
<router-view/>
</div>
</template>
<script>
import SonView from '@/views/SonView.vue'
export default {
components: {
SonView,
},
data () {
return {
SonTitle: 'Welcome to Your itheima',
name: 'itheima',
age: 18,
isSingle: true,
car: {brand: 'BMW',},
hobby: ['coding', 'reading', 'running']
}
},
methods: {
//
changeFn(newTitle){
this.SonTitle = newTitle
}
}
}
</script>
// SonView.vue
<template>
<div>
<h1>SonView</h1>
<h2>{{ title }}</h2>
<button @click="handleClick">向父组件通知</button>
<ul>
<li><h2>个人信息</h2></li>
<li>姓名:{{ username }}</li>
<li>年龄:{{ userage }}</li>
<li>是否单身:{{ issingle ? '是' : '否'}}</li>
<li>座驾:{{ car.brand }}</li>
<li>兴趣爱好:{{ hobby.join('、') }}</li>
</ul>
</div>
</template>
<script>
export default {
props:
// ['title', 'username','userage','issingle','car','hobby'],
{
title: {
type: String,
required: true
},
username: String,
userage: {
type: Number,
required: true,
default: 18,
validator(value){
console.log(value);
if(value<0 || value >150){
console.error("年龄校验错误 您输入的是 userage 年龄不得小于0且不得大于150");
return false
}else{
return true
}
}
},
issingle: Boolean,
car: Object,
hobby: Array
},
methods: {
handleClick () {
// 告诉父组件,修改成啥
this.$emit('changeTitle','子组件通知父组件')
}
}
}
</script>
非父子关系
- provide & inject
- eventbus
todo
通用解决方案 Vuex(适合复杂业务场景)
v-model详解
v-model实际上就是 :value=”msg” 和 @input=”msg = $event.target.value”
表单类组件封装
// FatherView.vue
<SonView :select="selectId" @selectCityId="selectId=$event"></SonView>
<script>
import SonView from '@/views/SonView.vue'
export default {
components: {
SonView
},
data() {
return{
selectId:'102',
}
},
}
</script>
// SonView.vue
拆解 :value="父组件传来的值" @change="handleSelect"
<script>
export default {
props:{
select:{
default:'101'
}
},
methods:{
handleChangeSelect(e){
this.$emit("selectCityId",e.target.value)
}
}
}
</script>
// 再来
<SonView v-model="selectId"></SonView>
<select :value="value" @change="handleChangeSelect"></select>
props:{value:String},
methods:{
handleChangeSelect(e){this.$emit("input",e.target.value)}
}
.sync修饰符
:属性名 和 @update:属性名 合写
<BaseDialog :value="isShow" @update="isShow = $event"/>
<BaseDialog :visible.sync="isShow"/>
// 以上二选一
props:{visible:Boolean},
this.$emit('update.属性名',false)
$nextTick()
this.$nextTick(()=>{ /* 业务逻辑*/ })
自定义指令
// 全局注册
Vue.directive('指令名', {
'inserted' (el) {
// 可以对el标签,扩展额外功能
el.focus()
}
})
// 局部注册
directives:{
'指令名':{
inserted(el){
el.focus()
}
}
}
// 使用
<input v-指令名="" type="text">
// 补充 binding.value可以拿到指令值如:v-color="pink"
inserted(el,binding){}
update(el,binding){}
el.classList.add(“css样式标签”)
插槽
// 不同页面数据调用(仅为示例)
// SonView.vue
<main v-for="(item,index) in list" :key="item.id">
<slot name="body" :item="item" :index="index"></slot>
</main>
// FatherView.vue
<main>
<template #body="obj"> //或者解构 {item,index}
<tr>
<td>{{ obj.index+1 }}</td>
<td>{{ obj.name }}</td>
<td>{{ obj.sex }}</td>
</tr>
</template>
</main>
单页应用程序
单页面应用(SPA):Single Page Application
路由(Vue Router)
安装:安装 | Vue Router↗
按照(2 3 3 \3 4 4):即 Vue2 VueRouter3.x Vuex3.x \ Vue3 VueRouter4.x Vuex4.x
关于Vuex后面会介绍到。
安装命令:
npm install vue-router@3.6.5
自定义高亮类名
<router-link to="/my"/>
,会自带类名,可以通过下面的方式自定义类名。
在 routes:[]
同级别下使用 linkActiveClass:'自定义类名',linkExactActiveClass:'自定义类名'
路由传参
查询参数传参(适合传多个参数)$route.query.参数名
如:/search?keys=黑马程序员
$route.query.keys
动态路由传参(优雅,适合传单个参数)$route.params.参数名
如:/search/黑马程序员
$route.params.keys
另:路由需配置为/search/:keys
注:/search/:keys
表示必须传参,如果不传参数,也希望匹配,可以加个可选符”?
“
编程式导航
通过路径跳转(简单方便)this.$router.push("路由路径")
this.$router.push({path:"路由路径"})
通过路由名字跳转(适合路径名字长的场景)this.$router.push({name:"路由名"})
{name:"路由名",path:"/path/XXX",...}
Vue3
参考
pnpm 基本详细使用教程(安装、卸载、使用、可能遇到的问题及解决办法)-CSDN博客
起步
Vue.js – 渐进式 JavaScript 框架 | Vue.js (vuejs.org)
安装PNPM
npm i -g pnpm
创建项目Vue3
在命令行内输入
pnpm create vue
// 随后你将看到
C:\Users\Desktop\web>pnpm create vue
.../1900adaf91d-4da0 | +1 +
.../1900adaf91d-4da0 | Progress: resolved 1, reused 1, downloaded 0, added 1, done
Vue.js - The Progressive JavaScript Framework
√ 请输入项目名称: ... project-name
√ 是否使用 TypeScript 语法? ... 否 / 是
√ 是否启用 JSX 支持? ... 否 / 是
√ 是否引入 Vue Router 进行单页面应用开发? ... 否 / 是
√ 是否引入 Pinia 用于状态管理? ... 否 / 是
√ 是否引入 Vitest 用于单元测试? ... 否 / 是
√ 是否要引入一款端到端(End to End)测试工具? » 不需要
√ 是否引入 ESLint 用于代码质量检测? ... 否 / 是
√ 是否引入 Vue DevTools 7 扩展用于调试? (试验阶段) ... 否 / 是
正在初始化项目 C:\Users\Desktop\web\project-name...
项目初始化完成,可执行以下命令:
cd project-name
pnpm install
pnpm dev
请根据实际开发来选择,一般来说会选择Vue Router和Pinia。