vue组件

组件使用的细节点

is的使用

<div id="app">
    <table>
        <tbody>
            <tr is="row"></tr>
            <row></row>
            <row></row>
        </tbody>
    </table>
</div>

<script>
    Vue.component("row", {
        template: "<tr><td>this is a row</td></tr>"
    })

    var app = new Vue({
        el: "#app",

    })

通过浏览器查看网页源码,使用了is=row的标签进行了正常的输出,

两外两个标签渲染的位置有误(不同浏览器可能不同)

子组件数据

在子组件中,data是一个函数,必须返回一个对象

Vue.component("row", {
    data: function() {
        return {
            content: "this is a row"
        }
    },
    template: "<tr><td>{{content}}</td></tr>"
})

ref引用

通过使用ref来进行两个数字的相加

<body>
    <div id="app">
        <counter ref="one" @change="handleChange"></counter>
        <counter ref="two" @change="handleChange"></counter>
        <div>{{total}}</div>
    </div>

    <script>
        Vue.component("counter", {
            data: function() {
                return {
                    content: 0
                }
            },
            template: "<div @click='handleClick'>{{content}}</div>",
            methods: {
                handleClick: function () {
                    this.content++;
                    this.$emit("change")
                }
            }
        })

        var app = new Vue({
            el: "#app",
            data: {
              total: 0
            },
            methods: {
                handleChange: function () {
                    this.total = this.$refs.one.content + this.$refs.two.content
                }
            }
        })
    </script>
</body>

父子组件传值

父传子

子组件中不能直接修改父组件中传递过来的数据(单项数据流)

<div id="app">
    <counter :content="0"></counter>
    <counter :content="0"></counter>
    <div>{{total}}</div>
</div>

<script>
    var counter = {
        props: ['content'],
        data: function() {
            return {
                num: this.content
            }
        },
        template: "<div @click='handleClick'>{{num}}</div>",
        methods: {
            handleClick: function () {
                this.num ++;
            }
        }
    }

子传父

通过事件触发的形式来进行传值

    <div id="app">
        <counter :content="0" @inc="handleChange"></counter>
        <counter :content="0" @inc="handleChange"></counter>
        <div>{{total}}</div>
    </div>

    <script>
        var counter = {
            props: ['content'],
            data: function() {
                return {
                    num: this.content
                }
            },
            template: "<div @click='handleClick'>{{num}}</div>",
            methods: {
                handleClick: function () {
                    this.num +=2;
                    this.$emit("inc", 2)
                }
            }
        }

        var app = new Vue({
            el: "#app",
            data: {
              total: 0
            },
            methods: {
                handleChange: function (step) {
                    this.total += step
                }
            },
            components: {
                "counter": counter
            }
        })
    </script>

prop验证

Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 匹配任何类型)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组且一定会从一个工厂函数返回默认值
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

插槽

<body>
    <div id="app">
        <row>
            <!--<div slot="header"></div>-->
            <div slot="footer">fotter</div>
        </row>
    </div>

    <script>
        Vue.component("row", {
            template: `<div>
                            <slot name="header">
                                <div>
                                    default
                                </div>
                            </slot>
                            <div>content</div>
                            <slot name="footer"></slot>
                        </div>`
        })

        var app = new Vue({
            el: "#app",

        })
    </script>
</body>

取消header的注释,div中的default就会消失

作用域插槽

<body>
    <div id="app">
        <child>
            <template slot-scope="props">
                <div>{{props.item}}</div>
            </template>
        </child>
    </div>

    <script>
        Vue.component("child", {
            data: function() {
              return {
                  list: [1, 2, 3, 4, 5]
              }
            },
            template: `<div>
                            <ul>
                                <slot v-for="item in list"
                                :item="item">
                                </slot>
                            </ul>
                        </div>`
        })

        var app = new Vue({
            el: "#app",

        })
    </script>
</body>

动态组件

    <div id="app">
        <component :is="type"></component>
        <!--<child-one v-if="type === 'child-one'"></child-one>-->
        <!--<child-two v-if="type === 'child-two'"></child-two>-->
        <button @click="handleClick">change</button>
    </div>

    <script>
        Vue.component("child-one", {
            template: "<div>child one</div>"
        })

        Vue.component("child-two", {
            template: "<div>child two</div>"
        })

        var app = new Vue({
            el: "#app",
            data: {
                "show": true,
                type: "child-one"
            },
            methods: {
                handleClick: function () {
                    this.type = (this.type === 'child-one' ? 'child-two':'child-one')
                }
            }
        })
    </script>

被注释的内容效果和<component :is="type"></component>效果是一样的

Vue.component("child-one", {
            template: "<div v-once>child one</div>"
        })

        Vue.component("child-two", {
            template: "<div v-once>child two</div>"
        })

当使用了v-once后,组件中的内容会被渲染成静态文本

posted @ 2018-07-19 19:22  寒菱  阅读(112)  评论(0编辑  收藏  举报