
学习自:B站up主FastAPIyesAIyes、菜鸟教程
为什么要学习vue
为什么要学习vue–为了实现前后端分离,为了实现数据驱动视图,为了减少DOM操作。。。让vue帮我们操作DOM,我们可以更加关注业务逻辑的开发。
未来的发展趋势是前后端只靠json数据进行通信,后端只处理和发送一段json到前端,计算和模板渲染都在前端进行,后台程序不再做模板的任何处理。使用MVVM框架能有效实现前后端的解耦,简化开发流程,便于维护管理,可以把精力更多放到业务逻辑,提升开发效率。
VUE生命周期
created
- 在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图
mounted
- 在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作
vue项目中组件created时,组件中的data和method准备就绪,data中的数据是依赖于axios请求过来的数据的,所以一般在created生命周期函数中发起网络请求
Hello World
Vue.js 的使用有多种方式,可以到官网下载依赖文件使用script标签引用到项目中,也可以使用cdn的方式引入到项目中,或者使用vue-cli创建项目。
vue-cli创建项目
使用vue-cli创建vue项目。
环境搭建
安装node.js,官网:http://nodejs.cn。(历史版本下载:[传送门](https://npm.taobao.org/mirrors/node/))
判断是否安装成功,使用命令:node -v
建议npm配置淘宝源(cnpm):
1 |
npm config set registry http://registry.npm.taobao.org/ |
安装cnpm:
1 |
npm install -g cnpm --registry=https://registry.npm.taobao.org |
创建项目
vue2.x
1 |
#安装vue2.x版本的脚手架(若安装失败可以试试管理员权限进行安装,前边加sudo) |
如何进入某目录打开cmd控制台:地址栏输入cmd后回车或者按住shift键单击鼠标右键选择powershell
案例:
1 |
qsdbl@qsdbl vue-project % vue init webpack pos //项目名为pos,vue-project目录专门放vue项目 |
vue3.x
1 |
#安装vue3.x版本的脚手架。若安装失败可以试试管理员权限进行安装,前边加sudo |
vue管理器:
vue管理器,vue3.x特有。使用vue管理器可以使用图形化界面管理vue项目(创建、删除等)
打开vue管理器,命令行界面中输入命令:vue ui
。
浏览器输入http://localhost:8000
。进入vue管理器:
更多vue3.x创建项目知识,见这篇博客。
项目结构
cdn导入vue
对于制作原型或学习,你可以这样使用最新版本:
1 |
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> |
对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:
1 |
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> |
第一个vue项目:
1 |
|
创建VUE对象
var vm = new Vue
中的Vue
,是前边使用cdn导入的js类,使用new创建了一个vue对象。构造方法中传递一个对象(json对象)进去:
- 其中el对应绑定的元素,可以是html页面中的类名
.app
、id名#app
、元素名div
等。这意味着我们接下来的改动全部在指定的元素(标签)内,外部不受影响。 - data对应绑定的数据,data为一个对象,其中的属性可以有很多。我们自定义一个
message
属性保存数据”Hello Vue!”。在html中使用插值表达式进行绑定(单向数据绑定)。
-
js中访问data中的message的值,可以使用
vm.$data.message
或vm.message
。 - 原始操作dom的方式:
document.querySelector('.app').innerHTML = "你好!👋";
- 使用vue对象操作dom:
vm.message="你好";
或vm.$data.message="你好";
-
js中访问data中的message的值,可以使用
- methods 用于定义的函数,可以通过 return 来返回函数值。
1 |
<script> |
操作data
对比:使用类名(class)绑定元素。将message改成inf。体验原始操作dom的方式和使用vue操作dom。
更多关于操作dom的笔记在后边
打包
部署到生产环境时别忘了使用适用于生产环境vue.js
直接下载并用 <script>
标签引入,Vue
会被注册为一个全局变量。
在开发环境下不要使用压缩版本,不然你就失去了所有常见错误相关的警告!
开发版本 包含完整的警告和调试模式
生产版本 删除了警告,33.46KB min+gzip
对于制作原型或学习,你可以这样使用最新版本:
1 |
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> |
对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏:
1 |
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> |
参考这篇博客。
vue2.x打包
命令:cnpm run build
。打包生成的文件放到根目录的dist文件夹内。
问题1:打包后访问异常
解决方法:将配置文件config/index.js
中的assetsPublicPath修改为相对路径(前边加个点即可)。
问题2:打包后icon失效
解决方法: 修改 build/utils.js
中的代码,加入 publicPath: '../../'
1 |
if (options.extract) { |
vue3.x打包
参考资料:
命令:npm run build
其实yarn run build 与 npm run build 命令作用相同。
注意事项:
打包时,将项目资源访问路径配置为相对路径,打包后的项目可直接以file协议访问站点(双击即可在浏览器访问),方便项目展示。配置与vue2.x项目中的不一样,具体配置如下:
在项目根路径下新建vue.config.js文件,添加以下配置:
1 |
module.exports = { |
注意:文件src/router/index.js
中的new VueRouter部分,有两个参数需要注意:mode、base。
-
若publicPath使用的不是相对路径,而是
/mywebapp/
这种web程序名构成的路径。则这里的参数base也要设置成一样的。 - 若publicPath使用的是相对路径,则不需要设置参数base的值,但是mode不建议设置成history。即要去掉该参数。
扩展:关于参数mode。
设置参数mode: 'history'
,则vue-router使用的是history模式。默认是hash模式,所以想使用hash模式去掉该参数即可。
- 若
vue-router
使用 hash 模式- 将网站部署到服务器或直接打开index.html文件即可访问
- 缺点:地址栏会有“
#
”。优点:不需要配置。
- 若
vue-router
使用 history 模式- 将网站部署到服务器后,需要进行相关配置才能正常访问。
- 缺点:配置麻烦。优点:地址栏不会有“
#
”。
vue案例
登陆/注册案例:传送门
数据绑定
数据绑定有:单向数据绑定、双向数据绑定。详细介绍,查看这篇博客。
v-bind
单向数据绑定。自下而上的单向数据绑定,下是指前端页面看不到的js,上是指展示在页面上的html。(可理解为设置后台数据只读)- 绑定标签,使用
v-bind
; - 非标签,使用插值表达式
(见上边hello world案例中的应用)
- 详细笔记,访问这里:传送门。
- 绑定标签,使用
v-model
双向数据绑定,前台更新数据后会立刻更新后台中的数据。(可理解为设置后台数据可读写)- 详细笔记,访问这里:传送门。
事件绑定
v-on
事件绑定。
详细笔记,访问这里:传送门。
模板语法
<!–67–>(双大括号)的文本插值
使用 v-html 指令用于输出 html 代码
HTML 属性中的值应使用 v-bind 指令。
以下实例判断 use 的值,如果为 true 使用 class1 类的样式,否则不使用该类:
1 |
<div v-bind:class="{'class1': use}"> |
指令
指令是带有 v- 前缀的特殊属性。
指令用于在表达式的值改变时,将某些行为应用到 DOM 上。如下例子:
实例:
1 |
<div id="app"> |
这里, v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
参数
参数在指令后以冒号指明。例如, v-bind 指令被用来响应地更新 HTML 属性:
1 |
<div id="app"> |
在这里 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定。
修饰符(后缀)
修饰符是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
1 |
<form v-on:submit.prevent="onSubmit"></form> |
.lazy
,焦点改变时触发。
过滤器(管道符)
Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化。由”管道符”指示, 格式如下:
1 |
<!-- 在两个大括号中 --> |
过滤器函数接受表达式的值作为第一个参数。
以下实例对输入的字符串第一个字母转为大写:
1 |
<div id="app"> |
过滤器可以串联:
1 |
{{ message | filterA | filterB }} |
过滤器是 JavaScript 函数,因此可以接受参数:
1 |
{{ message | filterA('arg1', arg2) }} |
这里,message 是第一个参数,字符串 ‘arg1’ 将传给过滤器作为第二个参数, arg2 表达式的值将被求值然后传给过滤器作为第三个参数。
条件语句
if-else
v-if、v-else、v-else-if
1 |
<div id="app"> |
这里, v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
1 |
<!-- Handlebars 模板 --> |
v-show
1 |
<h1 v-show="ok">Hello!</h1> |
小结
v-show小结:
1、v-show仅仅控制元素的显示方式,通过display属性的none
2、当我们需要经常切换某个元素的显示/隐藏时,使用v-show会更加节省性能上的开销
v-if小结:
1、v-if会控制这个DOM节点的存在与否。
2、如果在运行时条件很少改变,则使用 v-if 较好。
循环-for
v-for 指令
迭代数组
1 |
<div id="app"> |
迭代对象
1 |
<div id="app"> |
迭代整数
1 |
<div id="app"> |
多个参数
可以提供第二个的参数为键名:
1 |
<div id="app"> |
第三个参数为索引:
1 |
<div id="app"> |
模板中使用
模板中使用 v-for:
1 |
<ul> |
计算属性-computed
计算属性关键词: computed。(跟methods有点相似,但是依赖缓存)
1 |
<div id="app"> |
computed与methods有点相似,但又有所不同:
computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
computed与methods的不同点,还体现在getter、setter上。
setter
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
1 |
<div id="app"> |
运行结果:
1 |
菜鸟教程 http://www.runoob.com |
监听属性-watch
通过 watch 来响应数据的变化。
1 |
//在变量kilometers发生改变后调用 |
监听路由变化
当路由变化后(例如切换到其他页面后又切换回来),再次执行(调用)某个方法。
应用场景:使用keep-alive标签包裹的router-view,在切换路由后会保持页面状态,但我们想在切换路由后更新局部数据时可以使用路由监听。
1 |
watch:{ |
搜索
使用监听属性-watch,实现本地搜索功能。
- 输入框,双向数据绑定mysearch
- 数组tableData,保存全部数据
- 数组showTableData,保存要展示出来的数据
- 监听到变量mysearch变化之后,将与数组tableData中数据匹配的项返回(函数filter),保存在数组showTableData。
- 注意:数字或对象可以使用
JSON.stringify()
转换成字符串再进行比对。例如:JSON.stringify(data.goodsList).toLowerCase().inclXXX
- 注意:数字或对象可以使用
1 |
//输入框 |
样式绑定
Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。(菜鸟教程)
对象
我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:(对象中可以有多个属性)
1 |
<div v-bind:class="{ 'active': isActive }"></div>/*isActive的值为true,则应用的类名就等于属性active*/ |
计算属性computed
我们可以在这里绑定返回对象的计算属性(computed)。这是一个常用且强大的模式(将对象放到vue构造器中的计算属性computed中):
1 |
<div id="app"> |
数组语法
我们可以把一个数组传给 v-bind:class ,实例如下:
1 |
<div v-bind:class="[activeClass, errorClass]"></div> |
三元表达式
三元表达式来切换列表中的 class :isActive 为 true 时添加 activeClass 类:
1 |
<div v-bind:class="[ isActive ? activeClass : '']"></div> |
更多案例见菜鸟教程。
事件处理器
详细介绍,查看这篇博客
用法
事件监听可以使用 v-on 指令:(click,点击事件。更多事件类型,访问这里)
1 |
<div id="app"> |
事件修饰符
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。
Vue.js 通过由点 . 表示的指令后缀来调用修饰符。
.stop
- 阻止冒泡.prevent
- 阻止默认事件.capture
- 阻止捕获.self
- 只监听触发该元素的事件.once
- 只触发一次.left
- 左键事件.right
- 右键事件.middle
- 中间滚轮事件
1 |
<!-- 阻止单击事件冒泡 --> |
按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
1 |
<!-- 只有在 keyCode 是 13 时调用 vm.submit() --> |
记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:
1 |
<!-- 同上 --> |
全部的按键别名:
.enter
.tab
.delete
(捕获 “删除” 和 “退格” 键).esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
实例
1 |
<p><!-- Alt + C --> |
监听原生事件
1 |
//监听原生事件(添加.native后缀,即事件修饰符) |
扩展
click事件失效
vue的click事件失效。
在移动端,应该使用tap事件代替click事件。还可以使用@touchstart等事件。
组件component
组件一般由三部分组成,template、script、style。template中为html代码。
1 |
<!-- 组件一般由三部分组成,template、script、style --> |
组件即可以作为一个单独的页面也可以作为页面的一部分(有点类似母板页)
作为组件
使用vue-cli构建的vue项目为单页面应用,App.vue就是项目打开的第一个页面。在APP.vue中添加的内容,除非是手动去掉否则会一直存在。
作为单独的页面
在其他组件中(例如app.vue)通过链接<router-link to="/pos">点我,去pos页</router-link>
访问(见“作为组件”中的图)。通过router-link加载相应的组件,会渲染在router-view标签的位置(替换)
Vue3.x可以将import语句写在component后边(第12行代码)。
使用vue-cli构建的vue项目为单页面应用,App.vue就是项目打开的第一个页面:
点击router-link链接后,显示pos组件的内容:
案例
下拉刷新组件
使用vue实现的一个下拉刷新组件:https://blog.csdn.net/qq_34439125/article/details/85602508
应用的项目:我的Gitee仓库
1 |
//使用上边的组件报错(浏览器警告。与touch事件有关),可以添加下边的样式: |
表单
在表单上应用 v-model , v-model 指令在表单控件元素上创建双向数据绑定。详情见菜鸟教程。
v-model的使用
演示 input 和 textarea 元素中使用 v-model 实现双向数据绑定:
1 |
<div id="app"> |
修饰符
.lazy
在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:
1 |
<!-- 在 "change" 而不是 "input" 事件中更新 --> |
(失去焦点时才更新数据)
.number
如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值
.trim
如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入
操作DOM
认识vm.$refs
在VUE中操作DOM,可以使用document.querySelector(“#id名”)来获取DOM节点,也可以使用VUE提供的vm.$refs来获取DOM节点。
VUE官方文档中关于vm.$refs的介绍:一个对象,持有注册过 ref 属性 的所有 DOM 元素和组件实例。(参考:子组件 ref、特殊 attribute - ref)
什么是ref属性
在使用vm.$refs之前,我们需要先了解一下ref 属性。ref属性接收一个string类型的值,用来给元素或子组件注册引用信息。引用信息将会注册在父组件的
$refs
对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
我的理解:在使用document.querySelector(“#id名”)来获取DOM节点之前需要给元素添加一个id,同理在使用vm.$refs来获取DOM节点之前需要给元素添加一个ref,有点类似于给元素添加一个标识。
使用ref注意点:
当
v-for
用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。(即不是通过vm.$refs.ref名来获取DOM节点,而是通过vm.$refs.ref名[数组索引])关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!
$refs
也不是响应式的,因此你不应该试图用它在模板中做数据绑定。- 我的理解:在页面渲染之后vue才会去注册ref,在此之前不能访问到它们。在访问它们时要确保ref已注册,可以使用$nextTick来确保ref在注册后再访问。
1
2
3
4
5
6
7
8
9//$nextTick:在下次 DOM 更新循环结束之后执行延迟回调
Vue.$nextTick(() => {
Vue.$refs.myform.resetFields();
//清空form表单的数据(form表单中注册了ref="myform")
})
//下边两种写法是完全相等的:
this.$refs.myform
this.$refs['myform']
案例
通过给form表单添加ref属性,在弹出表单之前将表单中的数据清空(使用el-form表单的resetFields()方法)。
本案例中所使用的页面元素为ElementUI中的el-form。
el-form标签中,添加ref属性。(给页面form表单元素注册引用信息)
注意:若
el-form
放在v-for
中,就不是通过this.$refs.ref名来获取DOM节点,而是通过this.$refs.ref名[数组索引],详情见上边的“ref注意点”。要使用resetFields()清空表单,
el-form-item标签
中要添加prop属性。(尽量与form表单绑定的form对象中的属性名相同)1
2
3
4
5
6<el-form :model="form" ref="form">
<el-form-item prop="mat_name" label="物资名称">
<el-input v-model="form.mat_name"></el-input>
</el-form-item>
...
</el-form>
清空form表单的数据。通过
this.$refs.ref名
或this.$refs['ref名']
获取到DOM元素。1
2
3
4//在触发弹窗的按钮事件中添加如下代码:
this.$nextTick(() => {
this.$refs.form.resetFields(); //清空form表单的数据
})
小技巧
视图更新
问题:数据更新但是视图没有更新。常见于数据是数组或json对象。
解决方法:
调用vue的
set()
函数更新数据1
vue.$set( target, propertyName/index, value )
使用watch深度监听json对象的属性
v-for,遍历的视图,可尝试更改key值触发视图更新
调用vue的
forceUpdate()
函数,强制更新最笨的方法,使用v-if销毁再重建
路径
在cli项目中@指向src目录。
1 |
// 绝对路径,@指向项目根目录,在cli项目中@指向src目录 |
this关键字
vue回调函数中无法使用this访问vue中数据(data)或方法(methods)的问题:
解决方法一:先用一个变量将this保存在回调函数外边,在回调函数内使用该变量调用vue中的数据
解决方法二:使用箭头函数。this还是指向vue实例。更多笔记,访问MDN web文档。
1
2
3
4
5
6
7
8
9
10
11
12
13
14(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
//相当于:(param1, param2, …, paramN) =>{ return expression; }
// 当只有一个参数时,圆括号是可选的:
(singleParam) => { statements }
singleParam => { statements }
// 没有参数的函数应该写成一对圆括号。
() => { statements }
//动态获取/设置vue中定义的变量值(field_name,函数传递过来的变量名)
this.$data[field_name] = '';
定义全局变量
思路有两个:
- 挂载到原形上
- 例如:在main.js文件中添加
Vue.prototype.$http = axios
($符合,是变量名称的一部分。仅仅起到区分全局变量、局部变量的作用。变量可以是普通字符串、json对象等)
- 例如:在main.js文件中添加
- 单独写在一个配置文件中。可参考这篇博客。
- 使用vuex。
项目样式相关
设置项目的标题、图标、全局样式等。
vue-cli(vue2.x版本)创建的项目,在根目录下有一个index.html文件,要设置标题只需要修改其中的title即可,其他属性也是如此。还可以在该文件中设置一些全局样式,或者新建一个css文件专门设置全局样式。关于全局样式文件的配置可以查看ElementUI笔记中的样式部分。
vue2.x版本中添加全局样式表:
1 |
//在main.js中,导入全局样式表 |
浏览器调试
使用vue-cli开发项目时,要想在浏览器控制台调试data中的某个变量,需要在钩子函数created中添加如下代码:
1 |
created() { |
使用方法,在浏览器控制台中,输入vue
即可获取绑定的this实例,vue.$data.变量名
可获取某一变量的值。
安装浏览器插件
在chrome安装vue 开发插件。
使用佛跳墙科学上网,打开Chrome插件商店搜索vue
devtools
安装即可。重新打开开发者工具(快捷键f12或ctrl+fhift+i)即可在开发者工具的菜单栏中看到vue选项卡。
传递参数
方式一:
页面跳转,将要传递的参数拼接在url后边。?后边跟参数(baidu.com?key=value),参数之间&隔开(key=value&key2=value2)
新打开的页面中获取传递的参数,方法如下:
1 |
//获取地址栏中的参数(?key=value) |
扩展:使用vue-router传递参数。
1 |
this.$router.push({ |
方式二:
保存在localStore、sessionStore中,使用setItem、getItem、removeItem等函数保存、获取、移除。
注意:保存json对象,需要使用JSON.stringify(json对象)
转换为字符串,获取时再使用JSON.parse()
函数转换为json对象。
方式三:
定义全局变量,见上边笔记。
搜索框
监听输入框的输入事件,当有输入事件发生时调用searchInput函数。使用变量search绑定输入框中输入的数据(双向数据绑定)
1 |
@input="searchInput" |
匹配字段newstitle或newsauthor
1 |
searchInput(){ |
导入js文件
创建一个js文件(本案例是在与vue文件同级的地方),保存数据。
1 |
//导出一个变量mydata |
在vue文件中使用import导入js文件。
1 |
import { mydata } from "./data.js";//"./"表示当前目录,“../”表示上级目录 |
导入本地图片
注意:图片等静态资源(js、css等文件还是建议放在src的assets下,使用import导入),建议放在static目录下(与src同级),使用时用路径“./static/。。。”就无需使用import、require()了。
1 |
//img标签中使用相对路径可以正常引用 src/assets 下的图片 |
更多笔记,见web小技巧