zoukankan      html  css  js  c++  java
  • vue.js慢速入门(2)

    4.组件使用基础

    • 什么是组件?组件可以理解为可重用的自定义HTML。
    • 可以使用一堆组件来构造大型应用,任意类型的应用界面都可以抽象为一个组件树: 

    • 可以把组件代码按照template、style、script的拆分方式,放置到对应的.vue文件中。
    • 组件预定义选项中最核心的几个:

       模板(template)、初始数据(data)、接受的外部参数(props)、方法(methods)、生命周期钩子函数(lifecycle hooks)。

    4.1 基本步骤

      使用组件首先需要创建构造器:

    var MyComponent = Vue.extend({
      // 选项...
    })

      要把这个构造器用作组件,需要用 Vue.component(tag, constructor) 注册 :

    // 全局注册组件,tag 为 my-component
    Vue.component('my-component', MyComponent)

      然后使用:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="xxx">
                <my-component></my-component>
            </div>
        </body>
        <script src="js/vue.js"></script>
        <script>
            var myComponent = Vue.extend({
                template: '<p>9898不得了!</p>'
            });
            Vue.component('my-component', myComponent);
            new Vue({
                el: '#xxx'
            });
        </script>
    </html>

      其中,

    • Vue.component('my-component', MyComponent)这种是全局注册,第一个参数是注册组件的名称,第二个参数是组件的构造函数;
    • 选项对象的template属性用于定义组件要渲染的HTML;
    • 组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。组件挂载在vue实例上才会生效。
    • 对于自定义标签名字,Vue.js 不强制要求遵循 W3C 规则(小写,并且包含一个短杠),为了避免不必要的事端尽管遵循这个规则。

     

    4.2 局部注册

      用实例选项 components 注册:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="xxx">
                <my-component></my-component>
            </div>
        </body>
        <script src="js/vue.js"></script>
        <script>
            var myComponent = Vue.extend({
                template: '<p>9898不得了!</p>'
            });
    //      Vue.component('my-component', myComponent);
            new Vue({
                el: '#xxx',
                components: {
                    'my-component': myComponent
                }
            });
        </script>
    </html>

      也可以在组件中定义并使用其他组件:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="example">
                <xx-component></xx-component>
            </div>
        </body>
        <script src="js/vue.js"></script>
        <script>
            var Child = Vue.extend({
                template: '<div>i am zai</div>',
                replace: true
            })
            var Parent = Vue.extend({
                template: '<p>i am baba</p><br/><wa></wa>',
                components: {
                    // <xx-component>只能用在父组件模板内
                    'wa': Child
                }
            })
            // 创建根实例
            new Vue({
                el: '#example',
                components: {
                    'xx-component': Parent
                }
            })
        </script>
    </html>

      其中,子组件只能在父组件的template中使用。

      另外,有简化的写法,Vue在背后会自动地调用Vue.extend():

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="xxx">
                <my-component-continue></my-component-continue>
            </div>
        </body>
        <script src="js/vue.js"></script>
        <script>
            // 局部注册的简化写法
            var vm2 = new Vue({
                el: '#xxx',
                components: {
                    'my-component': {
                        template: '<div>9898不得了!</div>'
                    },
                    'my-component-continue': {
                        template: '<div>粮食大丰收!</div>'
                    }
                }
            })
        </script>
    </html>

    4.3 组件选项问题

      在定义组件的选项时,data和el选项必须使用函数。

      如果data选项指向某个对象,这意味着所有的组件实例共用一个data。
      所以应当使用一个函数作为 data 选项,让这个函数返回一个新对象:

    Vue.component('my-component', {
    
        data: function(){
    
            return {a : 1}
    
        }
    
    })

      同理,el 选项用在 Vue.extend() 中时也须是一个函数。

     

    5.数据传递

      Vue.js组件之间有三种数据传递方式:

    • props
    • 组件通信
    • slot

    5.1 props

      “props”是组件数据的一个字段,期望从父组件传下来数据。因为组件实例的作用域是孤立的,所以子组件需要显式地用props选项来获取父组件的数据。

      Props选项可以是字面量、表达式、绑定修饰符。

    5.1.1 字面量

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <child msg="hello!"></child>
            <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
            <script type="text/javascript">
                Vue.component('child', {
                  // 声明 props
                  props: ['msg'],
                  // prop 可以用在模板内
                  // 可以用 `this.msg` 设置
                  template: '<span>{{ msg }}你困吗</span>'
                })
                new Vue({
                    el: 'body'
                })
            </script>
        </body>
    </html>

      HTML 特性不区分大小写。名字形式为 camelCase 的 prop 用作特性时,需要转为 kebab-case(短横线隔开):

    Vue.component('child', {
      // camelCase in JavaScript
      props: ['myMessage'],
      template: '<span>{{ myMessage }}</span>'
    })
    <!-- kebab-case in HTML -->
    <child my-message="hello!"></child> 

    5.1.2 动态

      类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 绑定动态 Props 到父组件的数据。每当父组件的数据变化时,也会传导给子组件。比如酱:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div>
              <input v-model="parentMsg">
              <br>
              <child :my-message="parentMsg"></child>
            </div>
            <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
            <script type="text/javascript">
                Vue.component('child', {
                    props: ['myMessage'],
                    template: '<span>{{ myMessage }}你困吗</span>'
                })
                new Vue({
                    el: 'body',
                    data:{
                        parentMsg:''
                    }
                })
            </script>
        </body>
    </html>

      当我在input里面输入哈哈的时候:

    5.1.3 绑定类型

      可以使用绑定修饰符:

    • .sync,双向绑定
    • .once,单次绑定
    <!-- 默认为单向绑定 -->
    <child :msg="parentMsg"></child>
    
    <!-- 双向绑定 -->
    <child :msg.sync="parentMsg"></child>
    
    <!-- 单次绑定 -->
    <child :msg.once="parentMsg"></child>

      prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。

      不过需要注意的是:如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。

      示例:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="app">
    
                <table>
                    <tr>
                        <th colspan="3">父组件数据</td>
                    </tr>
                    <tr>
                        <td>name</td>
                        <td>{{ name }}</td>
                        <td><input type="text" v-model="name" /></td>
                    </tr>
                    <tr>
                        <td>age</td>
                        <td>{{ age }}</td>
                        <td><input type="text" v-model="age" /></td>
                    </tr>
                </table>
            
                <my-component v-bind:my-name.sync="name" v-bind:my-age="age"></my-component>
            </div>
            
            <template id="myComponent">
                <table>
                    <tr>
                        <th colspan="3">子组件数据</td>
                    </tr>
                    <tr>
                        <td>my name</td>
                        <td>{{ myName }}</td>
                        <td><input type="text" v-model="myName" /></td>
                    </tr>
                    <tr>
                        <td>my age</td>
                        <td>{{ myAge }}</td>
                        <td><input type="text" v-model="myAge" /></td>
                    </tr>
                </table>
            </template>
            <script src="js/vue.js"></script>
            <script>
                var vm = new Vue({
                    el: '#app',
                    data: {
                        name: 'k',
                        age: 24
                    },
                    components: {
                        'my-component': {
                            template: '#myComponent',
                            props: ['myName', 'myAge']
                        }
                    }
                })
            </script>
        </body>
    </html>

      上面这段设置了名字双向,年龄单向:

      以下是一个大神的综合示例:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
        </head>
        <body>
            <div id="app">
    
                <table>
                    <tr>
                        <th colspan="3">父组件数据</td>
                    </tr>
                    <tr>
                        <td>name</td>
                        <td>{{ name }}</td>
                        <td><input type="text" v-model="name" /></td>
                    </tr>
                    <tr>
                        <td>age</td>
                        <td>{{ age }}</td>
                        <td><input type="text" v-model="age" /></td>
                    </tr>
                </table>
            
                <my-component v-bind:my-name.sync="name" v-bind:my-age="age"></my-component>
            </div>
            
            <template id="myComponent">
                <table>
                    <tr>
                        <th colspan="3">子组件数据</td>
                    </tr>
                    <tr>
                        <td>my name</td>
                        <td>{{ myName }}</td>
                        <td><input type="text" v-model="myName" /></td>
                    </tr>
                    <tr>
                        <td>my age</td>
                        <td>{{ myAge }}</td>
                        <td><input type="text" v-model="myAge" /></td>
                    </tr>
                </table>
            </template>
            <script src="js/vue.js"></script>
            <script>
                var vm = new Vue({
                    el: '#app',
                    data: {
                        name: 'k',
                        age: 24
                    },
                    components: {
                        'my-component': {
                            template: '#myComponent',
                            props: ['myName', 'myAge']
                        }
                    }
                })
            </script>
        </body>
    </html>

      可以检索:

      其中, 

    {{ col | capitalize}}

      过滤,首字母大写。

    <tr v-for="entry in data | filterBy filterKey">
    
      <td v-for="col in columns">
    
        {{entry[col]}}
    
      </td>
    
    </tr>

      过滤搜索关键词;

      双循环,tr循环data条数,4行,entry表示每行;td循环columns数量,3列,col表示每列,entry[col]取具体数据。

    props: {
    
      data: Array,
    
      columns: Array,
    
      filterKey: String
    
    }

      验证:父组件传递过来的data和columns必须是Array类型,filterKey必须是字符串类型。

      验证要求示例:

    Vue.component('example', {
      props: {
        // 基础类型检测 (`null` 意思是任何类型都可以)
        propA: Number,
        // 多种类型 (1.0.21+)
        propM: [String, Number],
        // 必需且是字符串
        propB: {
          type: String,
          required: true
        },
        // 数字,有默认值
        propC: {
          type: Number,
          default: 100
        },
        // 对象/数组的默认值应当由一个函数返回
        propD: {
          type: Object,
          default: function () {
            return { msg: 'hello' }
          }
        },
        // 指定这个 prop 为双向绑定
        // 如果绑定类型不对将抛出一条警告
        propE: {
          twoWay: true
        },
        // 自定义验证函数
        propF: {
          validator: function (value) {
            return value > 10
          }
        },
        // 转换函数(1.0.12 新增)
        // 在设置值之前转换值
        propG: {
          coerce: function (val) {
            return val + '' // 将值转换为字符串
          }
        },
        propH: {
          coerce: function (val) {
            return JSON.parse(val) // 将 JSON 字符串转换为对象
          }
        }
      }
    })

      Stringtype 可以是下面原生构造器:

    • Number
    • Boolean
    • Function
    • Object
    • Array

      type 也可以是一个自定义构造器,使用 instanceof 检测。

      当 prop 验证失败时,Vue 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。

     

    参考:http://www.cnblogs.com/keepfool/p/5625583.html

      《vue.js权威指南》

     

  • 相关阅读:
    GIS重要概念与术语——矢量数据分析
    后台获取存储过程返回的数据(转)
    java集合map,set,list区别
    安装jdk配置环境变量并测试java
    使用JAVA读写Properties属性文件
    对象(含有java.util.Date),集合等转换成json
    SSH自我理解实质
    Hibernate中createCriteria即QBC查询的详细用法
    用Java递归来求N的阶层
    java this的使用
  • 原文地址:https://www.cnblogs.com/xulei1992/p/6031138.html
Copyright © 2011-2022 走看看