文章目录
Vue.directive
Vue.directive("changecolor",function(el,binding){//Vue需要大写,自定义指令不能有大写字母,自定义指令此处写法需要去掉v-前缀
console.log(el);//el是传入的div对象
console.log(binding);//binding是一个属性
// 比如这个实例中
// name: "changecolor"
// rawName: "v-changecolor"
// value: "red"
// expression: "color"
// modifiers: {}
// def: {bind: ƒ, update: ƒ}
// __proto__: Object
console.log(binding.value);
el.style ="color:"+binding.value;
});
binding对象
binding是一个对象,包含以下属性:
(1)name:指令名,不包括 v- 前缀。
(2)value:指令的绑定值,例如:v-my-directive=”1 + 1”, value 的值是 2。
(3)oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
(4)expression:绑定值的字符串形式。例如 v-my-directive=”1 + 1” ,expression 的值是 “1 + 1”。
(5)arg:传给指令的参数。例如 v-my-directive:foo,arg 的值是 “foo”。
(6)modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
自定义指令的生命周期函数
Vue.directive("changecolor",{
bind:function(){
console.log('a-bind');
console.log('a-num:'+this.num);
},
inserted:function(){
console.log('b-inserted');
console.log('b-num:'+this.num);
},
updated:function(){
console.log('c-updated');
console.log('c-num:'+this.num);
},
componentUpdated:function(){
console.log('d-componentUpdated');
console.log('d-num:'+this.num);
},
unbind:function(){
console.log('e-unbind');
console.log('e-num:'+this.num);
}
})
包含Vue生命周期钩子函数的实例测试图
Vue.extend构造器的延伸
使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数
Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器。
经常服务于Vue.component用来生成组件,
可以简单理解为当在模板中遇到该组件名称作为标签的自定义元素时,
会自动调用“扩展实例构造器”来生产组件实例,并挂载到自定义元素上。
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.extend 构造器的延伸</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.extend 构造器的延伸</h1>
<!--构造器的延伸:
组件也是类似的写法
所以一般建议以id形式写
-->
<blog></blog>
<div id="blog"></div>
<hr>
<script type="text/javascript">
var blogURL = Vue.extend({
template:"<p><a :href='blogURL'>{{blogName}}</a></p>",//注意href前面还有个冒号 v-bind 指令被用来响应地更新 HTML 属性
data:function(){
return{
blogName:'Kacey的博客',
blogURL:"https://blog.youkuaiyun.com/DUT_Walnut"
};
}
});
//创建 blogURL 实例,并挂载到一个元素上。
new blogURL().$mount("blog");//对应组件式写法
new blogURL().$mount("#blog");//对应id式写法
</script>
</body>
</html>
Vue.set
向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = ‘hi’)
Vue.set 的作用就是在构造器外部操作构造器内部的数据、属性或者方法。
比如在vue构造器内部定义了一个count为1的数据,
我们在构造器外部定义了一个方法,要每次点击按钮给值加1.就需要用到Vue.set。
Vue.set存在意义
当你利用索引直接设置一个项时,vue不会为我们自动更新。
当你修改数组的长度时,vue不会为我们自动更新
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue.set 全局操作</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>Vue.set 全局操作</h1>
<div id="test">
<p>{{count}}</p>
<br>
<p>Vue.set用于数组</p>
<br>
<ul>
<li v-for="ele in arr">{{ele}}</li>
</ul>
<button onclick="add()">Add</button>
<hr>
</div>
<script type="text/javascript">
var outData = {
count:1,
pet:'cat',
arr:['aa','bb','cc']
}
function add(){
//用Vue.set改变
Vue.set(outData,'count',2);
//用Vue对象的方法添加
app.count++;
//直接操作外部数据
outData.count++;
//用于数组元素值改变的Vue.set
Vue.set(app.arr,0,'ddd');
}
var app = new Vue({
el:'#test', //与div id相对应
data:outData
})
</script>
</body>
</html>
Vue生命周期
钩子函数
函数名 | 详细 | 注释 |
---|---|---|
beforeCreate | 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。 | |
created | 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前尚不可用。 | |
beforeMount | 在挂载开始之前被调用:相关的 render 函数首次被调用。 | 该钩子在服务器端渲染期间不被调用。 |
mounted | 实例被挂载后调用,这时 el 被新创建的 vm.$el 替换了。 如果根实例挂载到了一个文档内的元素上,当mounted 被调用时vm.$el 也在文档内。 注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick | 该钩子在服务器端渲染期间不被调用。 |
beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。 | 该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。 |
updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性 或 watcher 取而代之 . 注意 updated **不会*保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick | 该钩子在服务器端渲染期间不被调用。 |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。 | 该钩子在服务器端渲染期间不被调用 |
destroyed | 实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 | 该钩子在服务器端渲染期间不被调用 |
errorCaptured | 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。 |
代码展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.directive 自定义指令</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.directive 自定义指令</h1>
<div id="test">
<div v-changecolor="color">
{{num}}
</div>
<button @click="add">Add</button>
<button onclick="unbind()">解绑</button>
</div>
<hr>
<script type="text/javascript">
function unbind(){
app.$destroy();
}
/*
Vue.directive("changecolor",function(el,binding){//Vue需要大写,自定义指令不能有大写字母,自定义指令此处写法需要去掉v-前缀
console.log(el);//el是传入的div对象
console.log(binding);//binding是一个属性
一个对象,包含以下属性:
(1)name:指令名,不包括 v- 前缀。
(2)value:指令的绑定值,例如:v-my-directive=”1 + 1”, value 的值是 2。
(3)oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
(4)expression:绑定值的字符串形式。例如 v-my-directive=”1 + 1” ,expression 的值是 “1 + 1”。
(5)arg:传给指令的参数。例如 v-my-directive:foo,arg 的值是 “foo”。
(6)modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
// 比如这个实例中
// name: "changecolor"
// rawName: "v-changecolor"
// value: "red"
// expression: "color"
// modifiers: {}
// def: {bind: ƒ, update: ƒ}
// __proto__: Object
console.log(binding.value);
el.style ="color:"+binding.value;
});
*/
Vue.directive("changecolor",{
bind:function(){
console.log('a-bind');
console.log('a-num:'+this.num);
},
inserted:function(){
console.log('b-inserted');
console.log('b-num:'+this.num);
},
updated:function(){
console.log('c-updated');
console.log('c-num:'+this.num);
},
componentUpdated:function(){
console.log('d-componentUpdated');
console.log('d-num:'+this.num);
},
unbind:function(){
console.log('e-unbind');
console.log('e-num:'+this.num);
}
})
var app = new Vue({
el:'#test', //与div id相对应
data:{
num:'0',
color:'red'
},
beforeCreate:function(){
console.log('0-beforeCreate');
console.log('0-num:'+this.num);
},
created: function () {
console.log('1-created');
console.log('1-num:'+this.num);
},
beforeMount:function(){
console.log('0-beforeMount');
console.log('3-num:'+this.num);
},
mounted: function () {
console.log('4-mounted');
console.log('4-num:'+this.num);
},
beforeUpdate:function(){
console.log('5-beforeUpdate');
console.log('5-num:'+this.num);
},
updated: function () {
console.log('6-updated');
console.log('6-num:'+this.num);
},
beforeDestroy:function(){
console.log('7-beforeDestroy');
console.log('7-num:'+this.num);
},
destroyed:function(){
console.log('8-destroyed');
console.log('8-num:'+this.num);
},
methods:{
add:function(){
this.num++;
}
}
})
</script>
</body>
</html>
Template制作模板
直接写在选项里的模板
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'Hello World!'
},
template:`
<h1 style="color:red">我是选项模板</h1>
`
})
写在template标签里的模板
<template id="demo">
<h2 style="color:green">我是template模板</h2>
</template>
写在script标签里的模板
<script type="x-template" id="demo2">
<h2 style="color:red">我script模板</h2>
</script>
compenet入门
全局化注册组件
编写的标签必须放在有Vue实例对应的div里面才会生效
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.component入门</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.component入门</h1>
<div id="test">
<blog></blog>
</div>
<div id="demo">
<blog></blog>
</div>
<hr>
<script type="text/javascript">
Vue.component('blog',{
template:`<div style="color:red">我是全局component模板</div>`
})
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'Hello World!'
}
})
var ppap = new Vue({
el:'#demo', //与div id相对应
data:{
message:'Hello World!'
}
})
</script>
</body>
</html>
局部化注册组件
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'Hello World!'
},
components:{//局部构造里是components,全局注册是Vue.component
"part":{
template:`<div style="color:blue">我是局部component组件part标签</div>`
}
}
})
<div id="test">
<blog></blog>
<part></part>
</div>
component props
props选项就是设置和获取标签上的属性值的
定义属性并获取属性值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.component props</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.componen props</h1>
<div id="test">
<blog base="优快云"></blog>
</div>
<hr>
<script type="text/javascript">
Vue.component('blog',{
template:`<div style="color:red">我是全局component组件blog标签,base:{{base}}</div>`,
props:['base']
})
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'Hello World!'
},
components:{
"part":{
template:`<div style="color:blue">我是局部component组件part标签</div>`
}
}
})
</script>
</body>
</html>
属性中带’-'的处理方式
比如base-web,在props挂载和输出时必须用小驼峰式写法props:[‘baseWeb’]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.component props</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.componen props</h1>
<div id="test">
<blog base-web="优快云"></blog>
</div>
<hr>
<script type="text/javascript">
Vue.component('blog',{
template:`<div style="color:red">我是全局component组件blog标签,base:{{baseWeb}}</div>`,
props:['baseWeb']
})
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'Hello World!'
},
components:{
"part":{
template:`<div style="color:blue">我是局部component组件part标签</div>`
}
}
})
</script>
</body>
</html>
在构造器里向组件传值
用v-bind
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.component props</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.componen props</h1>
<div id="test">
<blog :base-web="message"></blog>
</div>
<hr>
<script type="text/javascript">
Vue.component('blog',{
template:`<div style="color:red">我是全局component组件blog标签,base:{{baseWeb}}</div>`,
props:['baseWeb']
})
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'优快云!'
},
components:{
"part":{
template:`<div style="color:blue">我是局部component组件part标签</div>`
}
}
})
</script>
</body>
</html>
component组件父子关系
在构造器外写局部组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.component nesting</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.component nesting</h1>
<div id="test">
<blog></blog>
</div>
<hr>
<script type="text/javascript">
var blogComponent = {
template:`<div style="color:blue">我是构造器外局部组件blog标签</div>`
}
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'优快云!'
},
components:{
"blog":blogComponent
}
})
</script>
</body>
</html>
父子组件的嵌套
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue.component props</title>
<script type="text/javascript" src="../assets/js/vue.js"></script>
</head>
<body>
<h1>vue.component nesting</h1>
<div id="test">
<blog></blog>
</div>
<hr>
<script type="text/javascript">
//渲染有顺序,所以被引用的应该先声明
var blogName = {
template:`<div style="color:red">我是构造器外局部组件blogName标签</div>`
}
var blogComponent = {
template:`<div style="color:blue">
<p>我是构造器外局部组件blog标签</p>
<blogName></blogName>
</div>`,
components:{
"blogName":blogName
}
}
var app = new Vue({
el:'#test', //与div id相对应
data:{
message:'优快云!'
},
components:{
"blog":blogComponent
}
})
</script>
</body>
</html>
component标签
实例:根据数据不同更换不同组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>component 标签</title>
</head>
<body>
<h1>component 标签</h1>
<hr>
<div id="app">
<component v-bind:is="who"></component>
<button @click="changeComponent">changeComponent</button>
</div>
<script type="text/javascript">
var componentA={
template:`<div style="color:red;">I'm componentA</div>`
}
var componentB={
template:`<div style="color:green;">I'm componentB</div>`
}
var componentC={
template:`<div style="color:pink;">I'm componentC</div>`
}
var app=new Vue({
el:'#app',
data:{
who:'componentA',
arr:["componentA","componentB","componentC"]
},
components:{
"componentA":componentA,
"componentB":componentB,
"componentC":componentC,
},
methods:{
changeComponent:function(){
// console.log("start");
// for(ele of this.arr){
// console.log(ele);
// this.who = ele;
// }
if(this.who=='componentA'){
this.who='componentB';
}else if(this.who=='componentB'){
this.who='componentC';
}else{
this.who='componentA';
}
}
}
})
</script>
</body>
</html>