Vue 第一章
一、Vue的初体验
1.引入Vue的js文件的方式
- 通过CND加速服务器的方式来引入
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
- 通过NPM的方式来导入
import i Vue
3. 下载源码或者压缩版本
开发环境 https://vuejs.org/js/vue.js
生产环境 https://vuejs.org/is/vue.min.js
2.初次的页面搭建
编程范式:声明式编程 【注】
区分:命令式编程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HelloVue</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="el">
{{msg}}
</div>
</body>
<script>
const app = new Vue({
el: '#el',
data() {
return {
msg: '爱是本次'
}
},
});
</script>
</html>
3.Vue的列表展示
- Vue有v-for的内置标签来遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HelloVue</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="el">
<ul>
<li v-for="(item, index) in list" :key="index">
{{item}}
</li>
</ul>
</div>
</body>
<script>
const app = new Vue({
el: '#el', //用于挂载要管理的元素
data() {
return {
list: ['李玉森', '吴志伟', '卢梦君', '魏耀']
}
},
});
</script>
</html>
4.计数器的简单案例
- 通过@click指令创建点击事件,在methods方法体中定义具体的方法实现的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计数器</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
{{count}}
</br>
<button @click="add">+</button>
<button @click="del">-</button>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
count: 0
}
},
methods: {
add: function() {
this.count++;
},
del: function() {
this.count--;
}
},
});
</script>
</html>
二、Vue中的MVVM
1.什么是MVVM呢?
- 通常我们学习-一个概念,最好的方式是去看维基百科(对,千万别看成了百度百科)https://zh.wikipedia.org/wiki/MVVM维基百科的官方解释,我们这里不再赘述。
2.Vue的MVVM
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pcCB46qd-1604748866167)(F:\vue的终极总结\第一章\Fimage-20201105184515629.png)]
3. Vue实例中的options
const vm = new Vue(options)
在这里把Vue的实列命名为vm,这是尤雨溪的习惯,我们沿用vm对象封装了对视图的所有操作,包括数据读写、事件绑定、DOM更新,vm的构造函数是Vue,按照ES6的说法,vm所属的类是Vue。
options是 new Vue 的参数,我们一般称之为选项或者构造选项
那么options里面有什么呢?
options的五类属性:
**数据:**data、 props、 propsData、 computed、methods、 Watch
DOM: el、 template、 render、 renderError
生命周期钩子: beforeCreate、 created、beforeMount、 mounted、 beforeUpdate、 updated、activated、 deactivated、 beforeDestroy、 destroyed、errorCaptured
资源: directives、 filters、 components
组合: parent, mixins、 extends、 provide、 inject
主要讲讲入门属性
默认你引入了vue
el - 挂载点
只在用new
创建实例时生效
html
<div id="app">
</div>
js
new Vue({
el: '#app',
})
这样Vue就挂载到了#app上
可以用$mount() 来代替
js
new Vue().$mount('#app')
data - 内部数据
支持对象和函数,优先使用函数
var data = { a: 1 }
// 直接创建一个实例
var vm = new Vue({
data: data
})
vm.a // => 1
vm.$data === data // => true
// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
data: function () {
return { a: 1 }
}
})
methods - 方法
事件处理函数或者是普通函数
var vm = new Vue({
data: { a: 1 },
methods: {
plus: function () {
this.a++
}
}
})
vm.plus()
vm.a // 2
components
Vue的组件要注意大小写
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是``。我们可以在一个通过new Vue
创建的 Vue 根实例中,把这个组件作为自定义元素来使用
<div id="components-demo">
<button-counter></button-counter>
</div>
new Vue({ el: '#components-demo' })
因为组件是可复用的 Vue 实例,所以它们与new Vue
接收相同的选项,例如data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像el
这样根实例特有的选项。
props - 外部数据
也叫属性
HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
重申一次,如果你使用字符串模板,那么这个限制就不存在了。
当然你也可以传入数据和函数
只需要在 post-title 前面加 : 或者 v-bind 就能传入 this.n 的数据 同理 也能传入this.add函数
三、Vue的生命周期
四、模板语法
1.插值表达式
-
如何将data中的数据,插入到Html中去
- 前面我们已经掌握了通过Mustache语法即双大括号的方法
- MUstache:胡子
-
我们可以向下面的方式来使用,数据的响应(数据是响应式的)
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">
</scrip>
<body>
<div id="el">
{{msg}}
</div>
</body>
<script>
const app = new Vue({
el: '#el', //用于挂载要管理的元素
data() {
return {
msg: '你好,Vue',
}
},
});
还可以用
v-text
指令达到相同的结果,但一般不用,因为他不够灵活!!!
2.v-once指令
- 只改变一次,不会随着页面内容的改变而改变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
<h1>{{msg}}</h1>
<h1 v-once>{{msg}}</h1>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
msg: '你好啊'
}
},
});
</script>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odEkQRxs-1604748866171)(F:\vue的终极总结\image-20201105193234996.png)]
3.v-html指令
- 当服务器给我们传过来的是html标签的,我们需要用该指令来解析数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
<h1>{{url}}</h1>
<h1 v-html="url"></h1>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
url: '<a href="https://www.baidu.com">百度一下</a>'
}
},
});
</script>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zXKVCEor-1604748866174)(F:\vue的终极总结\image-20201105193817440.png)]
4.v-pre指令
- 把标签内的东西原封不动的显示出来,不做任何处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
<h1>{{msg}}</h1>
<h2 v-pre>{{msg}}</h2>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
msg: '你好!!'
}
},
});
</script>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UqcfABN2-1604748866176)(F:\vue的终极总结\image-20201105194343334.png)]
5.v-cloak指令
- 当在实际运行的过程中我们可能会遇到延迟加载的情况,会出现如{{msg}}等不友好的界面效果,而这要避开这个效果就需要该指令,当延迟加载的时候会将它隐藏,当数据渲染完毕的时候才加载界面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="vue">
<h4>{{msg}}</h4>
<h4 v-cloak>{{msg}}</h4>
</div>
</body>
<script>
setTimeout(function() {
const app = new Vue({
el: '#vue',
data() {
return {
msg: '你好!!'
}
},
});
}, 2000);
</script>
</html>
6.v-if指令
- 使用 v-if 指令可以判断是否渲染指定的区域,不渲染会变成一行注释;
<div v-if="flag">v-if指令</div>
<script>
const dataObj={
flag:true
}
</script>
- 条件判断支持 v-else 指令,渲染 v-if 的另一区域;
<div v-if="flag">显示</div>
<div v-else>隐藏</div>
- 2.1.0 版本新增了 v-else-if,强化了条件判断;
<div v-if="num > 90">优秀</div>
<div v-else-if="num > 60">良好</div>
<div v-else>不及格</div>
ps:不管是 v-else 还是 v-else-if,必须跟在 v-if 后面,否则会异常;
- 使用存放多个元素做渲染分组,Vue 采用复用高效渲染方法;
<template v-if="flag">
<label for="reg">注册</label>
<input type="text" id="reg">
</template>
<template v-else>
<label for="login">登陆</label>
<input type="text" id="login">
</template>
<button type="button" @click="toggleIf">点我哦~</button>
-
这种渲染方法不会重头渲染,会复用相同的部分,只更改不同的部分;
-
另一种隐藏和显示的指令是 v-show,这种指令单纯的 display:none 或无;
<div v-show="flag">好好学习 天天向上</div>
- v-show 不支持和 v-else;
7. v-show指令
和v-if的用户相同,如果变换比较频繁的话,建议通过v-show的方法来转换
8.v-if和v-show的区别
- v-if当条件为false时,压根不会有对应的元素在DOM中。
- v-show当条件为false时,仅仅是将元素的display属性设置为none而已。
9.v-for指令
- 可以循环数组,也可以循环对象,是比较人性化的操作【注】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HelloVue</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="el">
<h5>循环组数</h5>
<ul>
<li v-for="(item, index) in list" :key="index">
{{item}}
</li>
</ul>
<h5>循环对象</h5>
<ul>
<li v-for="(key,value) in info" :key="index">
{{key}} ------->{{value}}
</li>
</ul>
</div>
</body>
<script>
const app = new Vue({
el: '#el', //用于挂载要管理的元素
data() {
return {
list: ['李玉森', '吴志伟', '卢梦君', '魏耀'],
info: {
id: 1,
name: '小木木',
age: 18,
sex: 'man'
}
}
},
});
</script>
</html>
10.v-model 指令
- 双向绑定,通常在表单的提交等方向上比较常用
- 配合过滤器的使用方法…
- 还可以通过值绑定的方式来实现更加方便的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
</style>
</head>
<body>
<div id="vue">
<!-- 双向绑定 -->
<span>
用户名:
<input type="text" v-model="msg">
</span>
<br>
<span>
邮箱1:
<input type="email" :value="msg+'@qq.com'">
</span>
<br>
<span>
邮箱2:
<input type="email" :value="msg|newmsg">
</span>
<h4>{{msg}}</h4>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
msg: '',
}
},
methods: {
},
filters: {
newmsg: function(msg) {
return msg + '@qq.com'
}
}
});
</script>
</html>
- 单选框案例
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree" > 同意协议<a href="#">《王者荣耀运行协议》</a>
</label>
<p>{{isAgree}}</p>
data() {
return {
msg: '',
isAgree: false
}
},
- 多选框案例
<input type="checkbox" value="李玉森" id="" v-model="hobbis" /> 李玉森
<input type="checkbox" value="撸梦君" id="" v-model="hobbis" /> 撸梦君
<input type="checkbox" value="吴志伟" id="" v-model="hobbis" />吴志伟
<input type="checkbox" value="魏耀" id="" v-model="hobbis" />魏耀
<input type="checkbox" value="微光海洋" id="" v-model="hobbis" />微光海洋
<p>你的室友是:{{hobbis}}</p>
data() {
return {
msg: '',
isAgree: false,
hobbis: []
}
},
- 复选框
<select name=" abc" v-model="fruit">
<option value="苹 果" >苹果</option>
<option value="香蕉" >香蕉</option>
<option value= "榴莲">榴莲</option>
<option value="葡 萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruit}} </h2>
10.1、v-model 的修饰符【重】
- 修饰符
.lazy
<!--1.修饰符: lazy-->
<input type="text" V- model.lazy=" message">
<h2>{ { message}}</h2>
在光标离开之后才绑定到具体的变量中,减少频繁调用的次数
- 修饰符:number
<input type= ”number" v-model="age"/>
<h2>{{typeof(age)}}</h2> //注意:类型是String
//可以是这样
<input type= ”number" v-model.number="age"/>
<h2>{{typeof(age)}}</h2>
该输入框有只能输入数字了
- 修饰符:trim
<!--3.修饰符: trim-->
<input type= ”text" v-model.trim="name">
<h2>{ {name}}</h2>
去除两边的空格
五、属性绑定
1.v-bind指令
- 在属性里动态的绑定,可以做到动态的刷新。缩写是: 例如
:src
- 在动态绑定class属性时常常用到
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
<h4>{{msg}}</h4>
<img :src="image" alt="">
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
msg: '你好!!',
image: 'https://v3.vuejs.org/logo.png'
}
},
});
</script>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VFXcFx9W-1604748866178)(F:\vue的终极总结\image-20201105200325027.png)]
1.1显示隐藏的案例【附加】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.del {
display: none;
}
</style>
</head>
<body>
<div id="vue">
<h4>{{msg}}</h4>
<img :class="{del:zhen}" :src="image" alt="" width="100" height="100">
<!--动态绑定样式-->
<button :style="{fontSize:'50px'}" @click="zheng()">显示隐藏</button>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
msg: '你好!!',
image: 'https://v3.vuejs.org/logo.png',
zhen: true
}
},
methods: {
zheng: function() {
this.zhen = !this.zhen;
}
},
});
</script>
</html>
六、计算属性
1.computed属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.del {
display: none;
}
</style>
</head>
<body>
<div id="vue">
<p>{{msg + a}}</p>
<p>{{msg}} {{a}}</p>
<p>{{NewFullName}}</p>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
msg: '你好!!',
a: '小明'
}
},
methods: {
},
computed: {
NewFullName: function() {
return this.msg + this.a;
}
},
});
</script>
</html>
2.计算价格的案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
<table>
<tbody>
<th>
<td>编号</td>
<td>书名</td>
<td>价格</td>
</th>
</tbody>
<th v-for="(item, index) in books" :key="index">
{{item.id}} {{item.bookName}} {{item.price}}
</th>
</table>
总价格:{{NewFullName}}
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
books: [{
id: 1,
bookName: 'JavaScript红宝书',
price: 100
}, {
id: 2,
bookName: 'JavaScript红宝书',
price: 100
}, {
id: 3,
bookName: 'JavaScript红宝书',
price: 100
}, {
id: 4,
bookName: 'JavaScript红宝书',
price: 100
}, ]
}
},
methods: {
},
computed: {
NewFullName: function() {
let res = 0
for (let book of this.books) {
res += book.price
}
return res
}
},
});
</script>
</html>
3.计算属性的Getter和Setter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
<h2>数据变化之前
<i>
指令on-once 可以限制视图的响应
</i>
</h2>
<p v-once>{{msg}}</p>
<p v-once>{{noSpace}}</p>
<h2>数据变化之后</h2>
<p>{{msg}}</p>
<p>{{noSpace}}</p>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
msg: '我 查看不成 才能撒'
}
},
methods: {
},
computed: {
noSpace: {
set(value) {
console.log(value)
this.msg = value
},
get() {
return this.msg.replace(/\s/g, '');
}
}
},
});
</script>
</html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDnkILsX-1604748866180)(F:\vue的终极总结\image-20201105214651477.png)]
4.计算属性computed和方法methods的对比
- 通过直接拼接的方法,语法繁琐
- 通过Vue的methods的方法
- 通过Vue的computed的方法
我们一般都使用第三种方法来实现我们这类的功能,因为computed的方法有缓存的功能。
七、事件监听
1. 事件的绑定v-on指令
- 在实际的开发工作中也通常写他的缩写
@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计数器</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vue">
{{count}}
</br>
<button @click="add">+</button>
<button @click="del">-</button>
</div>
</body>
<script>
const app = new Vue({
el: '#vue',
data() {
return {
count: 0
}
},
methods: {
add: function() {
this.count++;
},
del: function() {
this.count--;
}
},
});
</script>
</html>
2.@click的传参问题
-
如果该方法不需要额外的参数,那么方法后的()可以不添加
- 但是注意:如果方法本身有一个参数,那么会默认将原生事件event参数传递进去
-
如果需要同时传递某个参数,同时需要event时,可以通过$event传入事件。
3.v-on的修饰符
- 在某些情况下,我们拿到event的目的可能是进行一些事件处理。
- Vue提供了修饰符来帮助我们方便的处理一些事件
- .stop -调用event.stopPropagation()。
- prevent -调用event.preventDefault)。
- {keyCode | keyAliqgs} -只当事件是从特定键触发时才触发回调
- native -监听组件根元素的原生事件。
- once -只触发一次回调。