自定义指令 v-
作用: 对普通 DOM 元素进行底层操作;
全局自定义指令; Vue.directive( 指令名, 配置对象/回调函数)
局部自定义指令; directives:{指令名,配置对象/回调函数}
组件
组件的定义——实现应用中局部功能代码和资源的集合;
- 全局组件 Vue.component(); 可以在多个vue实例中使用;
- 局部组件 components:{ }; 只能在在注册的vue实例中使用;
- 创建组件构造器; 传入一个配置对象; 这个对象除了el配置项,其他的都有;
- 注册组件; 两个参数, '组件标签' 和 构造器名字
- 使用组件; 在挂载点中使用;
<body>
<div id="app">
<!-- 使用全局组件 -->
<cpn></cpn>
<!-- 使用局部组件 -->
<cpn2></cpn2>
</div>
<script>
// 创建组件的构造器
const cpnC = Vue.extend({
template:
`<div>
<p>你好</p>
<h3>hello</h3>
</div>
`
})
// 注册全局组件
Vue.component('cpn',cpnC)
const vm = new Vue({
el:'#app',
data:{},
methods:{},
// 注册局部组件
components:{
// 对象的key可以用引号,也可以不用
'cpn2':cpnC,
// cpn2:cpnC
}
});
</script>
</body>
注意:
- 调用Vue.extend()方法 - 创建组件构造器
- 调用Vue.component()方法 - 注册组件
- 在Vue实例的作用范围内 - 使用组件
- 组件构造器中的template中可以用引号(不能换行),用反引号(字符串模板可以换行);要有一个根标签<div>包裹;
- 在vue实例的配置项,components:{ } 注册局部组件 ;
- 对象的key值,可以加引号(当做字符串),也可以不加(变量)
- 对象字面量的增强写法:? 函数名: funtion() 可以省略:function ;
- 对象的字面量增强写法: 对象的属性名和属性值一样,是个变量可以省略一个;
父子组件
子组件在父组件中注册,在父组件中使用;
在父组件的构造器对象的配置项: coponents:{ } 中注册子组件,;在template模板中使用组件;
<body>
<div id="app">
<!-- 使用父组件B,包含子组件A -->
<cpn-b></cpn-b>
<hr>
<!-- 在root根组件中注册组件A,直接使用子组件A -->
<cpn-A></cpn-A>
</div>
<script>
// 创建子组件构造器 cpnA
const cpnA = Vue.extend({
template:
`
<div>
<h5> 我是子组件 </h5>
</div>
`
})
// 创建父组件构造器 cpnB
const cpnB = Vue.extend({
template:
// 在父组件的tempalte模板中使用子组件
`
<div>
<h3> 我是父组件 </h3>
<cpn-a></cpn-a>
</div>
`,
// 在父组件的components中注册子组件
components:{
'cpn-a':cpnA
}
})
const vm = new Vue({
el:'#app',
data:{},
methods:{},
// 注册局部组件 父组件
components:{
'cpn-b':cpnB,
// 想直接单独使用子组件A,在根组件root组件中注册
'cpn-a':cpnA
}
});
</script>
</body>
组件的语法糖注册方法
把创建组件构造器Vue.extend()中的配置对象{ } ,直接写到注册组件中去;省略Vue.extend()书写;
构造器名字,直接写成一个对象;这个对象就是之前构造器传入的配置对象;
但Vue会仍会自动的将此对象给Vue.extend()
// 内部会自动调用Vue.extend()
<body>
<div id="app">
<!-- 使用全局组件 -->
<cpn-a></cpn-a>
<hr>
<!-- 使用局部组件 -->
<cpn-b></cpn-b>
</div>
<script>
// 注册全局组件
Vue.component("cpn-a",{
template:'<div><h4>我是全局组件</h4></div>'
})
const vm = new Vue({
el:'#app',
data:{},
methods:{},
// 注册局部组件
components:{
"cpn-b":{
template:`
<div>
<p>我是局部组件</p>
</div>
`
}
}
});
</script>
</body>
组件构造器的配置对象中的template模板的抽离写法:?
template模板写:? '选择器';
template便签内写:? 选择器; 需要有个根标签<div>包裹;<div>内写需要的模板;
template标签不会被渲染,
<body>
<div id="app">
<!-- 使用组件 -->
<cpn></cpn>
</div>
<!-- template模板的抽离写法 -->
<template id="aaa"> // 选择器
<div>
<h3>模板的分离写法</h3>
</div>
</template>
<script>
// 注册组件
Vue.component('cpn',{
template:'#aaa' //选择器
})
const vm = new Vue({
el:'#app',
data:{},
methods:{}
});
</script>
</body>
组件使用数据
子组件不能直接使用父组件中的数据;
vue实例也是一个父组件,root根组件;
组件可以使用自己组件内的data配置项中的数据;
组件的data属性,必须是一个函数,且返回一个对象;
组件也有自己的data属性(在vue.extend()的配置对象中),必须是一个函数,且返回一个对象;
<body>
<div id="app">
<!-- 使用组件 -->
<cpn></cpn>
</div>
<template id="aaa">
<div>
<!-- 使用组件data中的数据 -->
<h3>{{msg}}</h3>
</div>
</template>
<script>
// 注册组件
Vue.component('cpn', {
template: '#aaa',
// 必须是一个函数,且返回一个对象
// 对象的字面量增强写法 省略 :function
data() {
return {
msg: '组件的data必须是一个函数'
}
},
// data:function () {
// return{
// msg:"组件的data必须是一个函数,且返回一个对象"
// }
// }
})
const vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
父子通信
父组件通过props向子组件传递数据 [props=> property 属性]
方法一: ? props:[ ]
- 注册组件的配置对象中的添加props配置项,是一个数组;
- 数组中的字符串是变量, 用来接受父组件传递过来的数组;
- 使用组件时,用过v-bind属性绑定, 用props中的变量接受父组件中的数据;
- 在模板中使用这些props[ ]中的变量;
<body>
<div id="app">
<!-- 使用子组件,父组件是vue实例 -->
<!-- 通过v-bind绑定props中的变量;
接收父组件传递给子组件的数据 -->
<cpn :cmsg="msg" :cmovies="movies"></cpn>
</div>
<template id="aaa">
<div>
<!-- 使用父组件传递过来的数据 -->
<h2>{{cmsg}}</h2>
<ul>
<!-- 使用父组件传递过来的数据 -->
<li v-for="item in cmovies">{{item}}</li>
</ul>
</div>
</template>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: '你很棒',
movies: ['西游记', '三国演义', '红楼梦', '水浒传']
},
methods: {},
// 注册局部组件
components: {
// 组件中的对象的key(属性名) 就是组件标签名, 可以加引号,也可以不加
'cpn': {
template: '#aaa',
// 数组中的字符串就是变量,
props: ['cmsg','cmovies'],
data() {
return {
}
}
}
}
});
</script>
</body>
方法二:? props:{ }
- props是一个对象时, 可以对接受的变量进行类型限制;
- 这些变量是一个对象,required: true 表示这个变量必传;
- default 是当没有数据接收时,显示默认值;
- 当数据类型是数组或对象时, 默认值必须是一个函数,且return{ 默认值 }
props的数据类型验证:
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,// 要求这个变量的数据类型是Number;
// 多个可能的类型
propB: [String, Number],//数据类型是字符串或数字类型;
// 必填的字符串
propC: {
type: String, // 数据类型是字符串类型,且这个变量必须使用;
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100 // 默认值,当没有接受数据时,默认值显示
},
// 带有默认值的对象或数组
propE: {
type:[Object,Array],
// 当数据类型是对象或数组时, 默认值必须函数获取且 return {默认值};
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
|