Vue study notes (seven) components

0, Getting Started

Before officially explain the components, we first look at a simple example:

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
    <div id="app">
        <button-counter></button-counter>
    </div>

    <script>
        Vue.component('button-counter', {
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="count++">{{ count }} times</button>'
        })
        new Vue({
            el: '#app',
        })
    </script>
</body>


</html>

Let's take a closer look at the above code is this:

Vue.component('button-counter', {
    data: function () {
        return {
            count: 0
        }
    },
    template: '<button v-on:click="count++">{{ count }} times</button>'
})

We first global method Vue.component()creates a global component called the button-counter

The first method is a parameter of the component name, the second parameter is an option object, the object contains two attributes, dataandtemplate

Property datais a function of target returns for dynamic data storage

The reason defined as a function, because the components may be used to create multiple instances, if defined as an object, all instances will share the same data objects

Property templateis a template string , HTML code that defines the component

It should be noted that the components must be a single root element , that is to say the content of the template must be wrapped within a parent element

new Vue({
    el: '#app',
})
<div id="app">
    <button-counter></button-counter>
</div>

Then, we can pass in a new Vue()root instance created in this component as a custom elements use

Well, after a preliminary understanding of the components have, here we come to learn in detail

1, component registration

Examples of components are reusable Vue, before using the component, the component we must first be registered in order to be able to be identified Vue

(1) There are two component registration parameters, namely the component names and options object

  • Component Name

Defined component name in two ways, namely kebab-case (separated by a dash named) and PascalCase (named after the first letter capitalized)

kebab-case: when referring to, also need to use the kebab-case

PascalCase: When you use the template, both nomenclature are available; when used in the DOM, only kebab-case is valid

  • Options object

Options with the object received by new Vue()the received option is similar, the only exception is as eloptions such instances root-specific

(2) The component registration There are two ways, namely, global registration and local register

  • Global registration

We can use the global method Vue.component()globally registered, the first parameter of the method is the component name, the second parameter is the options object

Component global registration can be used in any instance root Vue newly created

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })

new Vue({ el: '#app' })
  • Local registration

We can use when creating a root instance option componentsfor local registration, it is an object, is the key component name, the value of the option is subject

Registered partial assembly can not be used in its subassembly, i.e., the following example two components can not call each other inside each

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }

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

If you want ComponentAin ComponentBavailable, we will need to change a wording:

var ComponentA = { /* ... */ }

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

2, the data is transmitted to the sub-assembly - prop

prop some custom properties in the component registration, when a characteristic value is passed to a prop, it becomes an attribute of that component instance

(1) passes static prop

In the following example, we pass to prop up a static value,Title Here

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
    <div id="app">
        <title-item title="Title Here"></title-item>
    </div>

    <script>
        Vue.component('title-item', {
            props: ['title'],
            template: '<h3>{{ title }}</h3>'
        })
        new Vue({
            el: '#app'
        })
    </script>
</body>


</html>

(2) deliver dynamic prop

In the following example, we passed v-bindbind a dynamic object to the prop,content

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
    <div id="app">
        <title-item v-bind:title="content.title"></title-item>
    </div>

    <script>
        Vue.component('title-item', {
            props: ['title'],
            template: '<h3>{{ title }}</h3>'
        })
        new Vue({
            el: '#app',
            data: {
                content: {
                    'title': 'Title Here'
                }
            }
        })
    </script>
</body>


</html>

(. 3) and prop prop type validation

In the two examples above, props is an array of strings, each of which is a string prop

But in fact, prop may also be other types

Then we can list objects with prop, which is the name of the object key prop of the value of the object is of type prop

Vue.component('my-component', {
    props: {
        propA: String,
        propB: Number,
        propC: Boolean,
        propD: Array,
        propE: Object,
        propF: Function
        // ...
    },
    // ...
})

Since the prop with the type, it is necessary to determine whether the type of prop, we can customize the prop of authentication (The following is an example of an official document)

Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    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
      }
    }
  }
})

When prop verification fails, (development environment to build versions) Vue will generate a warning console

3, pass data to the parent component - Custom Event

prop is a unidirectional downlink binding, i.e. update the parent will flow down to prop the subassembly, but not vice versa

If sub-assemblies should pass the data to the parent component, you need to use custom events

Parent component can be v-onany event listener sub-component instances, and sub-assemblies can $emit()trigger events

(1) monitor sub-component events

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
    <div id="app">
        <p>{{ total }}</p>
        <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>

    <script>
        Vue.component('button-counter', {
            template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
            data: function () {
                return {
                    counter: 0
                }
            },
            methods: {
                incrementHandler: function () {
                    this.counter += 1
                    this.$emit('increment')
                }
            },
        })
        new Vue({
            el: '#app',
            data: {
                total: 0
            },
            methods: {
                incrementTotal: function () {
                    this.total += 1
                }
            }
        })
    </script>
</body>


</html>

Let's look at a detailed explanation of the code above:

Vue.component('button-counter', {
    template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
    data: function () {
        return {
            counter: 0
        }
    },
    methods: {
        incrementHandler: function () {
            this.counter += 1
            this.$emit('increment')
        }
    },
})

First, we define a component called the button-counter

Subcomponents button-counter use v-onlistens native event click, the event handler isincrementHandler()

In incrementHandler(), first (data subassemblies) counter value plus 1, then trigger a custom event increment

<div id="app">
    <p>{{ total }}</p>
    <button-counter v-on:increment="incrementTotal"></button-counter>
</div>
new Vue({
    el: '#app',
    data: {
        total: 0
    },
    methods: {
        incrementTotal: function () {
            this.total += 1
        }
    }
})

Also root component by v-onlistening custom event increment, the event handler isincrementTotal()

In incrementTotal(), the value of total (root component in the data) plus 1

(2) throws a value by event

We can $emit()throw a value of the second argument to the function in

Vue.component('button-counter', {
    template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
    data: function () {
        return {
            counter: 0
        }
    },
    methods: {
        incrementHandler: function () {
            this.counter += 1
            this.$emit('increment', 2)
        }
    },
})

And receiving the value of the first parameter of the event handler

new Vue({
    el: '#app',
    data: {
        total: 0
    },
    methods: {
        incrementTotal: function (value) {
            this.total += value
        }
    }
})

Guess you like

Origin www.cnblogs.com/wsmrzx/p/11210400.html