一、vue的核心思想
组件化
组件化的目的是扩展HTML元素,封装可重用的代码。
组件:独立的,可复用性的,整体化的。
组件设计原则
1、页面上每个独立的可视,可交互的区域视为一个组件,比如页面的头部,尾部,还有一些可以复用的区块,都可以抽象成一个组件。
2、每个组件对应一个工程目录,组件所需要的各种资源在这个目录下就近维护。
3、页面不过是组件的容器,组件可以嵌套自由组合形成完整的页面。开发过程中,会将页面拆分成一个个组件,进行开发维护。
二、vue中的插槽
slot标签显示的内容就是父组件向子组件插入进来的内容。
通过插槽可以更方便的向子组件传递dom元素,同时子组件只需要通过slot来使用就可以了。
<div id="root">
<child>
<p>Dell</p> //这种语法看起来非常像,用子组件,我向里插入内容
</child>
</div>
Vue.component('child', {
props: {
content:String
},
template: `<div>
<p>hello</p>
<slot></slot> //slot 标签显示的内容就是父组件向子组件插入进来的内容
</div>`,
})
let vm = new Vue({
el: '#root'
})
具名插槽
slot标签name属性对应的是组件中slot属性,通过这种写法,可以在调用子组件时,一次性传递多个区域的dom结构,在子组件里通过具名插槽来分别使用不同部分的dom结构。
<div id="root">
<body-content>
<div class="header" slot="header">header</div>
<div class="footer" slot="footer">footer</div>
</body-content>
</div>
Vue.component('body-content', {
props: {
content:String
},
template: `<div>
<slot name="header"></slot>
<div class="content">content</p>
<slot name="footer"></slot>
</div>`,
})
let vm = new Vue({
el: '#root'
})
三、模块化与组件化的区别
(1)组件化更多关注的是UI部分,页面的每个部分,比如头部,内容区,弹出框甚至确认按钮都可以成为一个组件,每个组件有独立的html、css、js代码。
可以根据需要把它放在页面的任意部位,也可以和其他组件一起形成新的组件。一个页面是各个组件的结合,可以根据需要进行组装。
(2)模块化更侧重于功能的封装,主要是针对Javascript代码,隔离、组织复制的JavaScript代码,将它封装成一个个具有特定功能的模块。
模块可以通过传递参数的不同修改这个功能的相关配置,每个模块都有一个单独的作用域,根据需要调用。
一个模块的实现可以依赖其它模块。
四、vue的自定义指令
1、使用Vue.directive()定义全局的指令
(1)参数1是指令的名称;
注:在定义的时候,指令的名称前面,不需要加v-前缀了,在调用的时候,必须在指令名称前面加上v-前缀来进行调用。
(2)参数2是一个对象,在这个对象上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作。
一个指定定义对象可以提供如下几个钩子函数:
bind:只调用一次,指定第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。指令的值可能发生个改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
componentUpdated:指令所在组件的VNode及其子VNode全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
<input type="text" v-model="keywords" v-focus class="form-control">
Vue.directive('focus',{
bind:function(el){//每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
//注意:在每个函数中第一个参数,永远是el,表示被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
//在元素刚绑定了指令的时候,还没有插入到DOM中去,这时调用 focus 方法么有作用
//因为,一个元素,只有插入DOM之后,才能获取焦点
//el.focus()
},
inserted:function(el){//元素插入到DOM中的时候,会执行inserted函数[触发一次]
el.focus()
},
updated:function(){// 当VNode 更新的时候,会执行 updated,可能会触发多次。
}
})
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
});
2、定义调用时可传参的指令
使用钩子函数的第二个binding参数拿到传递的值。
定义:
Vue.directive('color',{ bind:function(el,binding){ el.style.color = binding.value; }, })
使用:
<h3 v-color="'orange'">~~{{msg}}</h3>
## binding对象包含以下属性:
name:指令名,不包括v-前缀。
value:指令的绑定值,例如:v-my-directive="1+1",varlue的值是2。
oldValue:指令绑定的前一个值,仅在update和componentUpdated钩子中使用。无论值是否改变都可用。
expression:绑定值的字符串形式。例如:v-my-directive="1+1",expression的值是"1+1"。
arg:传给指令的参数。例如:v-my-directive:foo,arg的值是“foo”。
3、自定义私有指令
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="../css/bootstrap.css">
</head>
<body>
<div id='app'>
<h3 v-fontweight="'900'" v-fontsize="'40px'">~~{{msg}}</h3>
</div>
</body>
<script src="../lib/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:"欢迎学习Vue"
},
methods:{
},
//自定义私有指令
directives:{
'fontweight':{
bind:function(el,binding){
el.style.fontWeight = binding.value
}
},
//指令函数的简写形式。
//注意,这个 function 等同于把代码写到了 bind和 update中
'fontsize':function(el,binding){
el.style.fontSize = parseInt(binding.value)+'px'
}
}
});
</script>
</html>