引言
Vue是一个渐进式JavaScript框架
通过操作很少或者不操作的DOM元素,从而完成数据和试图的绑定,双向绑定mvvm
::mvvm进行双向绑定,vm同时监测view层和model层,一方数据改变,另一方也要进行数据改变,保证一致。
在使用Vue中不要尽量引用Jquery框架
入门
下载
从官网下载Vue.js官网描述
开发环境版本——————有警告,帮助之类的。
第一个入门应用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>flex布局</title>
</head>
<body>
<div id="app">
{{msg}}
<br>
<span>
{{username.sex}}
{{Lists[2]}}
{{users[1].name}}
</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app =new Vue({
el:"#app",
//element元素 用来给Vue实例定义一个作用范围,作用于界面的哪个元素,一般不会直接作用于body,而是用div,然后为div设置一个id
data:{ //用来给vue实例定义一些相关数据
msg:"你好,欢迎您!",
username:{name:"张三",sex:"男"}
Lists:["河南","北京","上海","天津"],
users:[{name:"one",age:"23"},{name:"two",age:"45"}]//数组调用
},
});
</script>
</body>
</html>
el:规定Vue的作用范围,推荐使用ID选择器,类选择器也可以
data:传递当数据,用{{}}渲染
在可以在{{}}中调用方法进行逻辑运算等
运行结果:
你好,欢迎您!
男 上海 two
ps:name.toUpperCase()------将内容大写
v-text
v-text用来获取data中数据将数据以文本的形式渲染到指定的标签内部,类似于JavaScript中的innerText
v-text 的取值会覆盖定义的标签内的取值,插值表达式不会覆盖标签原有的数据
如是的
结果会显示msg对应的内容,“是的”不显示
v-text可以避免在网络环境下出现插值闪烁,显示设置的源码
如当网络状态不好时
<span v-text="msg"></span>,是的
<span>{{msg}},是的</span>
开始显示为
您好,欢迎您,是的
{{msg}},是的
后来显示为
您好,欢迎您,是的
您好,欢迎您,是的
v-cloak
先通过样式隐藏内容,再内存中替换值,替换好之后在进行显示
指令用法:
[v-cloak]{
display:none;
}
data:{
msg:"lalla"
}
-------------
<div v-cloak>{{msg}}</div>
这种情况下不会出现闪动,网速达不到也不会出现{{msg}}
v-html
v-html:用来获取data中数据中含有的html标签先解析在渲染带指定的标签内部,类似以js里的innerHTML
本网站内部的数据可以使用,第三方数据不可使用
比如
<span v-html="msg"><a href="www.baidu.com">百度一下</a></span>
<span><a href="www.baidu.com">百度一下</a></span>
运行结果为
百度一下
<a href="www.baidu.com">百度一下</a>
v-pre
跳过编译过程,显示{{msg}}直接,不常用
Vue的事件绑定(v-on)
1、绑定事件语法界面总设置按钮
2、按钮绑定单击事件
3、再单击事件中实现功能修改,同时渲染界面
methods{ }//定义Vue中的的事件
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>v-on例子</title>
</head>
<body>
<div id="app">
<h1>{{msg}}</h1>
<h2 v-text="msg"></h2>
<h3>年龄:{{age}}</h3>
<input type="button" value="点我修改年龄" v-on:click="changeage">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script >
const app = new Vue({
el:"#app",
data:{
msg:"hi!",
age:23,
},
methods:{changeage:function(){
alert('点击触发');
this.age++;
}
}
})
</script>
</body>
</html>
this this this this this this this this别忘了
运行结果
略
事件:
事件源:发生时间dom元素
事件:发生的特定动作 click…
监听器:发生特定动作之后的时间处理程序,通常是js中函数
- 事件函数的调用方式
-<button v-on:click='say'>alal</button>
-----直接绑定函数名称
-<button v-on:click='say()'>alal<button>
------调用函数
Vue事件的使用
v-on:click{ }可以用@click代替写法,其他不变
1、v-on
2、
3、
~~ 事件函数的优化
方法名:function(){
方法体
}
同样于
方法名(){
方法体
}
Vue事件传递参数
@click=“changecount(23,‘小明’)”
methods{
changecount(count,name){
this.count=count;
alert(name);
}
}
事件触发时,直接在事件调用给出事件进行参数传递,在事件定义出通过定义对应变量接收传递的参数。
<button @click='save(12,13,$event)'>点击</button>
methods:{
save:function(p,p1,event){
console.log(p,p1)
console.log(event.target.innerHTML)
}
- ps:innerHTML获取事件内容
- 当事件直接绑定函数名时,默认传递事件对象为函数的第一个参数
- 当事件绑定函数调用,事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event.
v-show v-bind v-if
- v-show用来在标签内容频繁展示(已经渲染到界面)
v-show:“false” 标签内容不显示
v-show:“true” 显示标签内容 - v-bind
2.1 v-bind可以简化为”:“
html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-bind:title="one">one</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script >
const app = new Vue({
el:"#app",
data:{
one:"这是第一行字!",
}
})
</script>
</body>
</html>
运行结果:当鼠标悬停在one文字上,会提示“这是第一行文字”
2.2 样式绑定
- class样式处理
对象语法:
<div v-bind:class="{active :isActive}"></div>
--------------------------------------------------------
data:{
isActive: true
}
active是对象,isActive为是否显示.如果是false则定义在方法中用this.active = !this.active(取反)
ps:一般以is开头的属性是标志位或为true或为false
数组语法:
<div v-bind:class="[activeClass,errorClass]"></div>
-------
data:{
activeclass:'active';
errorclass:'error';
}
methods:{
点击事件的方法名:function(){
this.activeClass=' ';
this.errorClass=' ' ;
}//点击事件,去除样式的作用
- 对象绑定和数组绑定可以结合使用。
<style>
.test{
background-color:bule
}
.active{
border:1px soild red
}
.error{
font-color:yellow
}
<div v-bind:class="[activeClass,errorClass,{test.istest]"></div>
------------------------------------------------------------------------------------------------
data:{
activeclass:'active';
errorclass:'error';
isTest:true;
},
methods:{
点击事件的方法名:function(){
this.activeClass=' ';
this.errorClass=' ' ;
}//点击事件,去除样式的作用
- class绑定的值可以简化操作
<style>
.test{
background-color:bule
}
.active{
border:1px soild red
}
.error{
font-color:yellow
}
.base{
font-size:8px
}
<div v-bind:class="[activeClass,errorClass,{test.istest]"></div>
<div v-bind:class='arrclass'></div>
<div v-bind:class='objclass'></div>
------------------------------------------------------------------------------------------------
data:{
activeclass:'active';
errorclass:'error';
isTest:true;
arrClass:['active','error']
objClass:{
active:true,
error:true
}
},
methods:{
点击事件的方法名:function(){
this.activeClass=' ';
this.errorClass=' ' ;
this.objClass.error:false;
this.base:true;
}//点击事件,去除样式的作用
- 默认的class会保留下来
3、分支循环结构v-if v-else v-else-if
v-if:控制元素是否渲染到页面
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 v-bind:title="one">one</h1>
<h2 v-if="type==='A'">A</h2>
<h2 v-else-if="type==='B'">B</h2>
<h2 v-else="type==='C'">C</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script >
const app = new Vue({
el:"#app",
data:{
one:"这是第一行字!",
type:'B'
}
})
</script>
</body>
</html>
运行结果:
one
B
分支循环结构
- v-for遍历
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<li v-for=" item in xinxi" :key="xinxi.id" >
{{item.id}} {{item.name}} {{item.dept}} {{item.job}}
</li>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script >
const app = new Vue({
el:"#app",
data:{
xinxi:[
{id:'1',name:'张三',dept:'开发部',job:'运维师'},
{id:'2',name:'李四',dept:'人事部',job:'人事专员'},
{id:'3',name:'王五',dept:'财务部',job:'部长'},
]
}
})
</script>
</body>
</html>
运行结果
1 张三 开发部 运维师
2 李四 人事部 人事专员
3 王五 财务部 部长
v-for
<span v-for="(value,key,) in user">
{{key}}:{{value}}
</span>
<script>
const app = new Vue({
el:"#app",
data:{
user{name:"小明",age:23}
}
})
</script>
运行结果:
name:小明,age:23
v-for使用时,置样一定要加入“:key”用来给vue内部提供重用和排序的唯一key
- 加索引
<li v-for='(item,index)in list'>{{item}}+'----'+{{index}}</li>
<li :key='item.id' v-for='(item,index)in list'>{{item}}+'----'+{{index}}</li>
v-model双向绑定
- v-model:用来绑定标签元素的值于Vue示例数据的值保持一致,从而实现双向的数据绑定机制
- v-model的底层实现原理
<input v-bind:value="msg" v-on:input="msg=$event.target.value">
v-bind实现数据绑定,v-on实现事件绑定,$event.target.value用来获取事件触发后改变的值
<html lang="en">
<head>
<meta charset="UTF-8">
<title>记事本实例</title>
</head>
<body>
<div id="app">
<input type="text" v-model="msg" > <input type="button" value="添加到记事本" @click="save">
<br>
<ul>
<li v-for="item,index in items">
{{ index+1 }} {{item}} <a href="删除"></a>
</li>
</ul>
<br>
<span>总数量:2 条</span><input type="button" value="删除所有">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app =new Vue({
el :"#app",
data:{
items:[
"张三第一","李四第二","王五第三"
],
msg:"",
},
methods: {
save:function() {
console.log(msg);
this.items.push(this.message);
}
}
});
</script>
</body>
</html>
结果为404界面找不到,不过在其他电脑能运行,结果可是实现,目前再找原因:文件命名应该为英文,否则识别不到
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>jishiben</title>
</head>
<body>
<div id="app">
<input type="text" v-model="msg" > <input type="button" value="添加到记事本" v-on:click="save">
<br>
<ul>
<li v-for="item,index in lists">
{{ index+1 }} {{item}} <a href="javascript:;" v-on:click="delrow(index)">删除</a>
</li>
</ul>
<br>
<span>总数量:{{lists.length}} 条</span><input type="button" v-show="lists.length!=0" value="删除所有" v-on:click="delall">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app =new Vue({
el :"#app",
data:{
lists:[
"张三第一","李四第二","王五第三"
],
msg:"",
},
methods: {
save:function() {
console.log(this.msg);
this.lists.push(this.msg);//添加到记事本
this.msg='';
},
delrow:function (index) {//删除一条记录
this.lists.splice(index,1);//从下标开始删除,删除几个元素(参数介绍)
},
delall:function () {//删除所有数据
this.lists=[];
}
}
});
</script>
</body>
</html>
以上为记事本是实现案例。
MVVM机制
Model:数据 Vue实例中绑定数据
VM:VielModel 监听器
View:页面 页面展示的数据
监听器监听Model和View,当两者任一发生改变时,另一个也要对应改变
事件修饰符
用来决定事件触发条件或者是阻止事件的触发机制,和事件连用。
1、常用事件修饰符
- .stop
用来阻止事件冒泡
比如<div @click=“divclick”><input type=“button” @click=“btnclick”>
事件执行时,点击div区域,会执行divclick事件,点击button会执行先btnclick事件然后执行divclick事件,声明的时候使用@click.stop="btnclick可以只执行btnclick事件。 - .prevent
用来阻止标签的默认行为
比如<a href=“www.baidu.com” @click=“baidu”>百度一下你就知道,设置点击事件baidu为baidu{alter:“打开百度”},则默认执行顺序为点击事件弹出”打开百度“的提示,然后跳转到百度页面,如果不让他跳转到百度页面则如下设置,@click.prevent=“baidu” - .self
用来针对于当前标签的事件触发,只触发自己标签上的特定动作的事件。不监听事件冒泡
比如<div @click=“divclick”><input type=“button” @click=“btnclick”>
事件执行时,点击div区域,会执行divclick事件,点击button会执行先btnclick事件然后执行divclick事件,声明的时候使用@click.self="divclick可以只执行btnclick事件。 - .once
让事件只能触发一次
- 它们也可以并行使用
v-on:click.prevent.self:会阻止所有的点击。
v-on:click.self.prevent:只会阻止元素自身的点击。
按键修饰符
用来与键盘中的按键事件绑定在一起,修饰特定按键事件的修饰符
- .enter
触发按下回车键之后的事件
<intput type=“text” @keyup.enter=“submit”//点击回车键盘抬起> - tab
用来捕获tab键执行时触发的事件 - delete
- esc
- space
- up
- down
- left
- right
自定义按键修饰符
Vue.config.keyCodes(这是一个对象).f1(自定义的) = 112(赋的值每一个按键的唯一标识,从a为65开始到z,空格为32)
<input v-on:keyup.aaa='handle' v-model='info'>
声明:Vue.config.keyCodes.aaa = 65
方法定义:
data:{
info:' '
}
methods:{
handle: function(event){
console.log(event.keyCode)
}
Axios基本使用
1、引言
Axios是一个异步请求技术,核心作用用来在页面发送异步请求,并获取对应数据在页面的渲染,页面局部更新技术Ajax
2、第一个程序
中文网站:https://www.kancloud.cn/yunye/axios/234845
Using jsDelivr CDN:< script src=“https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js”>
安装:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
(需要在有网络的情况下使用)
2.1 get方式的请求
// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
catch块用来捕捉异常
2.2post方式请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
2.3并发请求
多个请求在同一时刻发送到后端服务接口,最后在集中处理每个请求的响应结果
Vue的组件
//组件:传递给组件中的值:props
<div id="app">
<mymodle v-for="item in items" v-bind:MM="item"></mymodel>
</div>
------------------------
Vue.component("mymodel",{
props:['MM']// 接收参数
template:'<li>{{MM}}</li>
}),
var vu = new Vue({
el:"#appp",
data:{
items:["java","Linux","web"]
});
Vue 文件export、export default、import的区别
- export default和export 导入导出变量,函数,模块,文件,等,然后在其他文件中进行导入时用import
- export向外展示变量可多次,export default只允许向外展露一次内容。
举例
数据的响应式————mvvm架构
数据的变化导致页面内容的变化
v-once只编译一次,希纳是内容之后不再有响应式功能
<div v-once>{{info}}</div>
data:{
info:"alala"
}
- 调用时,显示alala,在控制台给info进行再次赋值时,info不会发生改变。
- 用于显示后续信息不需要修改,这样就不需要在进行监听了,可以提高性能。
样式绑定
- class样式处理
- 对象语法:
<div v-bind:class="{active:isActive}"></div>
然后在data中设置相对应的参数值
- 数组语法:
<div v-bind:class="[activeClass,errorClass]"></div>
- style样式处理
- 对象语法
<div v-bind:style="{color:activeColor,fontSize:fontSize}"</div>
简洁版
data:{
objStyle:{
border:1px solid red
width:'100px';
height:'200px';
}
<div v-bind:style='objStyle'></div>
- 数组语法
<div v-bind:style="[baseStyle,overridingStyles]"></div>
当数组中的两个对象设置的属性相同但值不同时,会出现覆盖:没有的属性会加上,原有属性会被后边对象设置的覆盖掉
tab小案例
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>tab练习</title>
<style type="text/css">
.tab ul{
overflow: hidden;
padding:0;
margin:0;
}
.tab ul li {
box-sizing:border-box;
padding:0;
float:left;
width:100px;
height:45px;
line-height:45px;
list-style:none;
text-align:center;
border-top:1px solid blue;
border-right:1px solid blue;
cursor:pointer;
}
.tab ul li:first-child{
border-left:1px solid blue;
}
.tab ul li.active{
background-color:orange;
}
.tab div{
width:500px;
height:300px;
display:none;
text-align:30px;
line-height:300px;
border:1px solid blue;
border-top:0px;
}
.tab div.current{
display:block;
}
</style>
</head>
<body>
<div id="app">
<div class="tab">
<ul>
<li v-on:click="change(index)" :class='currentIndex==index?"active":""' :key='item.id' v-for='(item,index) in list'>{{item.title}}</li>
</ul>
<div :class='currentIndex==index?"current":""' :key='item.id' v-for='(item,index) in list'>
<img :src="item.path">
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
currentIndex: 0,//选项卡当前的索引
list:[{
id:1,
title:'A',
path:'img/A.jpg',
},{
id:2,
title:'B',
path:'img/B.jpg',
},{
id:3,
title:'C',
path:'img/C.jpg',
}]
},
methods:{
change:function(index){
//切换选项卡,本质时操作类名
//通过currentIndex操作类名
this.currentIndex = index;
}
}
});
</script>
</body>
</html>
运行结果:点击进行对应图片切换
Vue常用特性
表单操作
- 基于Vue的表单操作
- input 单行文本框
- textarea 多行文本框
- select 下拉多选 -----------多选时是一个数组,多选时设置标签为multiple为true
- radio 单选框 -------通过value值及进行区分
- checkbox 多选框 ---------通过数组进行默认选项的设置
通过v-model进行双向数据绑定
- 表单域修饰符
- number:转化为数值
v-model.number=‘age’ - trim:去掉开始和结尾的空格(中间的去不掉)
v-model.trim=‘info’ - lazy:将input事件切换为change事件
input事件监控输入域的内容,一有变化就改变对应的数据值,应用在注册时,用户名重复的的提示事件,在文本域失去焦点时做出判断(change事件触发),显示用户名已经存在,
- 自定义指令
- 语法规则(获取元素焦点)
Vue.directive('指令名'{
inserted:function(el){ //el表示指令所绑定的元素
//获取元素焦点
el.focus();
}
})
- 指令用法
<input type="text" v-指令名>
- 带参数的自定义指令(改变元素背景)
Vue.directive:('color'{ //color为指令名称
inserted.function(el,binding){ //binding为参数,是形参
el.style.backgroundColor = binding.value.color;
}
})
- 指令的用法
<input type="text" v-color='{color:"orange"}'>
- 局部指令
directives:{
color:{
bind: function(el,binding){
el.style.backgroundColor = binding.value.color;
}},
focus:{
inserted:function(el){
el.focus();
}}
}
<input type="text" v-focus>
局部指令只能在本组件中使用,全局指令可以。
- 计算属性
使模板内容更加简洁
反向输出msg
computed:{
reversedMessage: fuction(){
return this.msg.split(' ').reverse().join(' ')
}
}
<div>{{reverseMessage}}</div>//调用时不用加()
- 计算属性与方法的区别
计算属性是基于他们的依赖进行缓存的,可以节省一定的性能。不用重复计算
方法不存在缓存
侦听器
- 侦听器的应用场景
数据变化异步执行或者开销较大的操作 - 侦听器的用法
属性的名称要与侦听的名称一致
watch:{
firstName:fuction(val){
//val表示变化后的值
this.fullname = val + this.lastName;
}
lastName:function(val){
this.fullName = this.firstName + val;
}
}
也可以用计算属性
computed:{
fullname:function(){
return this.firstName + this.lastName;
}}
过滤器
- 过滤器的作用
格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等 - 自定义过滤器
Vue.filter('过滤器名称',function(val){
//过滤器业务逻辑
}
Vue.filter('upper',function(value){
return val.charAt(0).toUpperCase() + val.slice(1);
} //首字母大写
- 过滤器的使用
<div> {{msg|upper}}</div> //upper是过滤器的名称
<div>{{msg|upper|lower}}</div> //级联用法
<div v-bind:id="id |formatId"></div> //绑定属性
- 局部过滤器
filters:{
capitalize :function(){}
}
- 带参数的过滤器
Vue.filter('format',function(value,arg1){
//value是表示要处理的数据,传参是从第二个参数开始的
例如转换日期:
将时间转换为yyy-mm-dd
<div>{{data|format('yyyy-MM-dd')}}</div>
Vue.filter('format',function(value,arg){
if(arg == 'yyyy-MM-dd'){
var ret = ' ';
ret +=value.getFullYear() + '-'+(value.getMonth() + '-' +(value.getData();
return ret;
}
return value;
})
生命周期
主要阶段以及实例的生产过程
- 挂载(初始化相关属性)
beforeCreate// 实例在初始化之后,数据观测和时间配置之前辈调用
created// 在实例创建完成后被立即调用
beforeMount// 在挂载开始之前被调用
mounted //初始化已经完成了,界面中已经出现模板了,接下来可以进行数据获取并调用接口了 - 更新(元素或组件的变更操作)
beforeUpdated// 数据更新时调用,发生在虚拟DOM打补丁之前
updated// 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子 - 销毁(销毁相关属性)
beforeDestroy// 实例销毁之前调用
destroyed// 实例销毁之后调用
变异方法(修改原始数据)
push() //添加数据
pop() //删除数据
shift()
unshift()
splice()
sort()
reverse()
替换数组(生成新的数组)
filter()
concat()
slice()//替换,给原始的数组重新赋值
修改响应式数据
- Vue.set(vm.items,indexOfItem,newValue)
- vm.$set(vm.items,indexOfItem,newValue)
第一个参数表示要处理的数字名
第二个参数表示要处理的数组索引
第三个参数表示要处理的数组的值
Vue组件
组件化开发思想
一个模块一个模块
组件注册
- 全局组件注册语法
Vue.component(组件名称,{
data:组件数据,
template:'组件模板内容'
}
举例,设置一个按钮组件,功能是显示点击的次数
Vue.component('button-counter',{
data:function(){ //此处data的值是一个函数
return{
count:0,
}
},
template:'<button v-on:click="handle">点击了{{count}}次。</button>'
methods:{
handle:function(){
this.count++;
}
})
- 使用注册组件
将以上例子使用
<button-counter></button-counter>
- 使用注意事项
- data必须是一个函数,并返回一个函数,在实例化中data是放对象的
- 组件模板内容必须是单个根元素(不能是兄弟元素,比如button和button不可以,
<div><button></button></div>
就可以) - 组件模板内容可以是模板字符串
模板字符串需要浏览器提供支持(ES6语法)
template:`
<div>
<button @click="handle">点击了{{count}}次 </button>
<button>测试</button>
</div>
`,
`` 是模板字符串,表示在模板中可以用字符串形式
- 组件的命名方式
– 短横线方式(首字母必须是小写的,必须在单词之间加上短横线)
Vue.component('my-component',{/*---------*/})
– 驼峰方式------->使用组件的时候,只能用在模板字符串里使用驼峰的方式使用组件,但是在普通的标签模板中,必须使用短横线的方式使用组件
Vue.component('MyComponent',{/*---------*/})
- 局部组件注册
只能在注册他的父组件中使用
var componentA = {/*--------*/}
var componentB = {/*--------*/}
var componentC = {/*--------*/}
new Vue({
el:"#app"
components:{
'component-a':ComponmentA, //组件名称:属性
'component-b':ComponmentB,
'component-c':ComponmentC,
}
})
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<test-one>{{msg}}</test-one> //使用定义组件
<test-two>{{msg}}</test-two>
<test-three>{{msg}}</test-three>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var TestOne = { //定义组件的属性--data下必须是个函数
data: function () {
return {
msg: 'testone is begin'
}
},
template:'<div>{{msg}}</div>'
}
var TestTwo = {
data: function () {
return {
msg: 'testtwo is begin'
}
},
template:'<div>{{msg}}</div>'
}
var TestThree = {
data: function () {
return {
msg: 'testthree is begin'
}
},
template:'<div>{{msg}}</div>'
}
var vm = new Vue({
el:"#app",
data:{
},
components:{
'test-one':TestOne, //定义组件名
'test-two':TestTwo,
'test-three':TestThree,
}
});
</script>
</body>
</html>
运行结果:
testone is begin
testtwo is begin
testthree is begin
Vue调试工具
- 调试工具安装
为了展现元素之间的层次关系,元素们都是属于那些组件,对组建的数据进行调试,借入Vue的调试工具。
打开Vue.js官网https://cn.vuejs.org/v2/guide/-------》点击生态系统-------》在工具下点击Devtools
- 克隆仓库
复制地址 - 安装依赖包
- 构建
- 打开Chrome扩展页面
- 选择开发者模式
- 加载已解压的扩展,选择shell/chrome
组件间的数据交互
- 父组件向子组件传值
1.1 组件内部通过props接受传递过来的值
Vue.component('menu-item'),{
props:['title'] //值是一个数组,数组中可以包含许多属性
template:'<div>{{title}}</div>'
})
1.2 父组件通过属性将值传递给子组件
<menu-item title="来自父组件的数据"></menu-item> //静态绑定,写死
<menu-item : title="title"></menu-item> //动态绑定
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<test title='来自父组件的数据'></test>
<test v-bind:title='ptitle'></test>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('test',{
props:['title'], //用于父组件向子组件传递数据
data: function(){
return {
msg:'son data'
}
},
template:'<div>{{msg + "----" + title + "----" }}</div>'
});
var vm = new Vue({
el:"#app",
data:{
ptitle:'动态绑定',
},
components:{
}
});
</script>
</body>
</html>
1.3 props属性名规则
- 在props在中使用驼峰形式, 模板(template)中需要使用短横线形式,在使用时也要用短横线的形式
记不住就都用短横线 - 字符串形式的模板没有限制
1.4 props属性值类型
- 字符串String
- 数值 Number
- 布尔值Boolean
- 数组 Array
- 对象 Object
ps:数值和布尔类型的属性通过v-bind进行绑定可以得到对应类型的数据,否则默认为字符串类型,使用typeOf可以进行类型查看
- 子组件向父组件传值
props传递数据原则:只允许父组件向子组件传递数据———单项数据流
2.1 子组件通过自定义事件向父组件传递消息
<button v-on:click='$emit("enlarge-text")'>扩大字体</button>
子组件中的button,点击按钮时会触发$emit方法,方法名固定,并携带一个参数enlarge-text,传递给父组件。
父组件应用
<menu-item v-on:enlarge-text="fontSize +=0.1'></menu-item>
3.非父子组件间传值
3.1 单独的事件中心管理组件间的通信
var eventHub = new Vue()
3.2 监听事件与销毁事件
monted function(){监听事件}
//$on用于监听,第一个参数是事件的名称,第二个是事件的参数
eventHub.$on('add-todo',addTodo)
//$off用于事件的销毁
eventHub.$off('add-todo')
3.3触发指定的事件
eventHub.$emit('add-todo',id)
组件插槽
- 插槽的作用
父组件向子组件传递内容 - 基本语法
2.1 插槽位置----写在子组件的模板template中
指定插槽位置
Vue.component('alter-box'{
template:'
<div class="demo-alter-box">
<strong>error:</strong>
<slot></slot>
</div>
'
})
2.2插槽内容
父组件中放置插槽内容
<alter-box>Something great happy!</alter-box>
如果父标签中没有放置插槽内容如:
<alter-box></alter-box>
则子组件插槽中科自定义设置传递内容
<slot>你好</slot>
Vue.component('alter-box'{
template:'
<div class="demo-alter-box">
<strong>error:</strong>
<slot>你好</slot>
</div>
'
})
<div>
<alter-box></alter-box>
</div>
显示:
error:你好
- 具名插槽用法
插槽有名字
3.1 插槽定义–子组件模板中
Vue.component:('base-layout',{
template:`
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>`})
3.2插槽内容—父组件应用
显示时根据名称匹配对应内容,没有名称默认显示到未命名的插件里。
<base-layout>
<h1 slot="header">标题内容</h1>
<p>内容</p>
<p slot="footer">底部内容</p>
</base-layout>
或如下使用:
<base-layout>
<template slot='header'>
<h1 >标题内容</h1>
</template>
<template slot='footer'>
<h1 >底部内容</h1>
</base-layout>
- 作用域插槽
父组件对子组件的内容进行加工处理
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<fruit-test :list = 'list'>
<template slot-scope='slotProps'>
<strong>{{slotProps.info.name}}</strong>
</template>
</fruit-test>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('fruit-test', {
props: ['list '],
template: `
<div>
<li v-bind:key='item.id' v-for='item in list'>
<slot :info='item'>{{item.name}}</slot>
</li>
</div>
`
});
var app = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'apple'
},
{
id: 2,
name: 'banana'
},
{
id: 3,
name: 'candy'
}]
}
});
</script>
</body>
</html>
会报错
购物车案例
Vue前端交互开始
前后端交互方式
- 接口调用方式
- 原生ajax
- 基于jQuery的ajxa(对dom操作频繁)
- fetch
- axios
- URL地址格式
2.1传统的URL格式
schema://host:port/path?query#fragment
-
schema:协议。例如http https ftp等
-
host:域名或IP地址
-
port:端口,http默认端口80,可以省略
-
path:路径,如abc/a/b/c(虚拟路径,查询不同资源)
-
query:查询参数,例如uname=lisi&age=12(多个符号用&隔开)
-
fragment:锚点(哈希Hash),用于定位页面的某个位置
2.2 Restful形式的URL
-
HTTP请求方式
GET 查询
POST 添加
PUT 修改
DELETE删除 -
符合规定的URL地址
http://www.hello.com/books GET
http://www.hello.com/books POST
http://www.hello.com/books/123 PUT(修改id为123的这个事物)
http://www.hello.com/books/123 DELETE
Promise的用法
- 异步调用
- 异步效果分析
– 定时任务
–Ajax
–事件函数
$.ajax({ //调用后台接口,发送一个请求
url:’ ', //传递一个URL
success: function(data){ //回调函数,获取到后台返回的数据
console.log(data)
}
}); - 多次异步的依赖分析
–多次异步调用的结果顺序不对
–回异步调用结果若存在依赖需要嵌套(回调地狱)
同时返回多个Ajax,顺序不固定,如果指定顺序则需要嵌套,代码可读性比较低
- Promise 概述
可获取异步操作的消息,从语法上看是一个对象。是解决异步编程的一个方案。
- 避免多层异步调用
- Promise对象提供了简洁的API,使控制异步操作更加容易
- Promise对象
- 实例化Promise对象,在构造函数中传递函数,该函数中用于处理异步任务
- resolve和reject两个参数用于处理成功和失败两个情况,并通过p.then获取处理结果
var p = new Promise(function(resolve,reject){
//成功时调用 resolve();
//失败时调用 reject();
});
p.then(function(ret){
//从resolve得到正常结果
},function(ret){
//从reject得到错误信息
};
- 基于Promise处理Ajax
4.1
function queryData(url){
var p = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.onreadysatechange = function(){
if (xhr.readystate != 4) return;
if(xhr.readystate ==4&&xhr.status ==200){
resolve(xhr.responseText); //处理正常情况
}else{
reject('服务器错误'); // 处理异常情况
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data);
},function(info){
console.log(info)
});
4.2 多次发送ajax请求
queryData(){
.then(function(data){
return queryData();
})
.then(function(data){
return queryData();
})
.then(function(data){
return queryData();
});