Vue.js 的学习(四)

vuejs 李宜发

第四章Vue.js 的组件

1.基本概念

1.1组件是一个可复用的Vue实例,需要挂载到Vue的实例

1.2组件除了el选项外,同样包括有data、computed、watch、methods 以及生命周期钩子等。

2定义组件

<div id="app">
        <button-counter></button-counter>
    </div>
    <script>
        var compoent1 = {
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="count++">点击了{{ count }} 次.</button>'
        }
        Vue.component("button-counter", compoent1);
        var vm = new Vue({
            el: "#app"
        });
    </script>

2.1组件的data和Vue实例有区别

2.1.1组件通过一个函数返回一个对象

2.1.2Vue实例是对象

2.2el的区别

2.2.1组件没有el选项

2.2.2Vue实例有el选项

2.3html元素

2.3.1组件的html元素定义在template属性上

2.3.2Vue实例通过el指定挂载的位置

3注册组件到Vue实例

3.1全局注册

<div id="app">
        <button-counter></button-counter>
    </div>
    <script>
        var compoent1 = {
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="count++">点击了{{ count }} 次.</button>'
        }
        Vue.component("button-counter", compoent1);
        var vm = new Vue({
            el: "#app"
        });
    </script>
3.1.1.1通过组件名称应用组件 <button-counter></button-counter>
3.1.1.2每个组件都是独立的,互不影响。这样组件都可以重用了,维护起来会非常方便。

3.2组件名要求

3.2.1kebab-case 短横线隔开

例如:my-component-name
使用的时候 <my-component-name></my-component-name>

3.2.2PascalCase 帕斯卡命名|大驼峰|

例如:MyComponentName
使用 <my-component-name>(推荐)
使用 <MyComponentName>(错误)
总结:组件名称最好全部采用小写,因为html标签始终都是小写的。只有html的名称与组件一致才匹配。另外一种方式组件名采用大驼峰命名,表签名每个单词用短横杠分隔。推荐组名名小写,因为html的标签名始终都是小写方式渲染的,这样就可以避免不必要的麻烦

3.3局部注册 定义在components上

<script>
        new Vue({
            el: '#app',
            components: {
                'component-a': ComponentA,
                'component-b': ComponentB
            }
        })
    </script>

3.3.1属性名就是自定义元素的名字,属性值就是这个组件的选项对象。

3.3.2注意:局部注册的组件在其子组件中不可用。

3.3.3在子组件中注册其它的组件

<script>
        var ComponentA = { /* ... */ }

        var ComponentB = {
            components: {
                'component-a': ComponentA
            },
            // ...
        }
    </script>

4.props-父组件先子组件传递数据

4.1props 数组。

<div id="app">
        <course-item coursename="善良的死神"></course-item>
    </div>
    <script>
        var courseListComponent = {
            props: ['coursename'],
            template: '<p>{{ coursename }}</p>'
        }
        var vm = new Vue({
            el: "#app",
            components: {
                'course-item': courseListComponent
            }
        });
    </script>
注意:coursename="善良的死神" 和 coursename="1" 传递的是字符串类型,而不是数字。如果非要传递数字采用绑定的方式传递,例如::coursename="1" ,因为v-bind的表达式是js表达式,所以1会当作数字看待

4.2props 对象。

<div>
        <compoent :number="18"></compoent>
    </div>
    <script>
        // 对象语法,提供校验
        Vue.component('props-demo-advanced', {
            props: {
                // 检测类型
                height: Number,
                // 检测类型 + 其他验证
                age: {
                    type: Number,//数据类型
                    default: 0,//默认值
                    required: true,//required是否必须
                    validator: function (value) {//validator 校验器
                        return value >= 18
                    }
                }
            }
        })
    </script>

4.3注意命名

4.3.1全部小写 节点上的名称与属性的名一致

<div id="app">
        <course-item coursename="善良的死神"></course-item>
    </div>
    <script>
        var courseListComponent = {
            props: ['coursename'],
            template: '<p>{{ coursename }}</p>'
        }
        var vm = new Vue({
            el: "#app",
            components: {
                'course-item': courseListComponent
            }
        });
    </script>

4.3.2小驼峰命名 节点上要使用短横线隔开

<div id="app">
        <course-item course-name="善良的死神"></course-item>
    </div>
    <script>
        var courseListComponent = {
            props: ['courseName'], // course-name大小写没有关系或者course-Name也可以
            template: '<p>{{ courseName }}</p>'
        }
        var vm = new Vue({
            el: "#app",
            components: {
                'course-item': courseListComponent
            }
        });
    </script>

5.通过自定义事件向父级组件发送消息

5.1在vue.js中,可以使用$emit自定义事件

语法 $emit("事件名","事件传递的数据")
<div id="app">
        <stu-content @left-length="leftNumber=$event"></stu-content>//在事件处理上,使用$event获取返回来的值
        <p>剩余字数{{leftNumber}}</p>
    </div>
    <script>
        var component1 = {
            data: function () {
                return {
                    content: '',
                    maxLength: 50,
                }
            },
            template: '<textarea v-model="content" ></textarea>',//是父组件上使用v-model绑定事件
            watch: {
                content: function (newValue, oldValue) {
                    var len = newValue.length;
                    var leftLength = this.maxLength - len;
                    this.$emit("left-length", leftLength);
                }
            }
        }
        var vm = new Vue({
            el: "#app",
            data: {
                leftNumber: 50,
            },
            components: {
                'stu-content': component1
            }
        });
        //事件名称自定义,最好采用短横线,例如:left-input
    </script>

5.2使用v-model

 <div id="app">
        <stu-content v-model="leftNumber"></stu-content>//使用v-model接收事件处理的结果。
        <p>剩余字数{{leftNumber}}</p>
    </div>
    <script>
        var component1 = {
            data: function () {
                return {
                    content: '',
                    maxLength: 50,
                }
            },
            template: '<textarea v-model="content" ></textarea>',
            watch: {
                content: function (newValue, oldValue) {
                    var len = newValue.length;
                    var leftLength = this.maxLength - len;
                    this.$emit("input", leftLength);//修改事件名称为input
                }
            }
        }
        var vm = new Vue({
            el: "#app",
            data: {
                leftNumber: 50,
            },
            components: {
                'stu-content': component1
            }
        });
    </script>
v-model实际上是 @input="value=$event" 操作的语法糖。由此可见只需要在子组件的事件名定义为input即可

6.通过插槽分发内容

6.1期望组件之间的内容传入到组件里,如何做?

<div id="app">
        <stu-content v-model="leftNumber">500</stu-content>//使用<slot>获取组件之间的内容
        <p>剩余字数{{leftNumber}}</p>
    </div>
    <script>
        var component1 = {
            data: function () {
                return {
                    content: '',
                    maxLength: 50,
                }
            },
            template: '<div><textarea v-model="content" ></textarea><p>限输入<slot></slot>字</P></div>',
            watch: {
                content: function (newValue, oldValue) {
                    var len = newValue.length;
                    var leftLength = this.maxLength - len;
                    this.$emit("input", leftLength);
                }
            }
        }
        var vm = new Vue({
            el: "#app",
            data: {
                leftNumber: 50,
            },
            components: {
                'stu-content': component1
            }
        });
    </script>

6.2具名插槽

<div id="app">
        <slot-commponent>hello vue.js</slot-commponent>
    </div>
    <script>
        var component1 = {
            template: '<div><p>默认插槽的内容来自,标签之间的内容</P><slot></slot></div>'
        }
        var vm = new Vue({
            el: "#app",
            components: {
                'slot-commponent': component,
            }
        });
    </script>

还能输出{{restrictNumber}}个字符  
  • {{reply.author}}

    {{CommonUtil.formateDate(reply.ac_CommentDate).shortTime}}
  • 回复了{{Comments.author}} :