Your browser does not support the Canvas element.

VUE 之 组件

组件是为了解决页面布局的。

什么是单页面?

  答:整个页面的切换都是在这个页面上进行变化的,没有页面的刷新。

1、全局组件

  1.1全局组件流程:    1.创建全局组件======>创建一个Vue实例

  

<div id="app">
    <global-component></global-component>      # 第一种渲染<global-component>的方法。流程:1>全局组件中有一个global-component参数,此时就开始查。2>查到new Vue中的app有                                                                        
</div> # global-component标签,此时就会将data中的数据传给template中进行替换。由于自定义的标签在<div id='app'>中包着,所以生成的页 <script> # 也有div包着 Vue.component("global-component",{ template:`<div><h1>{{name}}</h1></div>`, data(){ return { name:'我叫小沈阳' } } }); new Vue({ el:'#app', // template:`<global-component></global-component>` # 第二种渲染方法 由于Vue根实例中有了template来承载自定义的标签,div顶部中就不需要写自定义标签了。而此时就会把Vue }) # 实例中自定义的标签作为根,在这个标签中进行渲染数据。

2、局部组件

  局部组件实际上就是创建了一个JavaScript object

  局部组件的执行流程: 创建一个局部组件(let 变量)=====>然后创建一个Vue根实例。 =====>创建一个入口app来承载本来应该在Vue实例中的代码,为了是代码更加清晰。

             内部的三大步骤:创建局部组件====>注册(components)=====>使用

<div id='app'>
</div>
let Header = { template:`
<div><h1>{{greeting}}</h1></div>`, # let Header 就是创建一个局部组件,内部除了没有el属性,其他属性都可以写。必须要有承载标签的template data(){ return{ greeting:'HELLO World' } } }; let App = { # 创建一个App入口,内部注册一个app_header标签指向Header,然后用template承载该标签。 template:`<div><app_header></app_header></div>`, components:{ app_header:Header } }; new Vue({ # 创建一个Vue根实例 注册一个 属性名:指向App,在template中承载该标签。 el:"#app", template:`<div><APP></APP></div>`, components:{ APP:App } })

 3、父子组件通信

  父组件如何给子组件传送数据

<div id="app">

    </div>
    <script>
        let Son = {                                                     1、# 先定义自一个局部组件
            template:`<div>
                        <h1>{{greeting}}</h1>
                        <h2>{{father}}</h2>                  7、#将数据交给template进行渲染 
                      </div>`,
            props:['father'],                          6、# 子组件中通过props:[],这种形式来接收父组件传送来的数据
            data(){
                return{
                    greeting:'Hello World'
                }
            }

        };
        let App = {                                    2、# 再定义一个入口组件注册局部组件         
            template:`<div>
                        <my_son v-bind:father="fatherData"></my_son>   5、# 给注册的属性绑定一个字定义属性,father
                      </div>`,
            components:{
                my_son:Son
            },
            data(){                                4、# 将数据赋值给自定义的属性father
                return{
                    fatherData:'Who are you!'
                }
            }
        };
        new Vue({                                                        3、# 创建一个Vue实例,注册所有组件的入口组件
            el:"#app",
            template:`<App></App>`,
            components:{
                App
            }
        })
    </script>

4、子父组件的通信

  子组件如何将数据传送给父组件

  业务要求:点击子组件让父组件的字体变大

<div id="app"></div>
    <script>
        let Son = {                                                                     1、# 创建一个子组件 
            template:`<div>
                        <button @click="Son_Click">点我就会变大</button>
                      </div>`,
            methods:{                                                                   9、# 只要绑定事件就用methods,然后通过this.$emit('自定义父组件中的事件',参数)
                Son_Click:function () {
                    this.$emit('change_size',0.1)
                }
            }
        };
        let Father = {                                                                  2、# 创建一个入口父组件
            template:`<div>
                       <span :style="{fontSize:postFontSize + 'em'}">我是你爸爸</span>    11、# 通过参数的传递使得字体发生变化,在template中渲染出来。
                       <my_son @change_size="fatherClick"></my_son>                     5、# 生成自定义的标签,并绑定一个自定义的点击事件,这个change_size就是自定义的,相当于
                      </div>`,                                                               click,父组件绑定字定义点击事件是用来监听父组件是否发生变化
            components:{                                                                4、# 注册子组件
                my_son:Son
            }, 
            data(){                                                                     6、# 传送数据,设定posFontSize 默认字体大小为1 
              return{
                  postFontSize:1
              }
            },
            methods:{                                                                   7、# 由于绑定了事件,所以要用methods方法,然后自定义一个fatherClick函数 赋值给自定义事件                                                                
                fatherClick:function (value) {                                          10、# value 用来接收子组件传过来的参数。
                    this.postFontSize += value
                }
            }

        };
        new Vue({                                                                       3、# 创建一个Vue实例 
            el:'#app',
            template:`<Father></Father>`,
            components:{
                Father
            }
        })
    </script>

5、非子父之间通信(用中间调度器)

 <script>
        let hanfei = new Vue();       // 中间调度器什么都不传
        let B = {
            template: `<div>
                        <h1>这是B</h1>
                        <button @click="my_click">点我向A说话</button>
                        </div>`,
            methods: {
                my_click: function () {
                    console.log("")
                    // 向A说话
                    // 向中间调度器提交事件
                    hanfei.$emit("maweihua_say", "晚上等我一起吃饭~~~")        // 组件向中间调度器提交过来的数据用$emit
                }
            }
        };
        let A = {
            template: `<div><h1>这是A</h1>{{say}}</div>`,
            data(){
              return {
                  say: ""
              }
            },
            mounted(){
                // 监听中间调度器中的方法
                let that = this;
                hanfei.$on("maweihua_say", function (data) {        //中间调度器向组件提交数据的时候用$on
                    console.log(data)
                    that.say = data
                })
            }
        };

        const app = new Vue({
            el: "#app",
            components: {
                A,
                B
            }
        })

    </script>

 

6、混入(mixs)

  由于有多个组件存在且有使用相同的可能是数据,也可能是方法时,就可以用混入mixs来封装这个数据或者方法,然后在其他组件调用即可。

<div id="app"></div>
<script> 
    let mixs = {                                                              # 由于都使用了show方法,所以创建一个mixs组件用来封装这些属性 
        methods: {
            show: function () {
                console.log('我来了')
            }
        }
    };
    let A = {                                                                  # 创建组件A
template: `
<div> <button @click="show">点我</button> # 使用了show这个方法 </div>`, mixins: [mixs], # 通过固定搭配 mixins:[mixs]调用 mixs这个组件 }; let B = { # 创建组件B template: `<div> <button @mouseenter="show">触摸我</button>         # 使用了show这个方法 </div>`, mixins: [mixs], }; new Vue({ # 创建Vue实例 el: "#app", template: `<div> <A></A> <B></B> </div>`, components: { A:A, B:B } }) </script>

7、插槽

  插槽可以进行内容的分发,提高组件的复用性。相同的组件写多个块,就可以用插槽,写一个组件,然后通过slot进行内容分发,来提高复用性。

<div id="app">
        <global-component>我佛</global-component>            # 同相同的<global-component>标签可以写多个块
        <global-component>慈悲</global-component>
    </div>
    <script>
        Vue.component("global-component",{
            template:`<div><slot></slot></div>`,            # 可以通过slot进行数据分发,将多个块中的内容,而不是标签分发给template进行渲染
        });
        new Vue({
            el:'#app',
        })
    </script>

8、具名插槽

  也是插槽的一种,它是将所有的slot标签包在了自己定义的里边

<div id="app">
        <global-component>
            <div slot="header">首页</div>
            <div slot="first">第一页</div>
            <div slot="second">第二页</div>
        </global-component>
    </div>
    <script>
        Vue.component("global-component",{
            template:`<div> 
                        <slot name="header"></slot>           # name 是slot中的夫定的写法
                        <slot name="first"></slot>
                        <slot name="second"></slot>
                      </div>`,
        });
        new Vue({
            el:'#app',
        })
    </script>

 

  

 

posted @ 2018-11-08 18:05  一根小菜  阅读(290)  评论(0编辑  收藏  举报
Your browser does not support the Canvas element.