Vue的组件

简介: 1、组件的概念组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树2、全局组件的注册(所有实例都能用)注册一个全局组件语法格式如下:Vue.component(tagName, options)tagName 为组件名,options 为配置选项。

1、组件的概念

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树

2、全局组件的注册(所有实例都能用)

注册一个全局组件语法格式如下:

  • Vue.component(tagName, options)
    tagName 为组件名,options 为配置选项。
  • 注册后,我们可以使用以下方式来调用组件:
    <tagName></tagName>
<div id="app">
    app<runoob></runoob>
</div>
<div id="app1">
    app1<runoob></runoob>
</div>
<script>
    // 注册全局组件runoob
    Vue.component('runoob', {
        template: '<h1>自定义全局组件!</h1>'
    });
    // 创建Vue根实例
    new Vue({
        el: '#app'
    });
    new Vue({
        el:'#app1'
    })
</script>

3、局部组件的注册

  • 我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用
<div id="app">
    app<runoob></runoob>
</div>
<div id="app1">
    app1<runoob></runoob>
</div>
<script>
    let Child = {
        template: '<h1>自定义组件!</h1>'
    };
    // 创建Vue根实例
    new Vue({
        el: '#app',
        components: {
            // <runoob> 将只在父模板可用
            'runoob': Child
        }
    });
    new Vue({
        el:'app1'
    })
</script>

4、父子组件通信(props)

  • prop 是父组件用来传递数据的一个自定义属性。
    父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":
  • 注意: prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
<div id="app">
    <parent></parent>
</div>
<script>
    let child = {
        template: `<div><p>这是个子组件{{name}}</p></div>`,
        // 声明 props
        props: ["name"]
    };
    let parent = {
        //模板
        template: `<div>
                    <h1>这是个父组件</h1>
                    <child :name="username"></child>
                    </div>`,
        //注册一个子组件
        components: {
            child: child
        },
        data() {
            return {
                username: "peiqi"
            }
        }
    };
    //创建Vue根实例
    const app = new Vue({
        el: "#app",
        //注册一个局部组件parent
        components: {
            parent: parent
        }
    })
</script>
  • 动态 Props
    类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg"></child>
    </div>
</div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    parentMsg: '父组件内容'
  }
})
</script>
  • 以下实例中将 v-bind 指令将 todo 传到每一个重复的组件中:
<div id="app">
    <ol>
    <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
      </ol>
</div>
 
<script>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})
new Vue({
  el: '#app',
  data: {
    sites: [
      { text: 'Runoob' },
      { text: 'Google' },
      { text: 'Taobao' }
    ]
  }
})
</script>

5、子父组件通信

  • 上面我们说过,props 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
  • 那么想一下子父通信怎么实现呢?
    机智如你发现:给子组件绑定事件,通过$emit将事件提交(可以携带参数),在父组件中绑定对应事件的处理函数就可以实现子父组件的通信了。
<div id="app">
    <parent></parent>
</div>
<script>
    // 子组件 提交一个事件 可以携带值
    let child = {
        template: `<div>
                        <p>这是个子组件</p>
                        <button @click="on_click">点我显示你银行卡余额</button>
                    </div>`,
        methods: {
            on_click: function () {
                //提交一个事件 可以携带值
                this.$emit("show_balance", this.balance)
            }
        },
        data() {
            return {
                balance: 998,
            }
        }
    };
    let parent = {
        template: `<div>
                    <h1>这是个父组件</h1>
                    <child @show_balance="my_func"></child>
                      <span>{{p_balance}}</span>
                    </div>`,
        //注册一个子组件
        components: {
            child: child
        },
        data() {
            return {
                username: "peiqi",
                p_balance: ""
            }
        },
        methods: {
            my_func: function (data) {
                this.p_balance = data
            }
        }
    };
    //创建Vue根实例
    const app = new Vue({
        //制定作用域
        el: "#app",
        //注册一个局部组件
        components: {
            parent: parent
        }
    })
</script>

6、非父子组件通信

  • 非父子组件的通信没有办法通过绑定事件来解决了,那就需要通过生成一个中间Vue实例来做父子组件通信的媒介,一个时间通过 Vue实例.emit()将事件提交到媒介实例,然后另一个组件通过 Vue实例.on()去处理传来的事件就可以完成两个互不相干的组件之间的通信了。
  • 只要思想不滑坡,方法总比问题多!!!
<div id="app">
    <alex></alex>
    <wenzhou></wenzhou>
</div>
<script>
    //生成一个中间Vue实例用于数据传递
    let Event = new Vue();
    let alex = {
        template: `<div>
                    <p>Alex</p>
                    //绑定事件
                    <button @click="on_click">点我给文周降薪</button>
                    </div>`,
        methods: {
            on_click: function () {
                //提交事件、传递参数
                Event.$emit("alex_said", this.money)
            }
        },
        //必须是这种return的数据形式
        data() {
            return {
                money: 10000,
            }
        }
    };
    let wenzhou = {
        template: `<div>
                        <p>哪吒</p>
                        {{wz_money}}
                    </div>`,
        // 加载结束后执行的
        mounted() {
            let that = this;
            Event.$on("alex_said", function (data) {
                that.wz_money = data;
                console.log(this)
            })
        },
        data() {
            return {
                wz_money: "",
            }
        }
    };
    //创建Vue根实例
    const app = new Vue({
        //制定作用域
        el: "#app",
        //注册两个局部组件
        components: {
            alex: alex,
            wenzhou: wenzhou,
        }
    })
</script>

7、mixins重复代码封装,类似于django中的母板

<div id="app">
    <popup></popup>
    <tip></tip>
</div>

<script>
    let base = {
        methods: {
            on_show: function () {
                this.show = true
            },
            on_hide: function () {
                this.show = false
            }
        },
        data() {
            return {
                show: false
            }
        }
    };
    let popup = {
        template: `<div>
                        <button @click="on_show">点我显示</button>
                        <button @click="on_hide">点我隐藏</button>
                        <p v-show="show">这是popup</p>
                   </div>`,
        mixins: [base],
        data() {
            return {
                show: true
            }
        }
    };
    let tip = {
        template: `<div>
                    <button v-on="{mouseenter: on_show, mouseleave: on_hide}">鼠标移入提示信息</button>
                    <p v-show="show">这是一个提示信息</p>
                </div>`,
        mixins: [base]
    };
    const app = new Vue({
        el: "#app",
        components: {
            popup: popup,
            tip: tip,
        }
    })
</script>

8、slot插槽

<div id="app">
    <test>
        <div slot="title"> 这是一个标题</div>
        <div slot="footer">这是底部</div>
    </test>
</div>
<template id="panel-tpl">
    <div>
        <slot name="title">1</slot>
        <hr>
        <slot name="content">2</slot>
        <hr>
        <slot name="footer">3</slot>
    </div>
</template>
<script>
    let test = {
        template: "#panel-tpl"
    };
    const app = new Vue({
        el: "#app",
        components: {
            test: test
        }
    })
</script>
相关文章
|
4天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
4天前
|
存储 JavaScript
Vue 状态管理工具vuex
Vue 状态管理工具vuex
|
10天前
|
缓存 JavaScript UED
Vue 中实现组件的懒加载
【10月更文挑战第23天】组件的懒加载是 Vue 应用中提高性能的重要手段之一。通过合理运用动态导入、路由配置等方式,可以实现组件的按需加载,减少资源浪费,提高应用的响应速度和用户体验。在实际应用中,需要根据具体情况选择合适的懒加载方式,并结合性能优化的其他措施,以打造更高效、更优质的 Vue 应用。
|
9天前
|
JavaScript
如何在 Vue 中使用具名插槽
【10月更文挑战第25天】通过使用具名插槽,你可以更好地组织和定制组件的模板结构,使组件更具灵活性和可复用性。同时,具名插槽也有助于提高代码的可读性和可维护性。
14 2
|
9天前
|
JavaScript
Vue 中的插槽
【10月更文挑战第25天】插槽的使用可以大大提高组件的复用性和灵活性,使你能够根据具体需求在组件中插入不同的内容,同时保持组件的结构和样式的一致性。
12 2
|
9天前
|
前端开发 JavaScript 容器
在 vite+vue 中使用@originjs/vite-plugin-federation 模块联邦
【10月更文挑战第25天】模块联邦是一种强大的技术,它允许将不同的微前端模块组合在一起,形成一个统一的应用。在 vite+vue 项目中,使用@originjs/vite-plugin-federation 模块联邦可以实现高效的模块共享和组合。通过本文的介绍,相信你已经了解了如何在 vite+vue 项目中使用@originjs/vite-plugin-federation 模块联邦,包括安装、配置和使用等方面。在实际开发中,你可以根据自己的需求和项目的特点,灵活地使用模块联邦,提高项目的可维护性和扩展性。
|
10天前
|
JavaScript 前端开发 UED
vue 提高 tree shaking 的效果
【10月更文挑战第23天】提高 Vue 中 Tree shaking 的效果需要综合考虑多个因素,包括模块的导出和引用方式、打包工具配置、代码结构等。通过不断地优化和调整,可以最大限度地发挥 Tree shaking 的优势,为 Vue 项目带来更好的性能和用户体验。
|
10天前
|
缓存 JavaScript UED
Vue 中异步加载模块的方式
【10月更文挑战第23天】这些异步加载模块的方式各有特点和适用场景,可以根据项目的需求和架构选择合适的方法来实现模块的异步加载,以提高应用的性能和用户体验
|
10天前
|
JavaScript 测试技术 UED
解决 Vue 项目中 Tree shaking 无法去除某些模块
【10月更文挑战第23天】解决 Vue 项目中 Tree shaking 无法去除某些模块的问题需要综合考虑多种因素,通过仔细分析、排查和优化,逐步提高 Tree shaking 的效果,为项目带来更好的性能和用户体验。同时,持续关注和学习相关技术的发展,不断探索新的解决方案,以适应不断变化的项目需求。
|
存储 前端开发 JavaScript
为什么我不再用Vue,改用React?
当我走进现代前端开发行业的时候,我做了一个每位开发人员都要做的决策:选择一个合适的框架。当时正逢 jQuery 被淘汰,前端开发者们不再用它编写难看的、非结构化的老式 JavaScript 程序了。