Vue组件化
1. 注册组件步骤
- 创建逐渐构造器,extend()
- 注册组件,component()
- 使用组件
2. 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id = "app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
//1.创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>组件测试</h2>
<p>组件测试1111</p>
<p>组件测试222222</p>
<p>组件测试333333</p>
</div>
`
});
//2.注册组件
Vue.component('my-cpn',cpnC);
const app = new Vue({
el: '#app',
})
</script>
</body>
</html>
3.全局组件和局部组件
- 全局组件可以再多个Vue实例下使用
Vue.component('cpn',cpnC)
- 局部组件的注册,是在new Vue({})对象中,通过components属性进行注册
const app = new Vue({
el: '#app',
data: {
},
components: {
//cpn对应的是组件的标签名
//cpnC对应构造器对象
cpn: cpnC,
}
})
4. 父组件和子组件
可以在组件构造器中注册组件,并且可以在注册之后直接调用该组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id = "app">
<cpn2></cpn2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
//1.创建组件构造器对象
const cpnC1 = Vue.extend({
//子组件
template: `
<div>
<h2>标题1</h2>
<p>组件测试1111</p>
</div>
`
})
const cpnC2 = Vue.extend({
//父组件
template: `
<div>
<h2>标题2</h2>
<p>组件测试22222</p>
<cpn1></cpn1>
</div>
`,
components: {
cpn1: cpnC1,
}
})
//第二种组件注册方式
const app = new Vue({
el: '#app',
components:{
cpn2: cpnC2
}
})
</script>
</body>
</html>
5.注册组件的语法糖写法
语法糖的写法虽然省略了Vue.extend()的步骤,但是在Vue内部依然是通过Vue.extend()是实现的。
- 全局组件的语法糖
Vue.component('cpn1',{
template: `
<div>
<h2>
我是标题
</h2>
<p>我是内容</p>
</div>
`
})
- 局部组件语法糖
const app = new Vue({
el: "#app",
components: {
cpn2: {
template: `
<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>
`
}
}
})
6.组件模板抽离的写法
<script type="text/x-template" id = "cpn">
<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>
</script>
<script>
Vue.component("cpn",{
template: "#cpn"
})
</script>
- 标签
<template id = "cpn">
<div>
<h2>我是标题</h2>
<p>我是内容</p>
</div>
</template>
<script>
Vue.component("cpn",{
template: "#cpn"
})
</script>
7.组件中的data必须为函数
Vue.component('cpn1', { template: cpn, data () { return { cpmess, } }})
8. 父子组建通
1.父传子,使用在子组件中使用props接收父组件数据
<div id = "app"> <cpn1 :cpmess = "message"></cpn1> <!--2.在标签中绑定两变量数据--> </div> <template id="cpn"> <div> <h2> 标题1 {{cpmess}} </h2> <p>内容1</p> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> <script> Vue.component('cpn1', { template: cpn, props: ['cpmess'] //使用props接收父组件数据 }) //第二种组件注册方式 const app = new Vue({ el: '#app', data: { message: "你好测试", //在Vue对象中定义数据 }, }) </script>
props除了可以写成数组形式还可以写成其他多种形式:
- 使用type属性规定数据类型,也可以传自定义类型
- 使用default为对象设置默认值
类型为对象或者数组时,default必须写成函数的形式
- 使用required规定对象必须传值
v-bind绑定是不支持驼峰标识的,驼峰标识的cInfo可以写为c-info
2.子传父
- 子组件自定义的事件传给父组件this.$emit向父组件发射自定义事件
<div id = 'app'> <cpn1 @enclick="cclickent"></cpn1> </div> <template id = 'cpn'> <div> <button v-for="item in message" @click="cclick(item)">{{item.name}}</button> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> <script> Vue.component('cpn1',{ data () { return { message:[{name: '文件管理',id: 1},{name: '测试管理',id: 2},{name: '系统设置', id: 3}] } }, template: cpn, methods: { cclick(item){ this.$emit('enclick', item) } } }) const app = new Vue({ el: '#app', methods: { cclickent(item){ console.log(item); } } }) </script>
- 计数器子传父小练习
<div id = 'app'> 计数为:{{message}} <cpn1 @caddb="fcount"></cpn1> </div> <template id = 'cpn'> <div> <button @click="ccount(1)">+</button> <button @click="ccount(2)">-</button> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> <script> Vue.component('cpn1',{ template: cpn, methods: { ccount(num){ this.$emit('caddb', num) }, } }) const app = new Vue({ el: '#app', data: { message: 0 } , methods: { fcount(num){ if(num === 1){ this.message++ }else{ this.message-- } } } }) </script>
3. 子父组件变量v-model实时修改不建议直接绑定props里面的属性,应该在data中重新创建一个变量,给props属性绑定,让后v-model绑定data中的属性。
9.父子组件相互访问
- 父组件访问子组件 c h i l d r e n 或 children或 children或refs,一般开发通过this.$refs是一个对象类型,默认为空对象,必须要在组件上加ref属性,才可以拿到该组件
通过children方式获取,由于children返回的是数组,通过下表访问数组的方式容易出问题,所以不建议该方法
<div id = 'app'>
<cpn1></cpn1>
<button @click="cl">按钮</button>
</div>
<template id = 'cpn'>
<div>
<p>我是子组件</p>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
cl(){
console.log(this.$children[0].show1());
}
},
components: {
cpn1: {
template: cpn,
methods: {
show1(){
console.log("子组件方法调用");
}
}
}
}
})
</script>
通过refs方式获取
<div id = 'app'>
<cpn1></cpn1>
<cpn1 ref="refTest"></cpn1>
<button @click="cl">按钮</button>
</div>
<template id = 'cpn'>
<div>
<p>我是子组件</p>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
cl(){
console.log(this.$refs.refTest.show1());
}
},
components: {
cpn1: {
template: cpn,
methods: {
show1(){
console.log("子组件方法调用");
}
}
}
}
})
</script>
- 子组件访问父组件: p a r e n t , 使 用 parent,使用 parent,使用root访问跟组件。