编程语言
C#编程语言基础
C#面向对象与多线程
C#数据及文件操作
JavaScript基础
JavaScript的数据类型和变量
JavaScript的运算符和表达式
JavaScript的基本流程控制
JavaScript的函数
JavaScript对象编程
JavaScript内置对象和方法
JavaScript的浏览器对象和方法
JavaScript访问HTML DOM对象
JavaScript事件驱动编程
JavaScript与CSS样式表
Ajax与PHP
ECMAScript6的新特性
Vue.js前端开发
PHP的常量与变量
PHP的数据类型与转换
PHP的运算符和优先规则
PHP程序的流程控制语句
PHP的数组操作及函数
PHP的字符串处理与函数
PHP自定义函数
PHP的常用系统函数
PHP的图像处理函数
PHP类编程
PHP的DataTime类
PHP处理XML和JSON
PHP的正则表达式
PHP文件和目录处理
PHP表单处理
PHP处理Cookie和Session
PHP文件上传和下载
PHP加密技术
PHP的Socket编程
PHP国际化编码
MySQL数据库基础
MySQL数据库函数
MySQL数据库账户管理
MySQL数据库基本操作
MySQL数据查询
MySQL存储过程和存储函数
MySQL事务处理和触发器
PHP操作MySQL数据库
数据库抽象层PDO
Smarty模板
ThinkPHP框架
Python语言基础
Python语言结构与控制
Python的函数和模块
Python的复合数据类型
Python面向对象编程
Python的文件操作
Python的异常处理
Python的绘图模块
Python的NumPy模块
Python的SciPy模块
Python的SymPy模块
Python的数据处理
Python操作数据库
Python网络编程
Python图像处理
Python机器学习
TensorFlow深度学习
Tensorflow常用函数
TensorFlow用于卷积网络
生成对抗网络GAN
1. 表单控件绑定:
在Web应用中,通过表单可以实现输入文字、选择选项和提交数据等功能。在Vue.js中,通过v-model指令可以对表单元素进行双向数据绑定,在修改表单元素值的同时,Vue实例中对应的属性值也会随之更新,反之亦然。v-model会根据控件类型自动选择正确的方法来更新元素。
1)绑定文本框:
在表单中,最基本的控件是文本框,分为单行文本框和多行文本框。
⑴ 单行文本框:
单行文本框用于输入单行文本,应用v-model指令对单行文本框进行数据绑定的示例代码:
<div id="box">
<p>单行文本框</p>
<input v-model="message" placeholder="在此输入数据">
<p>当前输入:{{message}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
message:''
}
});
</script>
上述代码中,应用v-model指令将单行文本框的值和Vue实例中的message属性值进行了绑定,当单行文本框中的内容发生变化时,message属性值也会相应进行更新。
⑵ 多行文本框:
多行文本框也叫文本域,应用v-model指令对文本域进行数据绑定的示例代码:
<div id="box">
<p>多行文本框</p>
<textarea v-model="message" placeholder="在此输入数据"></textarea>
<p style="write-space:pre">{{message}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
message:''
}
});
</script>
2)绑定复选框:
为复选框进行数据绑定有两种情况,一种是为单个复选框进行数据绑定,另一种是为多个复选框进行数据绑定。
⑴ 单个复选框:
如果只有一个复选框,应用v-model绑定的是一个布尔值。示例代码:
<div id="box">
<p>单个复选框</p>
<input type=":checkbox" v-model="checked">
<label for="checkbox">checked: {{checked}}</label>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
checked:false
}
});
</script>
运行上述代码,当选中复选框时,v-model绑定的checked属性值为true,否则为false,而label元素中的值也会随之改变。
⑵ 多个复选框:
如果有多个复选框,应用v-model绑定的是一个数组。示例代码:
<div id="box">
<p>多个复选框</p>
<input type="checkbox" value="Nokia" v-model="brand">
<label for="nokia">Nokia</label>
<input type="checkbox" value="Samsung" v-model="brand">
<label for="samsung">Samsung</label>
<input type="checkbox" value="Motorola" v-model="brand">
<label for="motorola">Motorola</label>
<p>选择的手机品牌:{{brand}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
brand:[]
}
});
</script>
上述代码中,应用v-model将多个复选框绑定到同一个数组brand。当选中某个复选框时,该复选框value值会存入brand数组;当取消某个复选框时,该复选框的值会从brand数组中移除。
3)绑定单选按钮:
当某个单选按钮被选中时,v-model绑定的属性值会被赋值为该单选按钮的value值。示例代码:
<div id="box">
<p>单选按钮</p>
<input type="radio" value="男" v-model="sex">
<label for="man">男</label>
<input type="radio" value="女" v-model="sex">
<label for="woman">女</label>
<p>选择的性别:{{sex}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
sex:''
}
});
</script>
4)绑定下拉列表:
下拉列表也分为单选和多选两种,所以v-model在绑定下拉列表时也分为两种不同的情况。
⑴ 单选下拉列表:
在只提供单选的下拉列表中,当选择某个选项时,如果为该选项设置了value值,则v-model绑定的属性值会被赋值为该选项的value值,否则会被赋值为显示在该选项中的文本。示例代码:
<div id="box">
<p>单选下拉列表</p>
<select v-model="type">
<option value="">请选择种类</option>
<option value="">手机</option>
<option value="">电视</option>
<option value="">空调</option>
</select>
<p>选择的种类:{{type}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
type:''
}
});
</script>
也可以通过v-for指令动态生成下拉列表中的option,并应用v-model对生成的下拉列表进行绑定。示例代码:
<div id="box">
<p>动态单选下拉列表</p>
<select v-model="answer">
<option value="">请选择答案</option>
<option v-for="iten in items" :value="item.value">{{item.text}}</option>
</select>
<p>选择的答案:{{answer}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
answer:'',
items:[
{text:'A',value:'A'},
{text:'B',value:'B'},
{text:'C',value:'C'},
{text:'D',value:'D'}
]
}
});
</script>
⑵ 多选下拉列表:
如果为select元素设置了multiple属性,下拉列表中的选项会以列表的方式显示,此时列表框中的选项可以多选。在进行多选时,应用v-model绑定的是一个数组。示例代码:
<div id="box">
<p>多选下拉列表</p>
<select v-model="filmtype" multiple="multiple" size=6>
<option>动作片</option>
<option>爱情片</option>
<option>科幻片</option>
<option>喜剧片</option>
</select>
<p>选择的类型:{{filmtype}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
filmtype:[]
}
});
</script>
上述代码中,应用v-model将select元素绑定到数组filmtype。当选中某个选项时,该选项中的文本会存入filmtype数组中;当取消选中某个选项时,该选项中的文本会从filmtype数组中移除。
5)值绑定:
通常情况下,对于单选按钮、复选框及下拉列表中的选项,v-model绑定的值是字符串(单选复选框是布尔值)。但是有时需要把值绑定到Vue实例的一个动态属性上,这时可以应用v-bind实现,并且该属性值可以不是字符串,如数值、对象、数组等。
⑴ 单选按钮:
单选按钮中将值绑定到一个动态属性上的示例代码:
<div id="box">
<p>单选按钮值绑定</p>
<input type="radio" :value="sexObj.man" v-model="sex">
<label for="man">男</label>
<input type="radio" :value="sexObj.woman" v-model="sex">
<label for="woman">女</label>
<p>选择的性别:{{sex}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
sex:'',
sexObj:{man:'男',woman:'女'}
}
});
</script>
⑵ 复选框:
在单个复选框中,可以应用true-value和false-value属性将值绑定到动态属性上。示例代码:
<div id="box">
<p>单个复选框值绑定</p>
<input type="checkbox" v-model="toggle" :true-value="yes" :false-value="no">
<label for="checkbox">当前状态: {{toggle}}</label>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
toggle:'',
yes:'选中',
no:'取消'
}
});
</script>
在多个复选框中,需要用v-bind进行值绑定,示例代码:
<div id="box">
<p>多个复选框值绑定</p>
<input type="checkbox" :value="brands[0]" v-model="brand">
<label>{{brands[0]}}</label>
<input type="checkbox" :value="brands[1]" v-model="brand">
<label>{{brands[1]}}</label>
<input type="checkbox" :value="brands[2]" v-model="brand">
<label>{{brands[2]}}</label>
<p>选择的手机品牌:{{brand.join('、')}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
brands:['Nokia','Samsung','Motorola']
brand:[]
}
});
</script>
⑶ 下拉列表:
在下拉列表中将值绑定到一个动态属性上的示例代码:
<div id="box">
<p>单选下拉列表</p>
<select v-model="num">
<option :value="num[0]">{{num[0]}}</option>
<option :value="num[1]">{{num[1]}}</option>
<option :value="num[2]">{{num[2]}}</option>
</select>
<p>选择的数字:{{num}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
nums:[10,20,30],
num:10
}
});
</script>
6)使用修饰符:
Vue.js为v-model指令提供了一些修饰符,通过这些修饰符可以处理某些常规操作。
⑴ lazy:
默认情况下,v-model在input事件中将文本框的值与数据同步。添加lazy修饰符后,可以转变为使用change事件进行同步。示例代码:
<div id="box">
<input v-model.lazy="message" placeholder="在此输入数据">
<p>当前输入:{{message}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
message:''
}
});
</script>
运行上述代码,当触发文本框的change事件后,才会输出文本框中输入的内容。
⑵ number:
在v-model指令中使用number修饰符,可以自动将用户输入转换为数值类型。如果转换结果为NaN,则返回用户输入的原始值。示例代码:
<div id="box">
<input v-model.number="message" placeholder="在此输入数据">
<p>当前输入:{{message}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
message:''
}
});
</script>
⑶ trim:
如果要自动过滤用户输入的字符串首尾空格,可以为v-model指令添加trim修饰符。示例代码:
<div id="box">
<input v-model.trim="message" placeholder="在此输入数据">
<p>当前输入:{{message}}</p>
</div>
<script type="text/javascript">
var vm=new Vue({
el: '#box',
data:{
message:''
}
});
</script>
2. 自定义指令:
Vue.js提供的内置指令很多,如v-for、v-if、v-model等。有时候在实现具体业务逻辑时,应用这些内置指令并不能实现某些特定功能,因此也允许用户注册自定义指令,以便提高代码的复用性。
1)注册指令:
Vue.js提供了注册自定义指令的方法,通过不同的方法可以注册全局自定义指令和局部自定义指令。
⑴ 注册全局自定义指令:
通过Vue.directive(id,definition)方法可以注册一个全局自定义指令。该方法可以接收两个参数,指令ID和定义对象,指令ID是指令的唯一标识符,定义对象是定义的指令的钩子函数。
注册全局自定义指令实现当前页面加载时使元素自动获得焦点的示例代码:
<div id="example">
<input v-focus>
</div>
<script type="text/javascript">
Vue.directive('focus',{
//当被绑定的元素插入DOM中时执行
inserted:function(el){
//使元素获得焦点
el.focus();
}
})
var exam=new Vue({
el: '#example'
});
</script>
上述代码中,focus是自定义指令ID,不包括前缀v-,inserted是指令定义对象的钩子函数。该钩子函数表示,当被绑定元素插入父节点时,使元素自动获得焦点。在注册全局指令后,在被绑定元素中应用该指令即可实现相应的功能。
⑵ 注册局部指令:
通过Vue实例中的directives选项可以注册一个局部自定义指令。注册一个为元素添加边框的局部自定义指令的示例代码:
<div id="example">
<span v-add-border="border">得过且过</span>
</div>
<script type="text/javascript">
var exam=new Vue({
el: '#example',
data:{
border:'1px solid #FF00FF'
},
directives:{
addBorder:function(){
inserted:function(el,binding){
el.style.border=binding.value;
}
}
},
});
</script>
上述代码中,在注册自定义指令时采用了驼峰命名方式,将自定义指令ID定义为addBorder,而在元素中应用指令时的写法为v-add-border。在为自定义指令命名时建议采用这种方式。
局部自定义指令只能在当前实例中进行调用,而无法在其他实例中调用。
2)钩子函数:
在注册指令时,可以传入definition定义对象,对指令赋予一些特殊的功能。一个指令定义对象可以提供的钩子函数见下表:
钩子函数 | 说明 |
---|---|
bind | 只调用一次,在指令第1次绑定到元素上时调用,可用来定义绑定时的初始化设置 |
inserted | 被绑定元素插入父元素时调用 |
update | 指令在bind后立即以初始值为参数进行第1次调用,之后每次当绑定值发生变化时调用,接收的参数为新值和旧值 |
componentUpdated | 指令所在组件及其子组件更新时调用 |
unbind | 只调用一次,指令从元素上解绑定时调用 |
· el:指令所绑定的元素,可以用来直接操作DOM
· binding:一个对象,包含的属性见下表:
属性 | 说明 |
---|---|
name | 指令名,不包括前缀v- |
value | 指令的绑定值,例如,v-my-directive="1+1",value的值为2 |
oldValue | 指令绑定的前一个值,仅在update和componentUpdated钩子函数中可用,无论是否改变都可用 |
expression | 绑定的表达式或变量名,例如,v-my-directive="1+1",expression的值是"1+1" |
arg | 传给指令的参数,例如,v-my-directive:foo,arg的值为foo |
modifiers | 一个包括修饰符的对象,例如,v-my-directive:foo.bar,修饰符对象modifiers的值是{foo:true, bar:true} |
· oldVnode:上一个虚拟节点,仅在update和componentUpdated钩子函数中可用
除了el参数外,其他参数都应该是只读的,不要修改。使用钩子函数的参数和相关属性的示例代码:
<div id="box" v-demo:hello.a.b="message"></div>
<script type="text/javascript">
Vue.directive('demo',{
bind:function(el,binding,vnode){
el.innerHTML=
'name: '+binding.name+'<br>'+
'value: '+binding.value+'<br>'+
'expression: '+binding.expression+'<br>'+
'argument: '+binding.arg+'<br>'+
'modifiers: '+JSON.string(binding.modifiers)+'<br>'+
'vnode: '+Object.keys(vnode).join(', ')
}
}
var vm=new Vue({
el: '#box',
data:{
message:'欢迎来到个人空间!'
}
});
</script>
通过文本框输入页面图片边框宽度的示例:
<div id="example">
边框宽度:<input type="text" v-model="border">
<p><img width="200" src="line.jpg" v-set-border="border"></p>
</div>
<script type="text/javascript">
var exam=new Vue({
el: '#example',
data:{
border:''
},
directives:{
setBorder:{
update:function(el,binding){
el.border=binding.value;
}
}
},
});
</script>
有些时候,可能只需要使用bind和update钩子函数,这时可以直接传入一个函数代替定义对象。示例代码:
Vue.directive('set-bgcolor',function(el,binding){
el.style.backgroundColor=binding.value;
})
页面中根据下拉列表中选择的选项实现设置文字大小的示例代码:
<div id="example">
<label>选择文字大小:</label>
<select v-model="size">
<option value="20px">20px</option>
<option value="30px">30px</option>
<option value="40px">40px</option>
<option value="50px">50px</option>
<option value="60px">60px</option>
</select>
<p v-font-size="size">过一天算一天</p>
</div>
<script type="text/javascript">
var exam=new Vue({
el: '#example',
data:{
size:'20px'
},
directives:{
fontSize:function(el,binding){
el.style.fontSize=binding.value;
}
}
},
});
</script>
3)自定义指令的绑定值:
自定义指令的绑定值除了可以是data中的属性之外,还可以是任意合法的JavaScript表达式,如数值常量、字符串常量、对象字面量等。
⑴ 绑定数值常量:
比如,注册一个自定义指令,通过该指令设置定位元素的左侧位置,将该指令的绑定值设置为一个数值,该数值即为被绑定元素到页面左侧的距离。示例代码:
<div id="example">
<p v-set-position="50">日子一天天过</p>
</div>
<script type="text/javascript">
Vue.directive('set-position',function(el,binding){
el.style.position='fixed';
el.style.left=binding.value+'px';
})
var exam=new Vue({
el: '#example'
});
</script>
⑵ 绑定字符串常量:
将自定义指令的绑定值设置为字符串常量需要使用单引号。例如注册一个自定义指令,通过该指令设置文本的颜色,将该指令的绑定值设置为字符串'#0000FF',该字符串即为被绑定元素设置的颜色。示例代码:
<div id="example">
<p v-set-color="'#0000FF'">伟大在于宣传</p>
</div>
<script type="text/javascript">
Vue.directive('set-color',function(el,binding){
el.style.color=binding.value;
})
var exam=new Vue({
el: '#example'
});
</script>
⑶ 绑定对象字面量:
如果指令需要多个值,可用传入一个JavaScript对象字面量,此时对象字面量不需要使用单引号括起来。比如注册一个自定义指令,通过该指令设置文本的大小和颜色,将该指令的绑定值设置为对象字面量的示例代码:
<div id="example">
<p v-set-style="{size:30,coloe:'gray'}">闲着无事到处逛</p>
</div>
<script type="text/javascript">
Vue.directive('set-style',function(el,binding){
el.style.fontSize=binding.value.size+'px';
el.style.color=binding.value.color;
})
var exam=new Vue({
el: '#example'
});
</script>
3. 组件:
组件Component是Vue.js最强大的功能之一,通过开发组件,可以封装可复用的代码,将封装好的代码注册成标签,实现扩展HTML元素的功能。几乎任意类型的界面都可以抽象为一个组件树,而组件树可以用独立可复用的组件来构建。
1)注册组件:
在使用组件之前,需要将组件注册到应用中,Vue.js提供了全局注册和局部注册两种方式。
⑴ 注册全局组件:
全局组件可以在所有实例中使用。注册一个全局组件的语法格式:
Vue.component(tagName,options)
其中参数:
· tagName:定义的组件名称,遵循W3C规范中的自定义组件命名方法,即全部字母小写并包含连字符“-”
· options:可以是应用Vue.extend()方法创建的一个组件构造器,也可以是组件的选项对象
因为组件是可以复用的Vue实例,所以它们与一个Vue实例一样接收相同的选项(el选项除外),如data、computed、watch、methods,以及生命周期钩子等。
全局组件需要在创建的根实例之前注册,这样才能使组件在实例中调用。在注册组件后,可以在创建的Vue根实例中以自定义元素的形式使用,使用组件的方法:
<tagName></tagName>
注册一个简单全局组件的示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//创建组件构造器
var myComponent=Vue.extend({
template:'<h2>注册全局组件</h2>'
});
//注册全局组件
Vue.component('my-component',myComponent);
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
上述代码使用组件构造器的方式,另外还可以注册是直接传入选项对象而不是构造器。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
template:'<h2>注册全局组件</h2>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
为了使代码更简化,建议在注册组件时采用直接传入选项对象的方式。
如果模板内容有多个元素,可以将模板的内容包含在一个父元素内。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
template:'<div>\
<h2>全局组件</h2>\
<span>全局组件可以在所有实例中使用</span>\
</div>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
需要注意,组件选项对象中的data和Vue实例选项对象中的data的赋值是不同的。一个组件的data选项必须是一个函数,而不是一个对象,这样每个实例都可以维护一份被返回对象的独立的复制。示例代码:
<div id="example">
<button-count></button-count>
<button-count></button-count>
<button-count></button-count>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('button-count',{
data:function(){
return {
count:0
}
},
template:'<button v-on:click="count++">单击了{{count}}次</button>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
上述代码中定义了3个相同的按钮组件。当单击某个按钮时,每个组件都会各自独立维护其count属性,因此单击一个按钮时其他组件不会受到影响。
⑵ 注册局部组件:
通过Vue实例中的components选项可以注册一个局部组件。对于components对象中的每个属性来说,其属性名就是定义组件的名称,其属性值就是这个组件的选项对象。局部组件只能在当前实例中使用。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
var Child={
template:'<h2>注册局部组件</h2>'
}
//创建根实例
var vm=new Vue({
el: '#example',
components:{
'my-component':Child //注册局部组件
}
});
</script>
局部注册的组件只能在其父组件中使用,而无法在其他组件中使用。父子组件定义示例:
<div id="example">
<parent-component></parent-component>
</div>
<script type="text/javascript">
var Child={
template:'<h2>这是子组件</h2>'
}
var Parent={
template:<div>\
<h2>这是父组件</h2>\
<child-component></child-component>\
</div>',
components:{
'child-component':child
}
}
//创建根实例
var vm=new Vue({
el: '#example',
components:{
'parent-component':Parent
}
});
</script>
2)数据传递:
因为组件实例的作用域是孤立的,所以子组件的模板无法直接引用父组件的数据。如果想要实现父子组件之间数据的传递,就需要定义Prop。
⑴ Prop:
Prop是父组件用来传递数据的一个自定义属性,这样的属性需要定义在组件选项对象的props选项中。通过props选项中定义的属性,可以将父组件的数据传递给子组件,而子组件需要显式地用props选项来声明Prop。示例代码:
<div id="example">
<my-component message="幻想总会破灭"></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
props:{'message'}, //传递Prop
template:'<p>{{message}}</p>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
一个组件默认可以拥有任意数量的Prop,任何值都可以传递给任何Prop。
⑵ Prop的大小写:
由于HTML中的属性是不区分大小写的,因此浏览器会把所有大写字符解释为小写字符。如果在调用组件时使用了驼峰式命名属性,那么在props中的命名需要全部小写。示例代码:
<div id="example">
<my-component myTitle="世俗与偏见"></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
props:{'mytitle'}, //名称小写
template:'<p>{{mytitle}}</p>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
如果在props中的命名采用的是驼峰方式,那么在调用组件的标签中需要使用其等价的短横线分隔的命名方式来命名属性。示例代码:
<div id="example">
<my-component my-title="世俗与偏见"></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
props:{'myTitle'}, //名称小写
template:'<p>{{myTitle}}</p>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
⑶ 传递动态Prop:
除了传递静态数据外,也可以通过v-bind的方式将父组件中的data数据传递给子组件。每当父组件的数据发生变化时,子组件也会随之变化。示例代码:
<div id="example">
<my-component v-bind:boxoffice="boxoffice"></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
props:{'boxoffice'}, //名称小写
template:'<p>该电影票房已经达到了{{boxoffice}}亿元</p>'
});
//创建根实例
var vm=new Vue({
el: '#example'
data:{
boxoffice:20
}
});
</script>
上述代码中,更改根实例中boxoffice的值时,组件中的值也会随之更改。另外,在调用组件时也可以简写为:
<my-component :boxoffice="boxoffice"></my-component>
使用Prop传递的数据除了可以是数值和字符串类型外,还可以是数组或对象类型。传递数组类型数据的示例代码为:
<div id="example">
<my-item :list="type"></my-item>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-item',{
props:['list'], //传递数组类型Prop
template:'<ol>\
<li v-for="item in list">{{item}}</li>\
</ol>'
});
//创建根实例
var vm=new Vue({
el: '#example'
data:{
type:['HTML','CSS','JavaScript']
}
});
</script>
如果Prop传递的是一个对象或数组,那么是按引用传递的,在子组件内修改这个对象或数组本身将会影响父组件的状态。
在传递对象类型数据时,如果想要将一个对象的所有属性都作为Prop传入,可以使用不带参数的v-bind。示例代码:
<div id="example">
<my-shop v-bind="shop"></my-shop>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-shop',{
props:['name','price','number'], //传递数组类型Prop
template:'<div>\
<div>名称:{{name}}</div>\
<div>价格:{{price}}</div>\
<div>数量:{{number}}</div>\
</div>'
});
//创建根实例
var vm=new Vue({
el: '#example'
data:{
shop:{
name:'Nokia T-1045',
price:999,
number:10
}
});
</script>
⑷ Prop验证:
组件可以为Prop指定验证要求。使用验证时,Prop接收的参数是一个对象,而不是一个字符串数组。Vue.js提供的Prop验证方式有多种。
· 基础类型验证:
允许参数为指定的一种类型。示例代码:
props:{
propA:String
}
上述代码表示,参数propA允许的数据类型为字符串。可以接收的参数类型包括,String、Number、Boolean、Array、Object、Date、Function、Symbol,也可以接收null和undefined,表示任意类型均可。
· 多种类型:
允许参数为多种类型之一。示例代码:
props:{
propB:[String,Number]
}
上述代码表示参数propB可以是字符串类型或数值类型。
· 参数必选:
参数必须有值且为指定的类型。示例代码:
props:{
propC:{
type:String,
required:true
}
}
上述代码表示,参数propC必须有值且为字符串类型。
· 参数默认:
参数具有默认值。示例代码:
props:{
propD:{
type:Number,
default:100
}
}
上述代码表示,参数propD为数值类型,默认值100。需要注意,如果参数类型为数组或对象,则其默认值需要通过函数返回值的形式赋值。示例代码:
props:{
propE:{
type:Object,
default:function(){
return {
message:'hello'
}
}
}
}
· 自定义验证函数:
根据验证函数验证参数的值是否符合要求。示例代码:
props:{
propF:{
validator:function(value){
return value>0
}
}
}
在开发环境中,如果Prop验证失败,Vue将会产生一个控制台警告。对组件中传递的数据进行Prop验证的示例代码:
<div id="example">
<my-component :num="100" :message="'我是乞丐'" :custom="50"></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
props:{
num:String,
message:{
type:String,
required:true
},
dnum:{
type:Number,
default:1000
},
object:{
type:Object,
default:function(){
return {message:'hello'}
}
},
custom:{
validator:function(value){
return value>10
}
}
},
template:'<div>\
<p>num:{{num}}</p>\
<p>message:{{message}}</p>\
<p>dnum:{{dnum}}</p>\
<p>object:{{object}}</p>\
<p>custom:{{custom}}</p>\
</div>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
3)自定义事件:
父组件通过使用Prop为子组件传递数据,但如果子组件要把数据传递回去,就需要使用自定义事件来实现。
⑴ 自定义事件的监听和触发:
父级组件可以像处理原生DOM事件一样通过v-on监听子组件实例的自定义事件,而子组件可以通过调用内建的$emit()方法传入事件名称来触发自定义事件。$emit()方法的语法格式:
vm.$emit(eventName,[...args])
参数说明:eventName:传入事件的名称;...args:触发事件传递的参数,可选。示例代码:
<div id="example">
<div v-bind:style="{fontSize:fontSize+'px'}">
<my-font v-bind:text="text" v-on:enlarge="fontSize+=2"></my-font>
</div>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-font',{
props:['text'],
template:'<div>\
<button v-on:click="action">放大文本</button>\
<p>{{text}}</p>\
</div>',
methods:{
action:function(){
this.$emit('enlarge'); //触发自定义enlarge事件
}
}
});
//创建根实例
var vm=new Vue({
el: '#example'
data:{
text:'人生得意须尽欢',
fontSize:16
}
});
</script>
有时需要在自定义事件中传递一个特定的值,这时可以使用$emit()方法的第2个参数,然后当在父组件监听这个事件的时候,可以通过$event访问到传递的这个值。
改写上例代码,实现每次单击按钮将文本大小增加5px:
<div id="example">
<div v-bind:style="{fontSize:fontSize+'px'}">
<my-font v-bind:text="text" v-on:enlarge="fontSize+=$event"></my-font>
</div>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-font',{
props:['text'],
template:'<div>\
<button v-on:click="action(5)">放大文本</button>\
<p>{{text}}</p>\
</div>',
methods:{
action:function(value){
this.$emit('enlarge',value); //触发自定义enlarge事件
}
}
});
//创建根实例
var vm=new Vue({
el: '#example'
data:{
text:'人生得意须尽欢',
fontSize:16
}
});
</script>
在父组件监听自定义事件时,如果事件处理程序是一个方法,那么通过$emit()方法传递的参数将会作为第1个参数传入这个方法。页面导航菜单示例代码:
<div id="example">
<my-menu @select-item="onSelectItem" :flag="flag"></my-menu>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-menu',{
props:['flag'],
template:'<div class="nav">\
<span @click="select(1)" :class="active:flag===1">音乐</span>\
<span @click="select(2)" :class="active:flag===2">体育</span>\
<span @click="select(3)" :class="active:flag===3">影视</span>\
<span @click="select(4)" :class="active:flag===4">图片</span>\
</div>',
methods:{
select(value){
this.$emit('select-item',value); //触发自定义事件并传递参数
}
}
});
//创建根实例
var vm=new Vue({
el: '#example'
data:{
flag:1
},
methods:{
onSelectItem:function(value){
this.flag=value
}
}
});
</script>
⑵ 将原生事件绑定到组件:
如果想在某个组件的根元素上监听一个原生事件,可以使用v-on的native修饰符,例如,在组件的根元素上监听click事件,当单击组件时弹出“欢迎访问本网站~”的对话框,代码:
<div id="example">
<my-component v-on:click.native="openDialog"></my-component>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-component',{
template:'<div>\
<button>单击按钮弹出对话框</button>\
</div>'
});
//创建根实例
var vm=new Vue({
el: '#example'
methods:{
openDialog:function(){
alert('欢迎访问本网站');
}
}
});
</script>
4)内容分发:
在实际开发中,子组件往往只提供基本的交互功能,而内容是由父组件提供。为此Vue.js提供了一种混合父组件内容和子组件模板的方式,称为内容分发。
⑴ 基础用法及编译作用域:
Vue.js参照当前Web Components规范草案实现了一套内容分发的API,使用
<div id="example">
<my-slot>{{message}}</my-slot>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-slot',{
template:'<div class="title">\
<slot></slot>\
</div>'
});
//创建根实例
var vm=new Vue({
el: '#example',
data:{
message:'先定一个小目标,比如一个亿'
}
});
</script>
父组件中的内容{{message}}会替代子组件中的
上述代码中,在<my-slot>{{data}}</my-slot>模板下,父组件模板里的所有内容都是在父组件作用域中编译的;子组件模板里的所有内容都是在子组件作用域中编译的。
⑵ 后备内容:
有些时候,需要为一个插槽设置具体的后备内容(即默认内容),该内容只会在没有提供内容的时候渲染。示例代码:
<div id="example">
<my-button></my-button>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-button',{
template:'<button>\
<slot>提交</slot>\
</button>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
上述代码中,在父组件中使用组件
<div id="example">
<my-button>{{value}}</my-button>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-button',{
template:'<button>\
<slot>提交</slot>\
</button>'
});
//创建根实例
var vm=new Vue({
el: '#example',
data:{
value:'注册'
}
});
</script>
上述代码中,在父组件中使用
⑶ 具名插槽与默认插槽:
有些时候,需要在组件模板中使用多个插槽,这时需要用到
<div id="example">
<my-slot>
<template v-slot:title>
<p>{{title}}</p>
</template>
<template v-slot:content>
<div>{{content}}</div>
</template>
</my-slot>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-slot',{
template:'<div>\
<div class="title">
<slot name="title"></slot>\
</div>\
<div class="content">
<slot name="content"></slot>\
</div>\
</div>'
});
//创建根实例
var vm=new Vue({
el: '#example',
data:{
title:'什么是Vue.js',
content:'一套用于构建用户界面的渐进式框架'
}
});
</script>
一个未设置name属性的插槽称为默认插槽,它有一个隐含的name属性值default。如果有些内容没有被包含在带有v-slot的<template>中,则这部分内容会被视为默认插槽内容。
<div id="example">
<my-slot>
<img :src="pic"><!--这行代码会被视为默认插槽内容-->
<template v-slot:name>
<p>{{name}}</p>
</template>
<template v-slot:price>
<p>{{price}}</p>
</template>
</my-slot>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-slot',{
template:'<div>\
<div class="pic">
<slot></slot>\
</div>\
<div class="name">
<slot name="name"></slot>\
</div>\
<div class="price">
<slot name="price"></slot>\
</div>\
</div>'
});
//创建根实例
var vm=new Vue({
el: '#example',
data:{
pic:'11.jpg',
name:'Nokia TA-1054',
price:999
}
});
</script>
为了使代码看起来更明确,可以在一个<template>元素中包含默认插槽的内容。比如:
<template v-slot:default>
<img :src="pic">
</template>
⑷ 作用域插槽:
有些时候需要让插槽内容能够访问子组件中才有的数据。为了让子组件中的数据在父级的插槽内容中可用,可以将子组件中的数据作为一个
<div id="example">
<my-shop>
<template v-slot:default="slotProps">
<p>商品名称:{{slotProps.shop}}</p>
</template>
</my-shop>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('my-shop',{
template:'<span>\
<slot v-bind:shop="shop"></slot>\
</span>',
data:fuction(){
return{
shop:'Nokia TA-1054'
}
}
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
上述代码中,将子组件中的数据shop作为
当提供了内容只有默认插槽时,组件的标签可以被当作插槽的模板来使用。这样就可以把v-slot直接用在组件上。上面代码可以简写为:
<my-shop v-slot:default="slotProps">
<p>商品名称:{{slotProps.shop}}</p>
</my-shop>
5)混入:
混入是一种为组件提供可复用功能的非常灵活的方式。混入的对象可以包含任意的组件选项。
⑴ 基础语法:
当组件使用混入对象时,混入对象中的所有选项将被混入该组件本身的选项中。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//定义一个混入对象
var myMixin={
created:function(){
this.show();
},
methods:{
show:function(){
document.write('Vue.js中的混入');
}
}
};
//定义一个使用混入对象的组件
Vue.component('my-component',{
mixins:[myMixin],
template:'<h3>Hello Vue.js</h3>'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
⑵ 选项合并:
当组件和混入对象包括同名选项时,这些选项将以适当的方式合并。比如,数据对象会在内部进行递归合并,在和组件的数据发生冲突时以组件数据优先。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//定义一个混入对象
var myMixin={
data:function(){
return {
type:'图书',
number:10
};
}
};
//定义一个使用混入对象的组件
Vue.component('my-component',{
mixins:[myMixin],
data:function(){
return {
type:'手机',
price:2000
};
}
template:'<div>\
<div>类型:{{type}}</div>\
<div>数量:{{number}}</div>\
<div>价格:{{price}}元</div>\
</div>',
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
同名钩子函数将混合为一个数组,因此都会被调用。另外,混入对象的钩子将在组件自身的钩子之前调用。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//定义一个混入对象
var myMixin={
created:function(){
this.show();
},
methods:{
show:function(){
document.write('混入调用<br>');
}
}
};
//定义一个使用混入对象的组件
Vue.component('my-component',{
mixins:[myMixin],
created:function(){
document.write('组件调用');
}
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
值为对象的选项,比如,methods、components和directives,将被合并为同一个对象。如果两个对象的键名冲突,则取组件对象的键值对。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//定义一个混入对象
var myMixin={
methods:{
showName:function(){
document.write('人物名称:虚竹<br>');
},
showSchool:function(){
document.write('所属门派:少林派<br>');
}
}
};
//定义一个使用混入对象的组件
Vue.component('my-component',{
mixins:[myMixin],
methods:{
showWugong:function(){
document.write('武功绝学:童子功<br>');
},
showSchool:function(){
document.write('所属门派:逍遥派<br>');
}
},
created:{
this.showName();
this.showSchool();
this.showWugong();
}
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
⑶ 全局混入:
混入对象也可以全局注册,但需要小心使用。一旦使用全局混入对象,它就会影响到所有之后创建的Vue实例。如果使用恰当,就可以自定义选项注入处理逻辑。全局注册一个混入对象使用的是Vue.mixin()方法。示例代码:
<div id="example">
<my-component></my-component>
</div>
<script type="text/javascript">
//定义一个混入对象
Vue.mixin={
created:function(){
var myOption=this.$options.myOption;
if(myOption){
document.write(myOption);
}
}
};
//在组件中自定义一个选项
Vue.component('my-component',{
myOption:'自定义选项'
});
//创建根实例
var vm=new Vue({
el: '#example'
});
</script>
6)动态组件:
Vue.js提供了对动态组件的支持。在使用动态组件时,多个组件使用同一个挂载点,根据条件在不同组件之间进行动态切换。
⑴ 基础用法:
通过使用Vue.js中的<component>元素,动态绑定到它的is属性,根据is属性的值来判断使用哪个组件。动态组件经常用在路由控制或选项卡切换中。示例代码:
<div id="example">
<div class="box">
<ul class="mainmenu" :class="current">
<li class="music" v-on:click="current='music'">音乐</li>
<li class="videos" v-on:click="current='videos'">视频</li>
<li class="news" v-on:click="current='news'">新闻</li>
</ul>
<component :is="current"></component>
</div>
</div>
<script type="text/javascript">
//创建根实例
var vm=new Vue({
el: '#example',
data:{
current:'music'
},
//注册局部组件
components:{
music:{
template:'<div>音乐内容</div>'
},
videos:{
template:'<div>视频内容</div>'
},
news:{
template:'<div>新闻内容</div>'
}
}
});
</script>
⑵ keep-alive:
在多个组件之间进行切换时,有时需要保持这些组件的状态,将切换后的状态保留在内存中,以避免重复渲染。为了解决这个问题,可以使用一个<keep-alive>元素将动态组件包含起来。修改上面的示例代码:
<div id="example">
<div class="box">
<ul class="mainmenu" :class="current">
<li class="music" v-on:click="current='music'">音乐</li>
<li class="videos" v-on:click="current='videos'">视频</li>
<li class="news" v-on:click="current='news'">新闻</li>
</ul>
<keep-alive>
<component :is="current"></component>
</keep-alive>
</div>
</div>
<script type="text/javascript">
//创建根实例
var vm=new Vue({
el: '#example',
data:{
active:true,
current:'music'
},
//注册局部组件
components:{
music:{
data:fuction(){
return {
subcur:'popular'
}
}
template:'<div class="sub">
<div class="submenu">
<ul :class="subcur">
<li class="popular" v-on:click="subcur='popular'">流行音乐</li>
<li class="national" v-on:click="subcur='national'">民族音乐</li>
<li class="classical" v-on:click="subcur='classical'">古典音乐</li>
</ul>
</div>
<component :is="subcur"></component> //定义动态组件
</div>',
components:{ //注册子组件
popular:{
template:'<div>流行音乐内容</div>'
},
national:{
template:'<div>民族音乐内容</div>'
},
classical:{
template:'<div>古典音乐内容</div>'
}
}
},
videos:{
template:'<div>视频内容</div>'
},
news:{
template:'<div>新闻内容</div>'
}
}
});
</script>
运行上述代码,页面中有音乐、视频、新闻3个类别选项卡,默认显式音乐选项卡下流行音乐栏目的内容;单击古典音乐栏目可以显式对应的内容;单击视频选项卡会显式该选项卡对应的内容。此时单击音乐选项卡,会继续显示之前选择的内容。
4. 常用插件:
如果想用Vue.js开发一个完整的单页Web应用,还需要使用一些Vue.js的插件,比较常用的是vue-route和axios,这两个插件可以分别提供路由管理和数据请求功能。
1)vue-route插件实现路由:
vue-route的作用是将每个路径映射到对应的组件上,并通过路由进行组件之间的切换。
⑴ 基础用法:
Vue.js路由允许通过不同的URL访问不同的内容,通过路由实现组件之间的切换需要使用<router-link>组件,该组件用于设置一个导航链接,通过to属性设置目标地址,从而切换不同的HTML内容。简单的示例代码:
<div id="example">
<p>
<router-link to="/first">页面一</router-link>
<router-link to="/second">页面二</router-link>
<router-link to="/third">页面三</router-link>
</p>
<!--路由出口,路由匹配到的组件渲染位置-->
<router-view></router-view>
</div>
<script type="text/javascript">
//定义路由组件,可以从其他文件import引入
var first={
template:'<div>这是第一个页面</div>'
};
var second={
template:'<div>这是第二个页面</div>'
};
var third={
template:'<div>这是第三个页面</div>'
};
//定义路由,每个路由映射一个组件
var routes=[
{path:'/first', component:first},
{path:'/second', component:second},
{path:'/third', component:third}
];
//创建路由实例,传入routes配置参数
var router=new VueRouter({
routes //相当于routes:routes的缩写
});
//创建并挂载根实例
var app=new Vue({
router
}).$mount('#example');
</script>
上述代码中,router-link会被渲染为<a>标签,比如第1个router-link会被渲染为<a href ="#/first">页面一</a>,当单击第1个router-link对应的标签时,由于to属性的值为/first,因此实际路径地址就是当前URL路径后加上#/first。这时,Vue会找到定义路由routes中path为/first的路由,并将对应的组件模板渲染到<router-view>中。
⑵ 路由动态匹配:
在实际开发中,经常需要将某种模式匹配到的所有路由全部映射到同一个组件,那么可以在vue-router的路由路径中使用动态路径参数来实现。示例代码:
<script type="text/javascript">
var User={
template:'<div>User</div>'
};
var router=new VueRouter({
routes: [ //动态路径参数,以冒号开头
{path: '/user/:id', component: User}
]
});
</script>
上述代码中,:id即为设置的动态路径参数,这时像/user/1、/user/2这样的路径都会映射到相同的组件。当匹配到一个路由时,参数值可以通过this.$route.params的方式获取,并且可以在每个组件内使用。更改上述示例代码为:
<script type="text/javascript">
var User={
template:'<div>用户ID:{{$route.params.id}}</div>'
};
var router=new VueRouter({
routes: [ //动态路径参数,以冒号开头
{path: '/user/:id', component: User}
]
});
</script>
常规路径参数只会匹配被“/”分隔的URL片段中的字符。如果想匹配任意路径,可以使用通配符*。比如,path:'*'会匹配所有路径、path:'/user-*'会匹配以'/user-'开头的任意路径。当使用通配符路由时,需要确保正确的路由顺序,含有通配符的路由应当放在最后。
⑶ 嵌套路由:
有些界面通常是由多层嵌套的组件组合而成,如二级导航菜单,这时就需要使用嵌套路由。一个被渲染的组件的模板同样可以包含嵌套的<router-view>,要在嵌套的出口中渲染组件,需要在VueRouter实例中使用children参数进行配置。示例代码:
<div id="example">
<router-view></router-view>
</div>
<script type="text/javascript">
var User={
template:'<div>用户{{$route.params.id}}</div>'
};
var router=new VueRouter({
routes: [ //动态路径参数,以冒号开头
{path: '/user/:id', component: User}
]
});
</script>
上述代码中,<router-view>是最顶层的出口,它会渲染一个和最高级路由匹配的组件。同样,在组件的内部可以包含嵌套的<router-view>,示例代码:
var User={
template:'<div>
<span>用户{{$route.params.id}}</span>
<router-view></router-view>
</div>'
};
如果要在嵌套的出口中渲染组件,需要在VueRouter中使用children参数进行配置。代码:
var router=new VueRouter({
routes: [
{path: '/user/:id',
component: User,
children:[{
path:'sex',
component:UserSex
},{
path:'age',
component:UserAge
}]
}]
});
需要注意,如果访问一个不存在的路由,则渲染组件的出口不会显示任何内容,这时可以提供一个空的路由。示例代码:
var router=new VueRouter({
routes: [
{path: '/user/:id',
component: User,
children:[{
path:'',
component:UserSex
},{
path:'sex',
component:UserSex
},{
path:'age',
component:UserAge
}]
}]
});
⑷ 命名路由:
在进行路由跳转时,可以为较长的路径设置一个别名。在创建VueRouter实例的时候,在routes配置中可以为某个路由设置名称。示例代码:
var router=new VueRouter({
routes: [
{path: '/user/:id',
name:'user',
component: User
}]
});
在设置了路由的名称后,想要链接到该路径,可以为router-link的to属性传入一个对象。代码为:
<router-link :to="{name:'user',params:{id:1}}">用户</router-link>
这样,当单击“用户”链接时,会将路由导航到/user/1路径。
⑸ 应用push()方法定义导航:
使用<router-link>创建<a>标签可以定义导航链接,除此之外还可以使用router实例的方法push()实现导航的功能。在Vue实例内部可以通过$router访问路由实例,因此通过调用this. $router.push即可实现页面的跳转。
该方法的参数可以是一个字符串路径,或者是一个描述地址的对象,示例代码:
this.$router.push('home');
this.$router.push({path:'home'});
this.$router.push({name:'user'});
this.$router.push({path:'home',query:{id:'2'}});
this.$router.push({path:'user',param:{userId:'1'}});
⑹ 命名视图:
有些页面分为顶部、左侧导航栏和主内容3个部分,这种情况下需要将每个部分定义为一个视图。为了在页面中同时展示多个视图,需要为每个视图router-view进行命名,通过名字进行对应组件的渲染。在界面中可以有多个单独命名的视图,而不是只有一个单独的出口。如果没有为router-view设置名称,那么它的默认名称为default。比如为界面设置3个视图的代码为:
<router-view class="top"></router-view>
<router-view class="left"></router-view>
<router-view class="main"></router-view>
由于一个视图使用一个组件渲染,因此对于同一个路由,多个视图就需要多个组件进行渲染。为上述3个视图应用组件进行渲染的示例代码:
var router=new VueRouter({
routes: [
{path: '/',
components: {
default:Top,
left:Left,
main:Main
}
}]
});
⑺ 重定向:
如果为要访问的路径设置了重定向规则,则访问该路径时会被重定向到指定的路径。重定向也是通过routes配置来完成。比如,设置路径从/a重定向到/b的代码为:
var router=new VueRouter({
routes: [
{path: '/a',redirect:'/b'}
]
});
上述代码中,当用户访问路径/a时,URL中的/a将会被替换为/b,并匹配路由/b,该路由映射的组件将被渲染。
重定向的目标也可以是一个命名的路由,比如将路径/a重定向到名称为user的路由,代码:
var router=new VueRouter({
routes: [
{path: '/a',redirect:{name:'user'}}
]
});
2)应用axios实现Ajax请求:
在实际开发过程中,通常需要和服务器端进行数据交互。Vue.js并未提供与服务器端通信接口,在2.0版本后推荐使用axios来实现Ajax请求。axios是一个基于promise的HTTP客户端。
⑴ GET请求:
使用axios发送GET请求有两种格式,第一种格式为:
axios(options)
采用这种格式需要将发送请求的所有配置选项写在oprions中,示例代码:
axios({
method:'get',
url:'/user',
params:{name:'jack',age:20}
})
第2种格式:
axios.get(url[,options])
其中,url为请求的服务器URL,options为发送请求的配置选项。示例代码:
axios.get('server.php',{
params:{
name:'jack',
age:20
}
])
使用axios无论发送GET请求还是POST请求,在发送请求后都需要使用回调函数对请求的结果进行处理。.then方法用于处理请求成功的回调函数,而.catch方法用于处理请求失败的回调函数。示例代码:
axios.get('server.php',{
params:{
name:'jack',
age:20
}
]).then(function(response){
console.log(response.data);
}).catch(function(error){
console.log(error);
})
这两个回调函数都有各自独立的作用域,直接在函数内部使用this并不能访问到Vue实例。这时。只要在回调函数的后面添加.bind(this)就能解决这个问题。
运行axios代码需要在服务器环境中,否则会抛出异常。
⑵ POST请求:
使用axios发送POST请求也有两种格式,第1种格式为:
axios(options)
采用这种格式需要将发送请求的所有配置选项写在oprions中,示例代码:
axios({
method:'post',
url:'/user',
params:{name:'jack',age:20}
})
第2种格式为:
axios.post(url,data[,options])
其中,url为请求的服务器URL,data为发送的数据,options为发送请求的配置选项。示例代码:
axios.get('server.php','name=jack&age=20')
axios采用POST方式发送数据时,数据传递的方式有多种,最简单的一种是将传递的参数写成URL查询字符串形式,比如'name=jack&age=20'。
5. 单页Web应用:
将多个组件写在同一个文件的方式适用于一些中小型项目,但是在更复杂的项目中就会有很多弊端。为此,Vue.js提供了文件扩展名为.vue的单文件组件,一个.vue文件就是一个组件,而多个组件结合在一起就可以实现单页Web应用。
1)webpack:
webpack是一个前端资源加载和打包工具,它可以将各种资源,比如JS、CSS、图片等,按照一定规则进行打包处理,从而形式对应的静态资源。
⑴ 安装webpack:
要安装webpack,首先需要安装node.js,然后使用npm命令进行全局安装:
npm install webpack webpack-cli -g
然后在指定路径下创建项目文件夹,在命令窗口中将当前路径切换到创建的项目文件夹,使用npm命令初始化项目:
npm init
对webpack进行本地安装:
npm install webpack --save-dev
⑵ webpack基本使用:
使用webpack需要一个入口文件,其他为依赖文件。在项目文件夹中创建一个entry.js入口文件和一个html依赖文件,在命令行输入命令:
webpack entry.js -o bundle.js --mode=development
这时会编译entry.js文件生成bundle.js。
在项目文件夹下创建另一个js文件module.js,代码为:
module.exports="欢迎访问本网站"; //指定对外接口
对entry.js文件进行修改,并基于CommonJS规范引用module.js,代码为:
var str=require("./module.js"); //引入module.js文件
document.write(str);
再次使用webpack打包处理。
webpack从入口文件开始对依赖文件进行打包,并会解析依赖的文件,然后将内容输出到bundle.js文件中。
2)loader:
loader是基于webpack的加载器。因为webpack本身只能处理JavaScript模块,如果要处理其他资源就需要使用loader进行转换。
⑴ 加载CSS:
要在应用中添加CSS文件,需要使用css-loader和style-loader,css-loader用于加载CSS文件,style-loader用于将原来的CSS代码插入页面的<style>标签中。安装命令:
npm install css-loader style-loader --save-dev
如果项目中有一个style.css文件,需要改写entry.js代码加载:
require("!style-loader!css-loader./style.css");
var str=require("./module.js");
document.write(str);
⑵ 加载图片文件:
应用中加载图片需要使用file-loader加载器,安装使用命令:
npm install file-loader --save-dev
⑶ webpack配置文件:
在应用webpack进行打包操作时,除了使用命令行,还可以通过指定的配置文件来执行。将一些编译选项放在一个配置文件中,便于集中管理。在项目根目录下不传入参数,直接调用webpack.config.js,该文件中的配置选项需要通过module.exports导出,格式:
module.exports={
//配置选项
}
常用配置选项有mode、entry、output、module、plugins等。
配置文件示例:
var HtmlWebpackPlugin=require('html-webpack-plugin');
module.exports={
mode: 'development',
entry:'./entry.js', //设置入口文件
output:{
path:__dirname+'/dist', //_dirname用于获取当前文件绝对路径
filename:'bundle.js' //设置输出文件名
},
//加载器配置
module:{
rules: [
{
test:/\.css$/, //匹配CSS文件
loader:'style-loader!css-loader'
},
{
test:/\.(jpg|png|gif)$/, //匹配图片文件
loader:'file-loader',
optopns:{
name:'[path][name].[ext]' //生成的路径和文件名
}
}
]
},
//插件配置
plugins:[
new HtmlWebpackPlugin() //使用插件
]
};
webpack会首先处理入口文件,将其所包含的依赖文件进行编译,再合并成一个JavaScript文件输出到output选项设置的路径中,然后应用HtmlWebpackPlugin插件将该文件通过<script>标签插入到HTML文件中,最终生成静态文件index.html和bundle.js文件。
3)单文件组件:
有了webpack和loader后,可以将一个组件的HTML、JavaScript和CSS应用各自的标签写在一个文件中,文件的扩展名为vue。这样的文件即为单文件组件。在应用中处理vue文件需要使用vue-loader加载器和vue-template-compiler工具。
4)构建项目:
使用Vue.js开发较大的应用时,可以使用@vue/cli工具快速构建项目。
6. 状态管理:
在Vue.js的组件开发中,经常会遇到需要将当前组件的状态传递给其他组件的情况。父子组件之间进行通信时,通常会采用Props的方式实现数据传递,而在一些比较大的应用中,单页面会包含大量组件,数据结构也比较复杂。当通信双方不是父子组件甚至不存在任何联系时,需要将状态共享给多个组件就会变得非常麻烦,就需要引入状态管理设计模式。Vuex就是一个专为Vue.js设计的状态管理模式。