🌵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

相关文章
|
2月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
301 2
|
1月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
280 137
|
5月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
777 0
|
4月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
403 1
|
4月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
259 0
|
存储 前端开发 JavaScript
为什么我不再用Vue,改用React?
当我走进现代前端开发行业的时候,我做了一个每位开发人员都要做的决策:选择一个合适的框架。当时正逢 jQuery 被淘汰,前端开发者们不再用它编写难看的、非结构化的老式 JavaScript 程序了。
|
7月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
1009 4
|
5月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
6月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
835 77
|
7月前
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍