前言
【目的】
【学习资源】
- 【学习视频】
- 【参考笔记】
- 【视频中出现的代码】
【==温馨提示==】
初识Vue
Vue官网使用指南
官网地址
如何合理使用导航栏?
如何搭建Vue开发环境?
1、 下载一个开发版本的Vue
-
官网开发版下载地址——【==注意==】选择开发版本
-
【拓展】开发版与生产版的区别
开发版 生产版 区别 包含完整的警告和调试模式 删除了警告 选择 开发的时候,最好用这个。出错了有提示 x项目写完了,要上线了,为了让vue.js体积更小
-
-
引入vue.js
- 在项目中新建文件夹命名为“JS”
- 将下载的
Vue.js
文件拖入JS文件夹中 - 在想要调用vue的html文件的< head>标签内引入Vue
【示例】
<script type="text/javascript" src="../js/vue.js"></script>
【==注意==】src路径为vue.js的相对路径
-
此时出现两个警告(先忽略,下一步解决)
-
【警告一】建议下载Vue开发者工具,达到一个更好的开发体验。
-
【警告二】你正在运行一个开发者版本的vue,请你确定你在生产环境下不要这样做(简单来说,就是vue引入的内容用点大,用此上线不太好)
-
-
验证是否引入成功(在控制台输入
Vue
)-
成功
-
失败
-
2、按照Vue开发者调试工具(处理警告一)
Vue开发者工具扩展链接: 【下载开发者工具】: https://pan.baidu.com/s/1MtYvMPew4lb14piIrs9x6w 提取码:6666
- 具体安装方式视频已经十分详细,请小伙伴们移步到尚硅谷Vue技术_搭建Vue开发环境
【==注意==】直接拖入,还未消除警告的情况
-
点击详情
-
打开此项
3、关闭提示(处理警告二)
-
在html文件
< body>
标签内写入脚本<script type="text/javascript">
Vue.config.productionTip=false;//阻止 vue 在启动时生成生产提示。
</script>
【拓展】Vue的全局配置
-
什么是全局配置?
- 一处修改,到处可用
-
先了解
productionTip
如何让Vue工作?
1、准备好一个容器
<div id="root">
<h1>Hello,{{name}}}</h1>
</div>
容器
:- 容器里的代码依然符号html规范,只不过混入了一些特殊的Vue语法
- 容器里的代码被称为【Vue模板】
- 作用:
- 为Vue提供模板
- 把Vue解析后的成果,告诉Vue往哪放。
- 作用:
{{xxx}}
:- 中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性
【拓展】Vue模板解析流程
- 先有容器,然后在有Vue实例
- 当Vue实例开始工作后
- 读取
el
对应的容器- 开始对容器进行解析,解析容器中有没有一些特殊的Vue语法
- 解析之后,判断Vue实例中是否有容器所需的属性。
- Vue实例中有容器所需要的属性,
- 则将Vue实例中的属性值传给容器设置Vue语法的地方
- 将容器中原有的Vue语法部分替换成Vue实例中的值,生成一个新的容器
- 将解析完的容器替换掉原有的整个容器
【拓展】js表达式 和 js代码(语句)的区分
表达式:一个表达式会产生一个值,可以放在任何已需要值的地方
【示例】
(1).a
(2).a+b
(3).demo(1)
(4).x === y? 'a' : 'b'
js代码(语句)
【示例】
(1)if()
(2)for()
2、必须创建一个Vue实例
- 想让Vue工作,就必须创建 一个Vue实例,且要传入一个配置对象
- ==Vue实例与容器是一一对应的==
- 真实开发中只有一个Vue实例,并且会配合着组件一起使用
创建Vue实例
<script type="text/javascript">
Vue.config.productionTip=false;
//创建Vue实例模板
new Vue({
el:"#root",
data:{
name:'lao'
}
})
</script>
el
:用于指定当前Vue实例为哪个容器服务- 值:通常为css选择器字符串
data
:用于存储数据,数据共el所指定的容器去使用- 一旦data中的数据发生变化,那么模板中用到该数据的地方也会自动更新
Vue核心
模板语法
插值语法
【功能】
- 用于解析标签体内容
【格式】
<标签>this is a {{js表达式}}</标签>
{{xxx}}
:xxx是js表达式
- 且可以直接读取到data中的所有区域
【==注意==】
-
若遇到多处使用Vue语法的地方可以设置为多个层级
【示例】
<div id="root">
<h3>你好,{{name}}</h3>
<a v-bind:href="auther.url.toUpperCase()">点我去{{auther.name}}学习</a>
</div>
<script type="text/javascript">
Vue.config.productionTip=false;
new Vue({
el:'#root',
data:{
name:'Vue初学者',
//设置为多个层级
auther:{
name:"lao-jiawei的博客",
url:'https://www.cnblogs.com/lao-jiaweijarvee/'
}
}
})
</script>
指令语法
【功能】
- 用于解析标签(包括:标签属性、标签体内容、绑定事件…)
【格式示例】用Vue的指令语法,来修改a
标签的href
值
<a v-bind:href="xxx"></a>
<!--"v-bind:" 可简写为-->
<a :href="xxx">
xxx
:同样要写js表达式
- 且可以直接读取到data中的所有属性
【==注意==】
- Vue中有很多的指令,且形式都是
v-???
,此处我们只是拿v-bind
举个例子 - 不是所有指令都可以简写为
:
数据绑定
单项绑定(v-bind
)
-
数据只能从data流向页面(如图橙色线)
双向绑定(v-model
)
-
数据不仅能从data流向页面(如图红色线),还可以从页面流向data(如图粉色线)
【解释】橙色线
- 由与单向数据表单值绑定的值也是data中的name值,所以
v-model
改变了data中的name,name值改变了单向表单值也改变了。
- 由与单向数据表单值绑定的值也是data中的name值,所以
-
一般都应用在表单类元素上(如:
<input>
、<select>
、<textarea>
等)
【格式示例】v-model
双向绑定表单数据
双向数据绑定:<input type="text" v-model:value="name">
<!--"v-model:value"可简写为"v-model",因为"v-model"默认收集的就是value值-->
双向数据绑定:<input type="text" v-model="name">
el与data的两种写法
el的两种写法
写法一:创建Vue实例对象的时候配置el属性
【示例】
<div id="root">
<h1>Hello,{{name}}!</h1>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el:'#root',
data:{
name:'Vue初学者'
}
})
</script>
写法二:先创建Vue实例,随后再通过
vm.$mount('#root')
指定el的值
- 更灵活
【示例】
<div id="root">
<h1>Hello,{{name}}!</h1>
</div>
<script>
Vue.config.productionTip = false;
const vm=new Vue({
data:{
name:'Vue初学者'
}
})
vm.$mount('#root');
</script>
data的两种写法
写法一:对象式
【示例】
new Vue({
el:'#root',
data:{
name:'Vue初学者'
}
})
写法二:函数式
- 使用组件时,data必须使用函数式,否则会报错
【示例】
new Vue({
el:'#root',
data:function(){
return{
name:'Vue初学者'
}
}
//可简写成
data(){
return{
name:'Vue初学者'
}
}
})
【==注意==】
-
由Vue管理的函数,一定不能写成箭头函数,否则this就不再是Vue实例了
【data使用普通函数】此处的this是Vue实例对象
【data使用箭头函数】this指向全局的
window
- 【解释】this没有自己的函数,就往外找,往外找就找到全局的
window
- 【解释】this没有自己的函数,就往外找,往外找就找到全局的
MVVM模型
【MVVM模型与代码的关系对应图】
M:模型(Model),data中的数据
V:视图(View),模板代码
VM:视图模型(ViewModel),Vue实例
-
在文档中经常会使用
vm
(ViewModel 的缩写) 这个变量名表示 Vue 实例。//所以以后接收Vue实例用vm接收
const vm = new Vue({
}) -
data中所有的属性,最后都出现在了vm身上
【示例】
const vm=new Vue({
el:'#root',
data:{
name:'Vue初学者',
address:'Shenzhen',
a:'1'
}
}) -
vm身上所有的属性 及 Vue原型身上所有的属性,在Vue模板中都可以直接使用
数据代理
回顾Object.defineProperty方法
【格式】
Object.defineProperty(obj,prop,{
//descriptor
})
obj
:要定义属性的对象
prop
:要定义或修改的属性的名称或 Symbol
descriptor
:要定义或修改的属性描述符。
-
描述符
-
value
:设置属性值 -
enumberable
:控制属性是否可以枚举- false:默认值,不可枚举
- true:可以被枚举。
-
writable
:控制属性是否可以被修改- false:默认值,不可被修改
- true:可以被修改。
-
configurable
:控制属性是否可以被删除- false:默认值,不可被删除
- true:可以被删除。
-
get()
:当有人读取obj
对象的prop
属性时,get函数(getter)就会被调用,且返回值就是prop
的值*(现用现取)*-
【示例格式】
<script type="text/javascript">
let number = 18;
let person = {
name:'lao',
sex:'男',
}
Object.defineProperty(person,'age',{
get(){
console.log('有人读取age属性了')
return number;
}
})
</script>
-
-
set()
:当有人修改obj
对象的prop
属性时,et函数(setter)就会被调用,且会收到具体值-
【示例格式】以上述例子追加
set(value){
console.log('有人修该了age属性,且值是',value)
number=value
}
-
-
**返回值:**被传递给函数的对象
使用Object.defineProperty方法添加属性和属性值 与 直接在对象体内添加的区别
使用Object.defineProperty方法 | 直接在对象体内添加 | |
---|---|---|
枚举性(遍历) | 默认不可枚举 | 可枚举 |
修改性 | 默认不可修改 | 可修改 |
删除性 | 默认不可被删除 | 可以被删除 |
什么是数据代理?
-
通过 一个对象代理对另一个对象中的属性的操作(读/写)
【示例】以上图为例
let obj={x:100}
let obj2={y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj.x;
},
set(value){
obj.x=value
}
})
Vue中的数据代理
-
Vue中的数据代理通过vm对象来代理data对象中属性的操作(读/写)
【验证一】红线:vm的
name
到底读的是不是data.name
-
修改data中的
name
属性值 -
vm,name
也随之改变
【验证二】蓝线:如何实现修改
name
通过setter修改到data.name
-
直接在控制台修改
vm.name
-
浏览器显示也随之修改
-
【说明】
vm.name
===_data.name
== =data.name
-
-
【好处】更加方便的操作data
中的数据
基本原理:
- 通过
object.defineProperty()
把data
对象中所有属性添加到vm
上。 - 为每一个添加到
vm
上的属性,都指定一个getter/setter
。 - 在
getter/setter
内部去操作(读/写)data
中对应的属性。
事件处理
事件的基本使用
-
使用
v-on:xxx
或@xxx
绑定事件,其中xxx
是事件名【示例】使用
v-on:click
或@click
绑定点击事件<div id="root">
<h2>hello,{{name}}</h2>
<button v-on:click="showInfo1">点我提示信息1</button>
<!--或简写为-->
<button @click="showInfo2">点我提示信息2</button>
</div> -
事件的回调需要配置在methods对象中,最终会在
vm
上【示例】
const vm = new Vue({
el:'#root',
data:{
name:'Vue初学者'
},
methods:{
showInfo1(event){
alert("同学你好!");
},
showInfo2(evnet){
alert("同学你好!!");
}
}
})
console.log(vm)【留意下图最后两行】说明事件的回调,最终会在
vm
上 -
methods中配置的函数,**不要用箭 头函数!**否则this就不是vm了
【使用常用函数】this是
vm
methods:{
showInfo1(event){
console.log(this === vm)
}
}【使用箭头函数】this是
window
methods:{
showInfo1:(event)=>{
console.log(this)
}
} -
methods中配置的函数,都是被Vue所管理的函数,this的指向是
vm
或组件实例对象 -
@click="demo
和@click="demo($event)"
效果一致,但后者可以传参【示例】
<div id="root">
<h2>hello,{{name}}</h2>
<button v-on:click="showInfo1">点我提示信息(不传参)</button>
<button @click="showInfo2(66,$event)">点我提示信息2(传参)</button>
</div>
<script>
Vue.config.productionTip = false
const vm=new Vue({
el:'#root',
data:{
name:'Vue初学者'
},
methods:{
showInfo1(event){
alert("同学你好!")
},
showInfo2(number,event){
console.log(number,event)
}
}
})
</script>【触发
showInfo2
方法得到的结果】
Vue中的事件修饰符
prevent:阻止默认事件(常用)
【示例】阻止a
标签的默认跳转行为。
<div id="root">
<h2>Hello,{{name}}!!</h2>
<a href="https://www.cnblogs.com/lao-jiaweijarvee/" @click="showInfo">不阻止默认跳转</a>
<br/>
<a href="https://www.cnblogs.com/lao-jiaweijarvee/" @click.prevent="showInfo">已使用prevent阻止默认跳转</a>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'Vue初学者'
},
methods:{
showInfo(e){
alert('同学你好!')
}
}
})
</script>
【效果】
- 点击第一个链接,跳出弹窗,点击确认后,执行默认事件,跳转至相关页面。
- 点击第二个链接,跳出弹窗,点击确认后,不执行默认事件,没有跳转至相关页面
stop:阻止事件冒泡(常用)
【示例】
- 【==注意==】该示例无法直接复制粘贴运行,需要读者自行调整
<!--Css样式-->
<style>
*{
margin-top: 20px;
}
.demo1{
height: 50px;
background-color: skyblue;
}
</style>
<!--body内容-->
<body>
<div id="root">
<h2>Hello,{{name}}!!</h2>
<div class="demo1" @click="showInfo">
<button @click="showInfo">没添加stop效果</button>
<button @click.stop="showInfo">已使用stop阻止事件冒泡</button>
</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'Vue初学者'
},
methods:{
showInfo(e){
alert('同学你好!')
}
}
})
</script>
</body>
【效果】
- 单击盒子,弹出一次弹窗
- 【原因】在
div
上,绑定了点击事件
- 【原因】在
- 单击第一个按键,弹出两次弹窗
- 【原因】点击的是按钮,但是最后冒泡冒到
div
上,又触发了事件。
- 【原因】点击的是按钮,但是最后冒泡冒到
- 单击第二个按键,弹出一次弹出
- 【原因】在第二个按钮
@click
后加了stop
,阻止了事件冒泡到div
上
- 【原因】在第二个按钮
【拓展】 修饰符可以连续写
-
【示例】
<a @click.prevent.stop="showInfo">已使用stop阻止事件冒泡</a>
once:事件只触发一次(常用)
【示例】
<div id="root">
<h2>Hello,{{name}}!!</h2>
<button @click="showInfo">无添加任何效果</button>
<button @click.once="showInfo">使用once事件只触发一次</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'Vue初学者'
},
methods:{
showInfo(e){
alert('同学你好!')
}
}
})
</script>
【效果】
- 点击第一个按钮,弹窗弹出,关闭弹窗再次点击,弹窗又会再次弹出。
- 点击第二个按钮,弹窗只弹出一次,关闭弹窗再次点击,弹窗不再弹出。
capture:使用事件的捕获模式
【示例】
<!--Css样式-->
<style>
*{
margin-top: 20px;
}
.box1{
padding: 5px;
background-color: skyblue;
}
.box2{
padding: 5px;
background-color: orange;
}
</style>
<!--body内容-->
<body>
<div id="root">
<h2>Hello,{{name}}!!</h2>
<h3>未使用</h3>
<div class="box1" @click="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<br/>
<h3>已使用capture事件捕获模式</h3>
<div class="box1" @click.capture="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'Vue初学者'
},
methods:{
showMsg(msg){
console.log(msg)
}
}
})
</script>
</body>
【效果】
-
未使用效果
-
点击
div1
: -
点击
div2
:【原因】先捕获*(蓝线)再冒泡(红线)*,默认情况下,冒泡阶段后再处理事件
-
-
使用效果
-
点击
div1
: -
点击
div2
:【原因】先捕获 再冒泡,
div1
中添加了capture
所以在捕获阶段就开始处理事件,再冒泡
-
self:只有
event.target
是当前操作的元素时才触发事件
<!--Css内容-->
<style>
*{
margin-top: 20px;
}
.demo1{
height: 50px;
background-color: skyblue;
}
</style>
<!--body内容-->
<body>
<div id="root">
<h2>Hello,{{name}}!!</h2>
<h3>未使用</h3>
<div class="demo1" @click="showInfo">
<button @click="showInfo">点我提示信息</button>
</div>
<h3>使用self</h3>
<div class="demo1" @click.self="showInfo">
<button @click="showInfo">点我提示信息</button>
</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'Vue初学者'
},
methods:{
showInfo(e){
// alert('同学你好!')
console.log(e.target);
}
}
})
</script>
</body>
【效果】
-
使用self的效果
【说明】无论冒泡到哪去,
event.target
始终是button
,不可能冒泡到div
中 -
对
div
使用self使用的效果【说明】因为
event.target
不是div
是button
,所以没有触发事件。
passive:事件的默认行为立即执行,无需等待事件回调执行完毕