vue除了提供了核心的一些指令,还允许注册自定义指令。
// 注册自定义指令
// 参数1,指令名称 参数2:配置参数
Vue.directive('focus', {
// 钩子函数比较多,用的比较多的是 bind 和 update
// 只会调用一次,当指令绑定到当前元素上时调用
bind (el) {
},
// 当前元素被插入到父节点的时候调用(渲染时)
inserted (el) {
el.focus()
},
// 当指令对应的数据发生改变的时候
update () {
},
// 所有的DOM都更新之后
componentUpdated () {
},
// 指令与元素解绑的时候
unbind () {
}
})
所有的钩子函数两个参数el
和binding
el: 当前元素
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
<script>
// 定义指定
Vue.directive('focus', {
// 5个钩子函数,并不是都需要写
// 每一个钩子函数中,还有2个参数
//el:当前元素
//binding:一个对象
bind: function () {
console.log('当指令与元素绑定的时候执行,此时还没显示到页面')
},
inserted: function (el) {
console.log('当前元素插入到父元素中的,触发')
el.focus()
},
update: function () {
console.log('当指令的值发生改变的时候执行')
}
})
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue'
}
})
</script>
<script>
Vue.directive('focus', {
inserted(el, binding) {
console.log('el', el)
/*
binding参数的值
name: 指令的名称 不带 v-
value: 指令对应的值
arg: 指令的参数
modifiers: 指令的修饰符 可以有多个
*/
console.log('binding', binding)
}
})
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue'
}
})
</script>
<script>
/*
v-text: 功能
设置当前元素的innerText的值
*/
Vue.directive('cctext', {
// 一来就设置当前元素的innerText值
bind(el, binding) {
el.innerText = binding.value
},
// 当msg发生了改变,修改innerText的值
update(el, binding) {
el.innerText = binding.value
}
})
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue'
}
})
</script>
<script>
// 自定义 v-mybind指令
// v-bind:src = 'imgUrl'
// 给src属性设置值 imgUrl对应的值
Vue.directive('mybind', {
bind(el, binding) {
// binding.name: 指令的名字
// binding.value: 指令的值imgUrl
// binding.arg: 指令的参数src
// binding.modifiers: 指令的修饰符
el.setAttribute(binding.arg, binding.value)
},
update(el, binding) {
el.setAttribute(binding.arg, binding.value)
}
})
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue',
imgUrl: '01.gif'
}
})
</script>
<script>
Vue.directive('myon', {
/*
v-on:
给当前元素注册对应的事件
*/
bind(el, binding) {
el.addEventListener(binding.arg, function (e) {
// 现在可以在function内部增加很多的逻辑
binding.value()
// 判断是否有modifiers.prevent
if (binding.modifiers.prevent) {
e.preventDefault()
}
if (binding.modifiers.stop) {
e.stopPropagation()
}
})
},
update(el, binding) {
el.addEventListener(binding.arg, binding.value)
}
})
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue'
},
methods: {
clickFn() {
console.log('哈哈')
}
}
})
</script>
<script>
// 全局自定义指令, 自定义指令可以在所有的vm实例中都使用
// Vue.directive('color', function (el, binding) {
// el.style.color = binding.value
// })
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue'
},
// data methods filters watch computed
// 局部指令, 只能在当前实例中使用
directives: {
color: function (el, binding) {
el.style.color = binding.value
}
}
})
</script>
组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。
在vue中都是组件化开发的,组件化开发就是把一个完整的页面分割成一个一个的小组件。
<div id="app">
<!-- 使用组件 -->
<hello></hello>
</div>
<script src="vue.js"></script>
<script>// 定义全局组件
// 参数1: 组件名
//
参数2: 组件的配置项
Vue.component('hello', {
// 组件的template中,必须保证只有一个根元素
template: '' +
'大家好,我是hello组件
' +
'我是另一个p标签
' +
''
})
var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue'
}
})
</script>
//在vue实例的内部,通过components属性来定义局部组件
components: {
"my-button": {
template: `
我是一个标题
我是一个段落
`
}
}
注意:
因为组件是一个独立的个体,组件无法使用到外部的数据
但是在真实开发中,多个组件之间是需要相互使用彼此的数据的,因此需要使用组件通讯的技术,让组件之间能够相互传值。
组件通讯分为三类
1. 在父组件的模版中,给子组件增加一个自定义的属性。
<son :car="car"></son>
2. 子组件通过props属性进行接收
//接收父组件传递过来的值
props: ['car']
3. 子组件使用父组件传递过来的值
template: `
这是子组件
这是父组件传递过来的值----{{car}}
`,
注意:props负责获取父组件的传递过来的,props中的值是只读的,不允许修改
1. 父组件给子组件注册一个自定义事件
2. 子组件触发这个自定义事件,触发事件时把数据传递给父组件
<son @fn='getData'></son>
methods: {
//1. 父组件中定义了一个方法,用于获取数据
getData () {
console.log("父组件中提供的方法");
}
}
//$emit可以出发当前实例的事件
this.$emit('getData', this.car);
methods: {
//1. 父组件中定义了一个方法,用于获取数据
getData (skill) {
console.log("父组件中提供的方法", skill);
this.skill = skill;
}
}
非父子组件之间通过一个空的Vue实例来传递数据。
const bus = new Vue(); //bus:公交车 事件总线
组件A给组件B传值:
1. 组件A给bus注册一个事件,监听事件的处理程序
2. 组件B触发bus上对应的事件,把 值当成参数来传递
3. 组件A通过事件处理程序获取数据
//rose在组件创建的时候,给bus注册了一个事件
created () {
bus.$on("get", (msg)=>{
console.log("这是rose注册的事件", msg);
this.msg = msg;
});
}
<button @click="send">表白</button>
methods: {
send() {
bus.$emit("get", this.msg);
}
}
bus.$on("get", (msg)=>{
console.log("这是rose注册的事件", msg);
this.msg = msg;
});
注意点:1. 必须是同一辆公交车 2. 注册的事件和触发的事件必须保持一致