有勇气的牛排博客

Vue组件化 模板 语法糖 函数 父子组件通信

有勇气的牛排 1211 前端 2021-11-15 00:47:44

文章目录

1 注册组件的基本步骤

  • 创建爱你组件构造器:Vue.extends()

  • 注册组件:Vue.component()

  • 使用组件

2 组件的基本使用

<div id="app"> <!-- 3 使用组件 --> <my-cpn></my-cpn> <my-cpn></my-cpn> <my-cpn></my-cpn> </div> <script src="../js/vue.js"></script> <script> // 1 创建组件构造器对象 const cpnConstructor = Vue.extend({ template: ` <div> <h2>标题</h2> <p>哈哈哈</p> </div> ` }) // 2 注册组件 Vue.component('my-cpn', cpnConstructor) const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排" } }) </script>

3 全局组件和局部组件

<script src="../js/vue.js"></script> <script> // 1 创建组件构造器 const cpnC = Vue.extend({ template: ` <div> <h2>标题</h2> <p>内容</p> </div> ` }) // 2 组件注册(全局组件: 意味着可以在多个Vue实例下面使用) // Vue.component('cpn', cpnC) // Vue实例1 const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排" }, // 局部组件 components:{ // cpn使用组件时的标签名 cpn:cpnC } }) // Vue实例2 const app2 = new Vue({ el: '#app2' }) </script>

4 父组件和子组件

<div id="app"> <cpn2></cpn2> </div> <script src="../js/vue.js"></script> <script> // 1 创建爱你第1个组件构造器(子组件) const cpnC1 = Vue.extend({ template: ` <div> <h2>标题1</h2> <p>666</p> </div> ` }) // 2 创建爱你第2个组件构造器(父组件) const cpnC2 = Vue.extend({ template: ` <div> <h2>标题2</h2> <p>777</p> <cpn1></cpn1> </div> `, components: { cpn1: cpnC1 } }) // root组件 const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排" }, components: { cpn2: cpnC2 } }) </script>

5 注册组件语法糖

主要省区了调用Vue.extend()的步骤,而是可以直接使用一个对象来代替

<script> // 1 全局组件注册的语法糖 // 1 创建组件构造器 // const cpn1 = Vue.extend() // 2 组件注册(全局方式) Vue.component('cpn1', { template: ` <div> <h2>标题1</h2> <p>666</p> </div> ` }) const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排" }, components: { 'cpn2': { template: ` <div> <h2>标题2</h2> <p>777</p> </div> ` } } }) </script>

6 组件模板分离写法 组件数据存放

存放

  • 组件对象向也有一个data属性(也可以有methods等属性)

  • 只是这个data属性必须是一个函数

  • 而且这个函数返回一个对象,对象内部保存着数据

<div id="app"> <cpn1></cpn1> <cpn2></cpn2> </div> <!-- 1 script标签,注意:类型必须是text/x-template --> <script type="text/x-template" id="cpn1"> <div> <h2>标题1</h2> <p>666</p> </div> </script> <!-- 2 template标签 --> <template id="cpn2"> <div> <h2>标题2</h2> <p>777</p> </div> </template> <script src="../js/vue.js"></script> <script> // 注册一个全局组件 Vue.component('cpn1', { template: '#cpn1' }) Vue.component('cpn2', { template: '#cpn2' }) const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排" } }) </script>

7 组件中data为什么是函数

<div id="app"> <cpn></cpn> <cpn></cpn> <cpn></cpn> </div> <!-- 组件实例对象 --> <template id="cpn"> <div> <h2>当前计数:{{ counter }}</h2> <button @click="increment">+</button> <button @click="decrement">-</button> </div> </template> <script src="../js/vue.js"></script> <script> // 1 注册组件 Vue.component('cpn', { template: '#cpn', data() { return { counter: 0 } }, methods: { increment() { this.counter++; }, decrement() { this.counter--; } } }) const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排" } }) </script>

8 父子组件的通信

  • 通过props想自键传递数据

  • 通过时间向父组件发送消息

props数据验证

支持:String、Number、Boolean、Array、Object、Date、Function、Symbol

<div id="app"> <!-- <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>--> <cpn v-bind:cmovies="movies"></cpn> </div> <template id="cpn"> <div> <h2>{{ cmessage }}</h2> <ul> <li v-for="item in cmovies">{{ item }}</li> </ul> </div> </template> <script src="../js/vue.js"></script> <script> // 父传子:props const cpn = { template: '#cpn', // props: ['cmovies', 'cmessage'], props: { // 1 类型限制 // cmovies:Array, // cmessage:String // 2 提供一些默认值 cmessage: { type: String, default: '666', required: true }, // 类型是对象或者数组时,默认值必须是一个函数 cmoves: { type: Array, default() { return [] } } }, data() { return {} }, methods: {} } const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排", movies: ['三体', '金刚狼', '疯狂外星人'] }, components: { cpn } }) </script>

9 父子通信-父传子(props中的驼峰命名)

<div id="app"> <cpn :c-info="info" :child-my-message="message"></cpn> </div> <template id="cpn"> <h2>{{ cInfo }}</h2> </template> <script src="../js/vue.js"></script> <script> const cpn = { template: '#cpn', props: { cInfo: { type: Object, default() { return {} } }, childMyMessage: { type: String, default: '' } } } const app = new Vue({ el: '#app', data: { info: { name: "有勇气的牛排", age: 18, sex: 0 } }, components: { cpn } }) </script>

10 组件通信-子传父(自定义事件)

什么时候需要使用自定义事件?

  • 当子组件需要想父组件传递数据时,就要用到自定义事件了

  • v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件

自定义事件的流程

  • 在子组件中,通过$emit()来触发事件。

  • 在父组件中,通过v-on来鉴定子组件事件

<!-- 子组件模板 --> <template id="cpn"> <div> <button v-for="item in categories" @click="btnClick(item)"> {{ item.name }} </button> </div> </template> <script src="../js/vue.js"></script> <script> // 1 子组件 const cpn = { template: '#cpn', data() { return { categories: [ {id: '1', name: '热门推荐'}, {id: '2', name: '手机数码'}, {id: '3', name: '家电'}, {id: '4', name: '电脑办公'}, {id: '5', name: '衣服'}, {id: '6', name: '玩具'} ] } }, methods: { btnClick(item) { // console.log(item) // 发射事件: 自定义事件 this.$emit('item-click', item) } } } // 2 父组件 const app = new Vue({ el: '#app', data: { message: '有勇气的牛排' }, components: { cpn }, methods: { cpnclick(item) { console.log('cpnclick', item); } } }) </script>

11 12 组件通信 案例

见gitee源代码

13 父子组件的访问方式:$children

有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是组件访问跟组件。

  • 父组件访问子组件:使用children或者refs(reference 引用)

  • 子组件访问父组件:$parent

<div id="app"> <cpn></cpn> <cpn ref="key1"></cpn> <cpn></cpn> <button @click="btnClick">按钮</button> </div> <template id="cpn"> <div>我是子组件</div> </template> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: "你好,有勇气的牛排" }, methods: { btnClick() { // 1 $children // console.log(this.$children); // this.$children[0].showMessage(); // this.$children[0].name; // for(let c of this.$children){ // c.showMessage(); // } // 2 $refs => 对象类型,默认是一个空对象 ref='key1' console.log(this.$refs.key1.name); } }, components: { cpn: { template: '#cpn', data() { return { name: '我是子组件的name' } }, methods: { showMessage() { console.log('showMessage'); } } } } }) </script>

留言

专栏
文章
加入群聊