Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)

Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)

文章目录

  • 一、基本知识
    • 1. 组件的使用
    • 2. 全局组件和局部组件
    • 3. 父组件和子组件
    • 4. 模板的分离写法
    • 5. 组件数据
  • 二、父子组件通信
    • 1. 父传子
    • 2. 子传父
    • 3. 父访问子
    • 4. 子访问父
  • 三、插槽slot
  • 四、模块化开发

一、基本知识

组件化:
组件化是Vue.js中的重要思想,它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。任何的应用都会被抽象成一颗组件树

1. 组件的使用

1.创建组件构造器:Vue.extend()

        //1.创建组件构造器对象
        const cpnC = Vue.extend({
     
            template: `
            	

标题

内容

`
});

2.注册组件:Vue.component('my-cpn', cpnC);
创建构造器+注册语法糖(更常用):就是把template的内容直接写到cpnC中,省去extend这一步
全局组件:

Vue.component('myCpn', {
     
	template: `
		

标题

内容

`
})

局部组件:

const app = new Vue({
     
	el: '#app',
	data: {
     },
	components: {
     
		myCpn: {
     
			template: `
				

标题

内容

`
} } })

3.使用组件:在Vue实例的作用范围内(id="app"内)使用

2. 全局组件和局部组件

全局组件:可以在多个Vue实例下使用
在Vue外部注册的:Vue.component('myCpn', cpnC);

局部组件:只能在特定的Vue实例下使用(用得更多)
在Vue中写在components中:components: { myCpn: cpnC }

3. 父组件和子组件

app是cpnC2的父级(可看作root),cpnC2是cpnC1的父级,只有注册了,才可以在其实例范围下使用

    <script>
        const cpnC1 = Vue.extend({
     
            template: `
            

标题1

内容1

`
}); const cpnC2 = Vue.extend({ template: `

标题2

内容2

`
, components: { cpn1: cpnC1 } }); const app = new Vue({ el: '#app', data: { }, components: { cpn2: cpnC2 } }) </script>

4. 模板的分离写法

Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第1张图片

5. 组件数据

组件中的html结构要使用数据,使用组件中的data来设置,data是一个函数,返回一个对象
为什么是一个函数?因为当多次使用组件时,data是函数的形式,则会重新调用函数,里面的数据对于每个组件来说是私有的,不是公用的

<body>
    <div id="app">
        <cpn1></cpn1>
        <cpn2></cpn2>
    </div>

    <!-- html结构分离 -->
    <template id="cpn1">
        <h2>{
     {
     title1}}</h2>
    </template>
    <template id="cpn2">
        <h2>{
     {
     title2}}</h2>
    </template>

    <script src="../vue.js"></script>
    <script>
        //全局组件
        Vue.component('cpn1', {
     
            template: '#cpn1',
            data() {
      //注意data是一个函数 返回一个对象
                return {
     
                    title1: '全局组件'
                }
            }
        })
        const app = new Vue({
     
            el: '#app',
            data: {
     

            },
            components: {
     
                cpn2: {
     
                    template: '#cpn2',
                    data() {
      //data是函数 返回一个对象
                        return {
     
                            title2: '局部组件'
                        }
                    }
                }
            }
        })
    </script>
</body>

二、父子组件通信

在开发中,往往需要上层组件请求网络数据,再传递给下面的组件进行展示
父子组件间通信:
1.通过props向子组件传递数据
2.通过事件向父组件发送消息
Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第2张图片

1. 父传子

props

<body>
    <div id="app">
        <!-- 要用v-bind语法绑定数据 -->
        <cpn :cmovies="movies" :cmessage="message"></cpn>
    </div>

    <template id="cpn">
        <div>
            <p>{
     {
     cmessage}}</p>
            <ul>
                <li v-for="item in cmovies">{
     {
     item}}</li>
            </ul>
        </div>
    </template>

    <script src="../vue.js"></script>
    <script>
        const app = new Vue({
      //相当于父组件
            el: '#app',
            data: {
     
                message: 'vivian',
                movies: ['海贼王', '柯南', '火隐忍者', '蜡笔小新']
            },
            components: {
     
                cpn: {
      //子组件
                    template: '#cpn',
                    // 属性,里面是属性名
                    // 写法一:数组形式
                    // props: ['cmovies', 'cmessage']

                    //写法二:类型限制
                    // props: {
     
                    //     cmovies: Array,
                    //     cmessage: String
                    // }

                    //写法三:有默认值
                    props: {
     
                        //类型是对象或者数组时,默认值必须是一个函数
                        cmovies: {
     
                            type: Array,
                            default() {
     
                                return []
                            }
                        },
                        cmessage: {
     
                            type: String,
                            default: 'aaa',
                            required: true
                        }
                    }
                }
            }
        })
    </script>
</body>

Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第3张图片
注意:v-bind语法不支持驼峰命名法,要转成小写,例如childMyMessage要转成child-my-message才能使用v-bind

2. 子传父

子组件中,通过$emit来触发事件
父组件中,通过v-on来监听事件

<body>
    <!-- 父组件模板 -->
    <div id="app">
        <!-- 监听事件 v-on -->
        <cpn @itemclick="cpnClick"></cpn>
    </div>

    <!-- 子组件模板 -->
    <template id="cpn">
        <div>
            <button v-for="item in categories" @click="btnClick(item)">
                {
     {
     item.name}}</button>
        </div>
    </template>

    <script src="../vue.js"></script>
    <script>
        //子组件
        const cpn = {
     
            template: '#cpn',
            data() {
     
                return {
     
                    categories: [
                        {
      id: '111', name: '热门' },
                        {
      id: '222', name: '手机数码' },
                        {
      id: '333', name: '家用' }
                    ]
                }
            },
            methods: {
     
                btnClick(item) {
     
                    //发射事件:自定义事件
                    this.$emit('itemclick', item);
                }
            }
        }
        //父组件
        const app = new Vue({
     
            el: '#app',
            data: {
     

            },
            components: {
     
                cpn
            },
            methods: {
     
                cpnClick(item) {
     
                    console.log(item);
                }
            }
        })
    </script>
</body>

3. 父访问子

$children得到所有子组件,可以访问其中的属性和方法,但是对于获取第n个组件不那么方便
如:this.$children[0].showMessage();
$refs得到的对应ref名字的组件,可以访问特定的子组件,用得较多
如:this.$refs.aaa.showMessage();

4. 子访问父

$parent 访问父组件,但是一般不适用,组件耦合度高,不方便复用
例如:this.$parent.name
$root 访问根组件,也很少用
例如:this.$root.name

三、插槽slot

slot的目的:更具有扩展性,抽取共性,保留不同
Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第4张图片
基本使用:

默认值

编译作用域
举个例子,当父组件和子组件都有数据(data)isShowed时,在父作用域下(e.g. id=“app”)使用的isShowed会在父组件中找,在子作用域下(id=“cpn”)使用的isShowed会在子组件中找

作用域插槽
父组件对子组件展示数据的方式不满意,拿到子组件的数据进行展示

    <div id="app">
        <cpn>cpn>
        <cpn>
            
            <temlate slot-scope="slot">
                <span v-for="item in slot.data">{
    {item}} - span>
            temlate>
        cpn>
        <cpn>cpn>
    div>

    <template id="cpn">
        <div>
            
            <slot :data="pLanguages">
                <ul>
                    <li v-for="item in pLanguages">{
    {item}}li>
                ul>
            slot>
        div>
    template>

Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第5张图片

四、模块化开发

是为了解决多人开发下全局变量命名冲突的问题,还有js文件依赖的问题
常见的模块化规范:CommonJS、AMD、CMD、ES6的Modules
Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第6张图片
Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第7张图片
Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第8张图片
Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第9张图片
Vue学习2:组件化开发(基本知识、父子间通信、slot、模块化开发)_第10张图片

你可能感兴趣的:(前端开发,vue,vue.js)