文章目录
Vue学习笔记
一、Vue 简介
1、什么是 Vue
一套用于构建用户界面的渐进式 JavaScript 框架。
1.1 MVVM 模型
MVVM 是 Vue 实现 数据驱动视图 和 双向数据绑定 的核心原理。
MVVM指的是 Model 、View、和 ViewModel ,它把每个HTML页面都拆成了这三个部分。
其中 ViewModel 是核心:
2、Vue 的特点
1)数据驱动视图
Vue 会监听数据的变化,从而自动重新渲染页面的结构
好处:当页面发生变化时,页面会自动重新渲染
坏处:数据驱动视图是单向的数据绑定
2)双向数据绑定
在填写表单时,双向数据绑定可以辅助开发者在不操作 DOM 的前提下,自动把用户填写的内容同步到数据源中。
好处:开发者不需要手动操作 DOM 元素来获取表单元素最新的值
3、Vue 的基本使用
1)导入 Vue.js 的 Script 脚本文件
2)在页面中声明一个将要被 Vue 控制的 DOM 区域
3)创建 vm 实例对象(Vue 实例对象)
4、Vue 的指令
指令是 Vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
是 Vue 中最基础、最简单、最常用的知识点
内容渲染指令
v-text 缺点:会覆盖元素内部原有的值
{{ }} 解决了会覆盖元素内部原有的值的问题,实际开发中用的最多
注意:插值表达式 只能用在元素的内容节点中,不能用在元素的属性节点中
v-html 把包含 HTML 标签的字符串渲染为页面的 HTML 元素
属性绑定指令
- v-bind 为元素的属性动态绑定值;也可简写为一个冒号 :
事件绑定指令
v-on 用来辅助程序员为 DOM 元素绑定事件监听,可以简写为 @
Vue 提供了内置变量,名字叫做 $event ,它就是原生 DOM 的事件对象 e
事件修饰符:
.prevent 作用是阻止默认事件的发生
.stop 阻止事件冒泡
按键修饰符:
在监听键盘事件时,我们经常要判断详细的按键。此时,可以键盘相关的事件添加按键修饰符
.enter
.esc 等等
双向绑定指令
v-model 只有表单元素才能使用(才有意义)
条件渲染指令
条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏
- v-if 每次动态创建或移除元素,实现元素的显示和隐藏
如果刚进入页面时,某些元素默认不需要被展示,而且后期也不需要被展示,此时应该用 v-if
v-else-if
这是充当 v-if 的 “else-if 块” ,可以连续使用
v-else
- v-show 动态为元素添加或移除 display:none 样式来实现显示和隐藏
如果要频繁的切换元素的显示状态,用 v-show 性能更好
列表渲染指令
v-for 指令还支持一个可选的第二参数,即当前项的索引。语法为(item,index) in items
item in items 形式的特殊语法
- items 需要循环的数组
- item 名字
:key 官方建议,只要用到了 v-for 指令,一定要绑定一个 :key 属性,尽量把 id 作为 key 的值
key 的值只能是字符串或数字,key 的值必须具有唯一性
<tr v-for="(item,index) in items" :key="item.id"> </tr>
5、Vue 的过滤器
因为 Vue3 里过滤器这块已经被删了,所以不作为重点,理解就好
常用于文本的格式化,可以用在两个地方
- 插值表达式
- v-bind 属性绑定
1、过滤器应该被添加到 JavaScript 的尾部,由“管道符”进行调用 |
<p>{{ message | capitalize }}</p> // 后面一个是返回值 <div v-bind=""></div>
2、私有过滤器和全局过滤器
可以连续地调用多个过滤器
当有多个过滤器时,每一遍过滤都会返回一个值,这样依次过滤,最后一个过滤器返回的值即为最后的值
6、总结
二、Vue 基础
1、watch 侦听器
watch 侦听器允许开发者监视数据变化,从而针对数据的变化做特定的操作
<body>
<div id="app">
<input type="text" v-model="username">
</div>
<script src="./lib/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: ''
},
// 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
watch: {
// 新值再前,旧值在后
username(newVal, oldVal) {
console.log('监听到了变化!!', newVal, oldVal)
}
}
})
</script>
</body>
watch: {
username(newVal) {
if(newVal === '') return
// 调用 JQuery 中的AJAX请求,判断newVal是否可用
$.get('https://www.escook.cn/api/finduser/' + newVal, function (res) {
console.log(res)
})
}
}
1.1 方法格式的侦听器
- 缺点1:无法在刚进入页面的时候,自动触发
- 缺点2:如果侦听的是一个对象,如果对象的属性发生了变化,不会触发侦听器
1.2 对象格式的侦听器
- 好处1:可以通过 immediate 选项,让侦听器自动触发!fale 是默认值
- 好处2:可以通过 deep 选项,让侦听器深度监听对象中每个属性的变化!!!(深度监听)
2、计算属性
计算属性值得是通过一系列运算之后,最终得到的一个属性值
这个动态计算出来的属性值可以被模板结构或 methods 方法使用
2.1 特点:
- 在定义的时候,要被定义为方法
- 在使用计算属性的时候,当普通的属性使用即可
2.2 好处:
- 实现了代码复用
- 只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值
3、axious 介绍
axios 是一个专注于网络请求的库
3.1 发起 GET 请求
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 调用axios 方法得到的返回值是 Promise 对象
axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
// URL 中的查询参数, GET 传参用这个
param:{}
// 请求体参数, POST 传参用这个
data: {}
}).then(function (result) {
console.log(result)
})
</script>
3.2 发起 POST 请求
<button id="btnPost"></button>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 如果每个方法的返回值是 Promise 实例,则前面可以添加 await
// await 只能用在被 async “修饰”的方法中
document.querySelector('btnPost').addEventListener('click', async function() {
await axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: {
name: 'zs',
age:20
}
})
})
</script>
解构赋值:
3.3 基本使用
以前的方式的缺点:不利于 api 的复用
4、vue-cli 基本使用
简化了程序员基于 webpack 创建工程化的 Vue 项目的过程
4.1 安装和使用
安装:
npm install -g @vue/cli
使用 vue-cli 快速生成工程化的 Vue 项目
vue create 项目的名称
使用 npm run serve 启动项目
4.2 Vue 项目的运行流程
在工程化的项目中,Vue 要做的事情非常单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。
main.js 文件:
// 导入 vue 这个包,得到 vue 构造函数
import Vue from 'vue'
// 导入 App.vue 根组件,将来要把 App.vue 中的模板结构渲染到 HTML 中
import App from './App.vue'
// import Test from './Test.vue'
Vue.config.productionTip = false
// 创建 Vue 的实例对象
new Vue({
// 把 render 函数指定的组件,渲染到 HTML 页面中
render: h => h(App),
}).$mount('#app')
// Vue 实例的 $mount() 方法,作用跟 el: "" 一样!
5、组件化开发
指的是:根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护
组件的后缀名是 .vue 之前接触到的 App.vue 文件本质上就是一个 vue 组件。
每个 .vue 组件都有三个组成部分:
- template 组件的模板结构
- script 组件的JavaScript行为
- style 组件的样式
5.1 组件中定义 methods 方法
注意:如果想让组件识别 less 样式,需要在 style 标签的身上加上 lang=less
5.2 组件之间的父子关系
使用组件的三个步骤
注意:通过 components 注册的是私有组件
配置 @ 符号表示根路径
1、下载 VsCode 里面的插件 Path Autocomplete
2、在 settings.json 下增加如下配置:
// 导入文件时是否携带文件的拓展名 "path-autocomplete.extensionOnImport": true, // 配置 @ 的路径提示 "path-autocomplete.pathMappings": { "@": "${folder}/src" },
5.3 怎么注册全局组件
全局组件,一次注册,到处使用
5.4 组件的 props
props 是组件的自定义属性,在封装通用组件的时候,合理地使用 props 可以极大的提高组件的复用性
props 是只读的
vue 规定:组件中封装的自定义属性是只读的,程序员不能直接修改 props 的值,否则会报错
<script>
export default {
// props 是自定义属性,允许使用者通过自定义属性,为当前组件指定初始值
// 自定义属性的名字,是封装者自定义的(只要名称合法即可)
props:['init'],
data() {
return {
}
},
};
</script>
- props 的默认值为: default
props:[]只能接受值,无法定义默认值。
props:{init:{}}可以default定义默认值,还可以定义多个自定义属性
- props 的 type 属性
- props 的 required 必须项校验
5.5 组件之间的样式冲突问题
如何解决样式冲突问题?
给 style 加上 scoped 属性 :
<style lang = "less" scoped>
</style>
当使用第三方库的时候,如果有修改第三方组件默认样式的需求,需要用到 /deep/
5.6 vue 组件的实例对象
通过这个依赖,将以 .vue 结尾的文件渲染成 html 页面,不然浏览器是看不懂 .vue 结尾的文件的
5.7 最常用的 vue 组件库
6、生命周期
生命周期:是指一个组件从 创建 -> 运行 -> 销毁 的整个阶段,强调的是一个时间段
生命周期函数: 是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行。
注意:生命周期强调的是 时间段,生命周期函数强调的是 时间点
6.1 创建阶段
created 和 mounted 最常用
- created 组件的 props/data/methods 已经创建好,都处于可用状态,但是组件的模板结构尚未生成
- mounted 已经把内存中的 HTML 结构,成功的渲染到了浏览器中,此时浏览器中已经包含了当前组件的DOM结构
如果要操作当前组件的 DOM ,最早在 mounted 阶段执行
6.2 运行阶段
- 当数据变化了之后,为了能够操作到最新的 DOM 结构,必须把代码写到 updata 生命周期函数中
6.3 销毁阶段
- destoryed 组件已经被销毁,此组件在浏览器中对应的 DOM 结构已经被完全移除!
7、组件之间的数据共享
7.1 父子组件之间的数据共享
父组件向子组件共享数据需要用到自定义属性 props
父 --> 子
子组件向父组件 共享数据 要使用自定义事件 $emit()
子 –> 父
兄弟组件之间的数据共享
vue 2.X 版本中,兄弟组件之间的数据共享的方案是 EventBus
使用步骤:
8、ref 引用
ref 用来辅助开发者在不依赖于 JQuery 的情况下,获取 DOM 元素或组件的引用
每个 vue 的组件实例上,都包含一个 $refs 对象,里面存储这对应的 DOM 元素或组件的引用。默认情况下,组件的 $ $refs 指向一个空对象
8.1 this.$nextTick(cb) 方法
组件的 this.$nextTick(cb) 方法,会把 cb 回调推迟到下一个DOM更新周期之后执行。通俗来讲就是:等组件的 DOM 更新完成之后,再执行 cb 回调函数。从而保证 cb 回调函数可以操作最新的 DOM 元素。
8.2 数组中的方法
- some 循环
some 循环,找到了该元素,循环就停止
-
every 循环
购物车中,判断商品是否全选的时候用 every 循环
- reduce 方法
累加器
经常与 filter 过滤器一起使用
9、动态组件
动态组件 指的是动态切换组件的显示与隐藏
vue 提供了一个内置的 组件,专门用来实现动态组件的渲染。
- 可以认为是一个占位符,由 is 属性决定选择哪个组件在它所占的位置
<script>
// import Left 和 Right 组件
export default{
data() {
return {
comeName: 'Left'
}
}
}
</script>
keep-alive
9.1 keep-alive 对应的生命周期函数
-
当组件 被缓存 时,会自动触发组件的 deactivated 生命周期函数
-
当组件 被激活 时,会自动触发组件的 activated 生命周期函数
keep-alive 中的 include 属性
用来指定:只有名称匹配的组件会被缓存。多个组件名之间使用英文的逗号分隔开
exclude 属性用来指定谁不会被缓存,两者只能用一个
<keep-alive include="Right"> <component :is="comName"></component> </keep-alive>
10、插槽
插槽(Slot) 是 vue 为组件的封装者提供的能力。允许开发者在组装组件时,把不确定的、希望由用户指定的部分定义为插槽。
官方规定:每一个 slot 插槽,都要有一个 name 名字,如果省略了,则有一个默认的名称叫做 default
v-slot: 指令的简写形式是 #
<template #default>
<p></p>
</template>
10.1 具名插槽
name 属性不是默认的 default 的插槽(有名字的插槽)
10.2 作用域插槽
在封装组件时,为预留的 提供属性对应的值,这种用法叫做作用域插槽
<div>
<slot name="content" msg="hello vue.js" :user="userinfo"></slot>
</div>
11、自定义指令
11.1 私有自定义指令
在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令
当指令第一次被绑定到元素上的时候,会立即触发 bind 函数
<h1 v-color>App 根组件</h1>
函数简写
如果 bind 和 update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式
11.2 全局自定义指令
全局共享的自定义指令,需要通过 “vue.directive()” 进行声明
可以简写为:
Vue.directive('color',function(el,binding) {
el.style.color = binding.value
})
12、eslint 的作用
可组装的 JavaScript 和 JSX 检查工具
常用语法规则:
12.1 配置 VsCode
VsCode 中的 ESlint 插件装上后,在第一行增加如下配置:
//ESlint 插件的配置
"editor.codeActionsOnSave": {
"source.fixAll": true,
},
Prettier - Code formatter 插件配置:
创建.prettierrc文件的内容:
{
"semi": false,
"singleQuote": true,
"bracketSpacing": true
}
settings.json中的配置如下:
"prettier.configPath": "C:\\Users\\HP\\.prettierrc",
// 安装Prettier配置
"eslint.alwaysShowStatus": true,
"prettier.trailingComma": "none",
"prettier.semi": false,
// 每行文字个数超出此限制将会被迫换行
"prettier.printWidth": 300,
// 使用单引号替换双引号
"prettier.singleQuote": true,
"prettier.arrowParens": "avoid",
// 设置 .vue 文件中,HTML代码的格式化插件
"vetur.format.defaultFormatter.html": "js-beautify-html",
"vetur.ignoreProjectWarning": true,
"vetur.format.defaultFormatterOptions": {
"prettier": {
"trailingComma": "none",
"singleQuote": true,
"semi": false,
"arrowParens": "avoid",
"printWidth": 300
},
"js-beautify-html": {
"wrap_attributes": false
},
},
13、路由
路由(router) 就是对应关系,简而言之 就是地址与组件之间的对应关系
前端路由的工作方式:
Hash 地址 与 组件 的对应
13.1 vue-router 的基本使用
vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 Vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换。
1、安包
npm i vue-router@版本号 -S
2、在 src 源代码目录下,新建 router/index.js 路由模块,并初始化如下代码
// 当前项目的路由模块 // 1、导入 Vue 和 VueRouter 的包 import Vue from 'vue' import VueRouter from 'vue-router' // 2、调用 Vue.use()函数,把 VueRouter 安装为 Vue 的插件 Vue.use(VueRouter) // 3、创建路由的实例对象 const router = new VueRouter() // 4、向外共享路由的实例对象 export default router
3、在 main.js 中导入模块,然后挂载路由的实例对象
4、使用
app.vue 中:
router-view 是占位符
index.js 中:
当 安装和配置了 vue-router 后,就可以使用 router-link 来替代普通的 a 链接了
<a href="#home">首页</a>
// 改写成下面:
<router-link to="/home"></router-link>
13.2 路由重定向
路由重定向指的是:用户在访问地址A 的时候,强制用户跳转到地址C,从而展示特定的组件页面。
通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向
13.2 嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由
通过 children 属性声明 子路由规则
13.3 默认子路由
如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则,叫做“默认子路由”
13.4 动态路由分配
作用:增强路由规则的复用性
动态路由:把 Hash 地址可变的部分定义为 参数项,从而提高路由规则的复用性
在 vue-router 中使用英文的冒号 (:) 来定义路由的参数项
{ path: '/movie/:id', component: Movie }
可以为路由规则开启 props 传参,从而方便地拿到动态参数的值
{ path: '/movie/:mid', component: Movie,props: true} //props:true 表示开启props传参
然后在组件里用 props 来接收
拓展:
13.5 导航
1、声明式导航
在浏览器中,点击链接实现导航的方式,叫做声明式导航
- 普通网页中点击 链接、vue项目中点击 都是属于声明式导航
2、编程式导航
在浏览器中,调用API方法实现导航的方式,叫做编程式导航
- 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航
13.6 导航守卫
导航守卫可以控制路由的访问情况
1、全局前置守卫
router.beforeEach(fn)
每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,程序员可以对每个路由进行访问权限控制
- 守卫方法的三个形参: to from next
next 函数的三种调用方式
实例代码:
三、ES6 模块化与异步编程高级用法
1、ES6 模块化简介
模块化的好处:降低了沟通的成本,极大方便了各个模块之间的相互调用。
ES6 模块化规范是:是浏览器与服务器端通用的模块化开发规范。
ES6 模块化规范中定义:
- 每个 JS 文件都是一个独立的模块
- 导入其他模块成员使用 import 关键字
- 向外共享模块成员使用 export 关键字
1.1 默认导出与默认导入
- 默认导出的语法: export default 默认导出的成员
- 默认导入的语法: import 接收名称 from ‘模块标识符’
注意事项:每个模块中,只允许使用唯一的一次 export default,否则会报错!
默认导入时接收的名称可以是任意名称,只要合法的成员名称即可
1.2 按需导出与按需导入
-
按需导出 : export 按需导出的成员
-
按需导入:import { s1 } from ‘模块标识符’
注意事项:
import info,{ s1,s2 as str2,say } from './按需导出.js'
1.3 直接导入并执行模块中的代码
如果只想单纯地执行某个模块中的代码,并不需要得到模块中向外共享的成员。此时,可以直接导入并执行模块代码
2、Promise
2.1 回调地狱
多层回调函数相互嵌套,就形成了回调地狱
2.2 promise 基本概念
- Promise 是一个构造函数
- Promise.protoytpe 上包含一个 .then() 方法
- .then() 方法用来预先指定成功和失败的回调函数
2.3 基于回调函数按顺序读取文件内容
- 基于 then-fs 读取文件内容
// 先安装包 npm i then-fs
- then-fs 的基本使用
调用 then-fs 提供的 readFile() 方法,可以异步地读取文件的内容,它的返回值是 Promise 的实例对象。
注意:上述代码无法保证文件的读取顺序,需要做进一步的改进!
- .then() 方法的特性
如果上一个 .then() 方法中返回了一个新的 Promise 实例对象,则可以通过下一个 .then() 继续进行处理。 通过 .then() 方法的链式调用,就解决了回调地狱的问题
2.4 通过 .catch 捕获错误
在 Promise 中的链式操作中如果发生了错误,可以使用 Promise.prototype**.catch 方法**进行捕获和处理
放在最后,则发生错误后就直接进行 .catch这,就不会执行 .then 了
2.5 Promise.all() 方法
Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .tnen 操作(等待机制)
2.6 Promise.race() 方法
Promise.race() 方法会发起并行的 Promise 异步操作,只要任何一个异步操作完成,就立即进行下一步的 .then 操作(赛跑机制)
谁执行得快,就拿它的结果当做最终的 result
2.7 基于 Promise 封装读文件的方法
方法封装要求:
调用 resolve 和 reject 回调函数
3、async 和 await
3.1 async /await简介
async /await 是 ES8 引入的新语法,用来简化 Promise 异步操作。在 async /await 出现之前,开发者智能通过链式 .then() 的方式处理 Promise 异步操作
注意事项:
4、EventLoop
JavaScript 是一门 单线程执行的编程语言。
4.1 EventLoop 事件循环的基本概念
5、宏任务和微任务
5.1 宏任务和微任务的执行顺序
交替执行
示例:
6、总结
四、vue ui可视化面板
1、利用 vue ui 创建可视化面板
vue ui
2、 element-ui
- 在 vue2 中安装 element-ui
npm i element-ui -S
- 引入
完整引入:
按需引入:
6、总结
四、vue ui可视化面板
1、利用 vue ui 创建可视化面板
vue ui
2、 element-ui
- 在 vue2 中安装 element-ui
npm i element-ui -S
- 引入
完整引入:
按需引入: