美文网首页
Vue的组件

Vue的组件

作者: SlashBoyMr_wang | 来源:发表于2018-08-25 21:13 被阅读0次

    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>
    

    相关文章

      网友评论

          本文标题:Vue的组件

          本文链接:https://www.haomeiwen.com/subject/eiagiftx.html