这里写目录标题
全局API
全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,比如自定义指令Vue.directive。说的简单些就是,在构造器外部用Vue提供给我们的API函数来定义新的功能。
1.Vue.directive自定义指令
关于Vue内部指令的文章可以戳这里👉Vue内部指令,当然我们也可以自定义一些指令,自定义它的功能。比如我要自定义一个v-yyz
的指令,功能是让字体颜色变成蓝色:
...
<div v-yyz="color">{{number}}</div>
...
Vue.directive("yyz",function(el,binding){
console.log(el);
console.log(binding);
console.log(binding.name);//输出"yyz"
console.log(binding.value);//输出"blue"
console.log(binding.expression);//输出"color"
el.style="color:"+binding.value;
})
...
data:{
number:10,
color:"blue"
},
...
其中函数的参数中,el是指令所在的DOM元素(在这里就是
<div v-yyz="color"></div>
),binding是一个对象类型的元素。
另外,自定义指令有五个生命周期(也叫钩子函数),分别是 bind(),inserted(),update(),componentUpdated(),unbind()。它们的作用及含义如下:
bind()
:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。inserted()
:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。update()
:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。componentUpdated()
:被绑定元素所在模板完成一次更新周期时调用。unbind()
:只调用一次,指令与元素解绑时调用。
示例代码如下(相比较于上面就是把function(el,binding)
改写成了五个生命周期函数):
...
<div id="app">
<div v-yyz="color">{{number}}</div>
<p><button @click="add">ADD</button></p>
</div>
<p>
<button onclick="unbind()">解绑</button>
</p>
...
function unbind(){
app.$destroy();
}
Vue.directive("yyz",{
bind:function(el,binding){//被绑定
console.log('1 - bind');
el.style="color:"+binding.value;
},
inserted:function(){//绑定到节点
console.log('2 - inserted');
},
update:function(){//组件更新
console.log('3 - update');
},
componentUpdated:function(){//组件更新完成
console.log('4 - componentUpdated');
},
unbind:function(){//解绑
console.log('5 - unbind');
}
}
)
...
要注意解绑的方法
unbind(){app.$destroy();}
,解绑之后点击ADD无法再做到+1
页面效果如下图所示:
2.Vue.extend构造器的延伸
示例代码:
<body>
<h1>vue_extend</h1>
<hr>
<author></author>
<script type="text/javascript">
var authorExtend = Vue.extend({
//template就是模板的意思,这里绑定标签中的属性值需要用到v-bind指令
template:"<p><a v-bind:href='authorUrl'>{{authorName}}</a></p>",
//这里的data不是传统的构造器,所以不能直接大括号写数据
data:function(){
return {
authorName:"yyz",
authorUrl:"http://www.baidu.com"
}
}
});
//把自定义的构造器挂载到自定义的DOM中去
new authorExtend().$mount("author");
</script>
</body>
页面实现效果就是:<p><a href='http://www.baidu.com'>yyz</a></p>
这段代码在页面上的显示效果。
3.Vue.set全局操作
Vue.set
的作用就是在构造器外部操作构造器内部的数据、属性或者方法。比如在vue构造器内部定义了一个count
为1的数据,我们在构造器外部定义了一个方法,要每次点击按钮改变count
的值.就需要用到Vue.set。
<body>
<h1>vue_set</h1>
<hr>
<div id="app">
{{count}}
</div>
<p><button onclick="add()">ADD</button></p>
<script type="text/javascript">
function add() {
//方法一:每次点击把outDate中的count值设为2
Vue.set(outDate,'count',2);
//方法二:点击按钮+1
//app.count++;
//方法三:点击按钮+1
//outDate.count++;
}
var outDate={
count:1,
goods:'basketball'
}
var app = new Vue({
el:'#app',
data:outDate
})
</script>
</body>
上面代码中的
outDate
就是外部数据(对象),就是不在Vue构造器里里的data处声明,而是在构造器外部声明,然后在data处引用。外部数据的加入让程序更加灵活,我们可以在外部获取任何想要的数据形式,然后让data引用。
但是当我们呢的数据是数组时,如果用下标索引的方法来改变数组中的某个值,Vue.js
是无法检测到的。必须使用Vue.set()
。注意这并不是Vue的缺陷,而是Javascript本身的限制。例如:
在outDate中新增一个数组数据:
arr:['SC','KT','KD']
在页面上增加显示数组数据的循环:
<div id="app">
{{count}}
<ul>
<li v-for="item in arr">{{item}}</li>
</ul>
</div>
如果在add()方法中只有:
//改变数组的值
app.arr[1]="AI";
在点击按钮之后是不会发生改变的。因为用数组下标监测不到数据更新。因此只能用Vue.set()
:
//两句二选一即可
Vue.set(app.arr,1,"LBJ");
Vue.set(outDate.arr,1,"LBJ");
4.生命周期(钩子函数)
Vue一共有10个生命周期函数,我们可以项目运行的过程中在每个函数中进行数据或事件的操作。Vue官网给的生命周期流程图如下:
示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue生命周期</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>Vue生命周期</h1>
<hr>
<div id="app">
{{count}}
<p><button @click="add">ADD</button></p>
</div>
<p><button onclick="app.$destroy()">destroy</button></p>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
count:1
},
methods:{
add:function(){
this.count++;
}
},
beforeCreate:function(){
console.log('1-beforeCreate 初始化之前');
},
created:function(){
console.log('2-created 创建完成');
},
beforeMount:function(){
console.log('3-beforeMount 挂载之前');
},
mounted:function(){
console.log('4-mounted 被创建');
},
beforeUpdate:function(){
console.log('5-beforeUpdate 数据更新前');
},
updated:function(){
console.log('6-updated 被更新后');
},
activated:function(){
console.log('7-activated');
},
deactivated:function(){
console.log('8-deactivated');
},
beforeDestroy:function(){
console.log('9-beforeDestroy 销毁之前');
},
destroyed:function(){
console.log('10-destroyed 销毁之后')
}
})
</script>
</body>
</html>
5.Template制作模板
Template模板有三种写法:
1.直接在构造器中添加template选项增加模板
var app = new Vue({
el:'#app',
data:{
message:'hello world'
},
template:`
<h2 style="color:red;">我是选项模板</h2>
`
})
2.写在template标签里的模板
<template id="dd2">
<h2 style="color:red;">我是Template标签模板</h2>
</template>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
message:'hello world'
},
//方法二:在template标签里写
template:"#dd2"
})
</script>
3.写在script标签里的模板
这种写模板的方法,可以从外部引入模板文件。
<script type="x-template" id="dd3">
<h2 style="color:red;">我是script标签模板</h2>
</script>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
message:'hello world'
},
template:"#dd3"
})
</script>
6.Component组件
component组件是Vue学习的重点。所以你必须学好Vue component。组件就是制作自定义的标签,这些标签在HTML中所没有的。
1.全局组件
全局组件就是在构造器的外面通过Vue.component
来自定义组件,但是在使用时必须放在Vue的作用域内。
<div id="app">
//在HTML中调用了他,并且它可以放到多个构造器的作用域里
<sc></sc>
</div>
//下面这行自定义组件不会显示对应的信息,因为它不在Vue的作用域内
<sc></sc>
<script type="text/javascript">
//在javascript里注册了一个组件
Vue.component('sc',{
template:`<div style="color:red">我是全局组件sc</div>`
})
var app = new Vue({
el:'#app',
})
</script>
2.局部组件
局部组件只能在自己的作用域中进行调用而不能被其它作用域调用。一般在作用域内部进行定义。
<div id="app">
<sc></sc>//<sc></sc>是全局组件,在app和ppa这两个作用域中都能被调用
<panda></panda>// <panda></panda>是局部组件,只能在app这个作用域中被调用
</div>
<div id="ppa">
<sc></sc>
<panda></panda>
</div>
<sc></sc>//这个全局组件无法调用因为它不在任何一个作用域内
<script type="text/javascript">
Vue.component('sc',{
template:`
<div style="color:red">我是全局组件sc</div>
`
})
var app = new Vue({
el:'#app',
components:{
"panda":{
template:`<div style="color:blue">我是局部组件panda</div>`
}
}
})
var ppa = new Vue({
el:'#ppa',
})
</script>
7.Component组件props属性的设置
props选项就是设置和获取标签上的属性值的,例如:
<div id="app">
<panda where="China"></panda>
</div>
<script type="text/javascript">
var app = new Vue({
el:'#app',
components:{
"panda":{
template:`<div style="color:blue">panda from {{where}}</div>`,
props:['where']
}
}
})
</script>
另外,注意当传入的参数属性名带有像
-
等一些符号时,Vue是无法识别的,这时候需要把原来的from-where
改写成小驼峰的写法:fromWhere
。
当数据where来自于构造器中的data时,就需要用到内部指令中的绑定指令v-bind
,代码如下:
<div id="app">
<panda v-bind:where="messgae"></panda>
</div>
<script type="text/javascript">
var app = new Vue({
el:'#app',
data:{
messgae:"China"
},
components:{
"panda":{
template:`<div style="color:blue">panda from {{where}}</div>`,
props:['where']
}
}
})
</script>
8.Component父子组件的关系
1.组件信息外移
首先要学会把定义在构造器内部的组件信息放到构造器外部,因为一旦组件代码比较多的话,构造器的可读性就会很差。
首先需要先声明一个对象,对象里就是组件的内容:
var pandaComponent = {
template:`<div style="color:red">Panda from China</div>`
}
当然你还可以在另一个文件中声明,然后在通过src引入进来。
然后再构造器的内部只需呀引入这个对象就可以了:
var app = new Vue({
el:'#app',
components:{
"panda":pandaComponent
}
})
2.父子组件的嵌套
父组件是pandaComponent
,子组件是city
,代码如下:
<script type="text/javascript">
var city = {
template:`<div style="color:orange">中国四川</div>`
}
var pandaComponent = {
template:`
<div>
<p style="color:red">Panda from China</p>
<city></city>
</div>
`,
components:{
"city":city
}
}
var app = new Vue({
el:'#app',
components:{
"panda":pandaComponent
}
})
</script>
要注意,声明city子组件这个步骤要放在父组件调用子组件之前,也就是必须先注册再调用,否则会报错提示没有注册。并且,在父组件中,也得先通过
components
引入子组件再调用。
9.Component标签
<component></component>
是Vue框架自定义的一个标签,它可以根据数据的不同动态地绑定组件
例如现在声明三个不同的组件:
var componentA = {
template:`<div style="color:red">I am componentA</div>`
}
var componentB = {
template:`<div style="color:green">I am componentB</div>`
}
var componentC = {
template:`<div style="color:pink">I am componentC</div>`
}
然后将这三个组件挂载到页面中:
var app = new Vue({
el:'#app',
data:{
who:"componentA"
},
components:{
"componentA":componentA,
"componentB":componentB,
"componentC":componentC
}
})
当我们在页面中定义<component></component>
标签时,并用v-bind
绑定一个属性who
:
<div id="app">
<component v-bind:is="who"></component>
</div>
因为在data中设置了who
的值为componentA
,因此最后显示到页面中的就是componentA
组件。另外,我们还可以在<component></component>
下添加一个点击更换组件的按钮,并绑定方法:
<component v-bind:is="who"></component>
<button @click="changeComponent">changeComponent</button>
然后再构造器里定义方法:
methods:{
changeComponent:function(){
if(this.who=="componentA"){
this.who="componentB";
}else if(this.who=="componentB") {
this.who="componentC";
}else {
this.who="componentA";
}
}
}
最终实现的效果就是通过点击按钮能够再三个组件之间来回切换。