🌵Vue组件化开发

简介: 🌵Vue组件化开发

1. 组件的使用:


  • 创建组件构造器
  • 注册组件
  • 使用组件


1.创建组件构造器


const cpnC = Vue.extend({
            template: `
            <div>
                <h2>我是标题</h2>
                <p>我是内容</p>
            </div>`
        })
复制代码


2.注册组件


Vue.component('my_cpn', cpnC)
复制代码


3.使用组件


<div id='app'>
        <my_cpn></my_cpn>
        <my_cpn></my_cpn>
        <my_cpn></my_cpn>
    </div>
复制代码


ad5f1e952c6b4f2a8fc4f4cadb5efd2f_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


注:事实上,这种写法在Vue2.x的文档中几乎已经看不到了,它会直接使用下面的语法糖,但这种方式是学习后面方式的基础。


2. 全局组件和局部组件


全局组件,意味着可以在多个Vue的实例下面使用, 上面我们注册的组件就是全局组件。那么我们如何来注册局部组件呢?


我们需要在Vue实例下面注册


const app = new Vue({
            el: '#app',
            data: {
            },
            // 注册局部组件
            components:{
                my_cpn:cpnC
            }
        })
复制代码


61f21f4f11a54b4690e2f31339a2bcd8_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


3.父组件和子组件


<div id='app'>
        <cpn2></cpn2>
    </div>
复制代码


// 1. 创建第一个组件(子组件)
        const cpnC1 = Vue.extend({
            template: `
            <div>
                <h2>我是标题1</h2>
                <p>我是内容1</p>
            </div>
            `
        })
复制代码


// 2. 创建第二个组件(父组件)
        const cpnC2 = Vue.extend({
            template: `
            <div>
                <h2>我是标题2</h2>
                <p>我是内容2</p>
                <cpn1></cpn1>
            </div>
            `,
            components: {
                cpn1: cpnC1
            }
        })
复制代码


const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js'
            },
            components: {
                cpn2: cpnC2
            }
        })
复制代码


4. 注册组件语法糖


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


// 全局组件注册的语法糖
        // 1. 创建组件构造器
        // 2. 注册组件
        Vue.component('cpn1', {
            template: `
            <div>
                <h2>我是标题</h2>
                <p>我是内容</p>
            </div> `
        })
复制代码


5. 组件模板抽离的写法


<!-- 第一种:script标签,类型必须是text/x-template -->
    <script type="text/x-template" id="cpn1">
    <div>
        <h2>我是标题</h2>
        <p>我是内容</p>
    </div>
    </script>
复制代码


<!-- 第二种:template标签 -->
    <template id="cpn2">
        <div>
            <h2>我是标题1</h2>
            <p>我是内容1</p>
        </div>
    </template>
    <script src='../js/vue.js'></script>
    <script>
复制代码


Vue.component('cpn2', {
            template: "#cpn2"
        })
复制代码


6. 组件可以访问Vue实例数据吗?


不能!组件是一个单独功能模块的封装:


这个模块有属于自己的HTML模板,也应该有属于自己的数据data。


那么组件自己的数据存放在哪里呢?


  • 组件对象也有一个data属性(也可以有methods等属性)
  • 只是这个data属性必须是一个函数
  • 而且这个函数返回一个对象,对象内部保存着数据


Vue.component('cpn2', {
            template: "#cpn2",
            data() {
                return {
                    title: "abc"
                }
            }
        })
复制代码


为什么data必须是函数?


因为保证多个组件使用时,各个组件之间不会相互影响。


7. 父子组件的通信、


在上一节我们提到了子组件是不能引用父组件或者Vue实例的数据的。


但是,在开发中,往往一些数据确实需要从上层传递到下层:


  • 比如在一个页面上,我们从服务器请求到了很多的数据。
  • 其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。
  • 这个时候我们并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)那么如何进行父子组件间的通信呢?
  • 通过props向子组件传递数据
  • 通过事件向父组件发送信息


props基本用法


  • 在组件中,使用选项props来声明需要从父级接收到的数据。
  • props的值有两种方式
  • 方式一:字符串数据,数组中的字符串就是传递时的名称
  • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等方式一:


08d52c61dcf94234b1f95d277ab7e6f5_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


方式二:


ba6f12b72f7b4da78eb3919817245c48_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


通过事件向父组件发送信息


this.$emit()


<body>
    <div id='app'>
        <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='../js/vue.js'></script>
    <script>
        const cpn = {
            template: '#cpn',
            data() {
                return {
                    categories: [
                        { id: 1, name: "橙子" },
                        { id: 2, name: "苹果" },
                        { id: 3, name: "香蕉" },
                        { id: 4, name: "西瓜" },
                    ]
                }
            },
            methods: {
                btnclick(item) {
                    this.$emit('itemclick', item)
                }
            },
        }
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js'
            },
            components: {
                cpn
            },
            methods: {
                cpnclick(item) {
                    console.log('cpnclick', item)
                }
            },
        })
    </script>
复制代码


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


  • 父组件访问子组件:使用$children或$refs


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


<body>
    <div id='app'>
        <cpn></cpn>
        <cpn></cpn>
        <cpn></cpn>
        <cpn ref="aaa"></cpn>
        <button @click="btnclick">按钮</button>
    </div>
    <template id="cpn">
        <div>
            <h1>我是子组件</h1>
        </div>
    </template>
    <script src='../js/vue.js'></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js'
            },
            methods: {
                btnclick() {
                    // console.log(this.$children[0].showmessage);
                    console.log(this.$refs.aaa.name);;
                }
            },
            components: {
                'cpn': {
                    template: '#cpn',
                    data() {
                        return {
                            name: '橙子'
                        }
                    },
                    methods: {
                        showmessage() {
                            console.log('showmessage')
                        }
                    },
                }
            }
        })
    </script>
</body>
复制代码


<body>
    <div id='app'>
        <cpn></cpn>
    </div>
    <template id="cpn">
        <div>
            <ccpn></ccpn>
        </div>
    </template>
    <template id="ccpn">
        <div>
            <h1>我是cpn组件</h1>
            <button @click="btnclick">按钮</button>
            <h3>我是子组件</h3>
        </div>
    </template>
    <script src='../js/vue.js'></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js'
            },
            components: {
                'cpn': {
                    template: '#cpn',
                    data() {
                        return {
                            name: "橙子"
                        }
                    },
                    components: {
                        'ccpn': {
                            template: '#ccpn',
                            methods: {
                                btnclick() {// 访问父组件$parent
                                    // console.log(this.$parent.name)
                                    // 访问根组件$root
                                    console.log(this.$root.message);
                                }
                            },
                        }
                    }
                }
            }
        })
    </script>
</body>
复制代码


9.插槽的基本使用


<body>
    <div id='app'>
        <cpn>
            <h4>1111</h4>
        </cpn>
        <cpn>
            <h4>2222</h4>
        </cpn>
        <cpn></cpn>
        <cpn></cpn>
    </div>
    <template id="cpn">
        <div>
            <h2>Vue真有意思</h2>
            <p>哈哈哈</p>
            <slot><button>按钮</button></slot>
        </div>
    </template>
    <script src='../js/vue.js'></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js',
            },
            components: {
                'cpn': {
                    template: '#cpn'
                }
            }
        })
    </script>
</body>
复制代码


具名插槽


<body>
    <div id='app'>
        <cpn><button slot="medium">我是中间按钮</button></cpn>
        <cpn><button slot="right">我是右边按钮</button></cpn>
    </div>
    <template id="cpn">
        <div>
            <h2>具名插槽的使用</h2>
            <slot name="left"><span>左边</span></slot>
            <slot name="medium"><span>中间</span></slot>
            <slot name="right"><span>右边</span></slot>
        </div>
    </template>
    <script src='../js/vue.js'></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js'
            },
            components: {
                'cpn': {
                    template: '#cpn'
                }
            }
        })
    </script>
</body>
复制代码


编译作用域


<body>
    <div id='app'>
        <cpn v-show=isShow></cpn>
    </div>
    <template id="cpn">
        <div>
            <h2>我是子组件</h2>
            <p v-show=isShow>我是内容嘿嘿嘿</p>
        </div>
    </template>
    <script src='../js/vue.js'></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js',
                isShow: true
            },
            components: {
                cpn: {
                    template: "#cpn",
                    data() {
                        return {
                            isShow: false
                        }
                    }
                }
            }
        })
    </script>
</body>
复制代码


官方准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译


a4f72d1cd2974385bf5ea09e0bbdb33e_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


作用域插槽


比较难理解,有一句话概括一下


  • 父组件替换插槽的标签,但是内容由子组件来提供


<body>
    <div id='app'>
        <cpn>
            <template slot-scope="slot">
                <span v-for="item in slot.data">{{item}}-</span>
            </template>
        </cpn>
        <cpn>
            <template slot-scope="slot">
                <span v-for="item in slot.data">{{item}}-</span>
            </template>
        </cpn>
        <cpn>
            <template slot-scope="slot">
                <span>{{slot.data.join('*')}}</span>
            </template>
        </cpn>
    </div>
    <template id="cpn">
        <div>
            <h1>我是子组件</h1>
            <slot :data=planguage>
                <ul>
                    <li v-for="item in planguage">{{item}}</li>
                </ul>
            </slot>
        </div>
    </template>
    <script src='../js/vue.js'></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好 Vue.js'
            },
            components: {
                cpn: {
                    template: '#cpn',
                    data() {
                        return {
                            planguage: ['JavaScript', 'Java', 'Python', 'C++', 'Swift']
                        }
                    }
                }
            }
        })
    </script>
复制代码


d479556a4d66490c99fd6aa333e2836d_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


8e38c0d9166a49b79d0680c13cf88f68_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

相关文章
|
17天前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
17天前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
19 1
|
17天前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
17天前
|
存储 JavaScript 前端开发
介绍一下Vue的核心功能
介绍一下Vue的核心功能
|
存储 前端开发 JavaScript
为什么我不再用Vue,改用React?
当我走进现代前端开发行业的时候,我做了一个每位开发人员都要做的决策:选择一个合适的框架。当时正逢 jQuery 被淘汰,前端开发者们不再用它编写难看的、非结构化的老式 JavaScript 程序了。
|
19天前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
20天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
23 1
vue学习第一章
|
20天前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
22 1
vue学习第三章
|
20天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
35 1
vue学习第四章
|
20天前
|
JavaScript 前端开发 算法
vue学习第7章(循环)
欢迎来到瑞雨溪的博客,一名热爱JavaScript和Vue的大一学生。本文介绍了Vue中的v-for指令,包括遍历数组和对象、使用key以及数组的响应式方法等内容,并附有综合练习实例。关注我,将持续更新更多优质文章!🎉🎉🎉
21 1
vue学习第7章(循环)