组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重用的代码。

  组件:为了拆分Vue实例的代码量,以不同的组件来划分不同的功能模块,需要什么样的功能,可以去调用对应的组件。

  模块化和组件化的区别:

  ◊ 模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一。

  ◊ 组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用。  

2. 注册组件

  Vue.js提供两种组件注册方式:全局注册和局部注册。

2.1 全局组件

  全局注册需要在根实例初始化之前注册,这样组件才能在任意实例中被使用。

  注册全局组件语法格式:

Vue.component(tagName, options)

  其中,tagName 为组件名,options 为配置选项。

  这条语句需要写在var vm = new Vue({ options })之前。

  注册组件后调用方式:

<tagName></tagName>

  所有实例都能用全局组件。

  组件名定义方式:PascalCase和kebab-case。在组件命名时可以采用PascalCase或kebab-case,但在DOM中只能使用kebab-case。

  PascalCase示例:

<div id="app">
    <my-component></my-component>
</div>
<script>
    Vue.component('MyComponent', {
        template: '<div>标题</div>'
    });

    var vm = new Vue({
        el: "#app"
    });
</script>

  kebab-case示例:

<div id="app">
    <my-component></my-component>
</div>
<script>
    Vue.component('my-component', {
        template: '<div>标题</div>'
    });

    var vm = new Vue({
        el: "#app"
    });
</script>
<div id="app">
    <home></home>
</div>
<script>
    Vue.component("home", {
        template: "<div>{{text}}</div>",
        data: function () {
            return {
                text: "主页"
            };
        }
    });

    new Vue({
        el: "#app"
    });
</script>
<div id="app">
    <home></home>
</div>
<script>
    var homeTpl = Vue.extend({ 
        template: "<div>{{text}}</div>",
        data: function () {
            return {
                text: "主页"
            };
        }
    });

    Vue.component('home', homeTpl);

    new Vue({
        el: "#app"
    });
</script>

  使用template标签:

<div id="app">
    <home></home>
</div>
<template id="tpl">
    <div>{{text}}</div>
</template>
<script>
    Vue.component("home", {
        template: "#tpl",
        data: function () {
            return {
                text: "主页"
            };
        }
    });

    new Vue({
        el: "#app"
    });
</script>

2.2 局部组件

  局部组件只能在被注册的组件中使用,不能在其他组件中使用。

<div id="app">
    <home></home>
</div>
<script>
    new Vue({
        el: "#app",
        components: {
            "home": {
                template: "<div>{{text}}</div>",
                data: function () {
                    return {
                        text: "主页"
                    };
                }
            }
        }
    });
</script>

2.3 Vue.extend

2.3.1 基本使用

<div id="app">
    <home></home>
</div>
<script>
    var home = Vue.extend({
        template: "<div>标题</div>"
    });

    Vue.component("home", home);

    new Vue({
        el: "#app"
    });
</script>

2.3.2 参数data

  data:在 Vue.extend() 中必须是函数。

<body>
    <task></task>

    <script>
        var task = Vue.extend({
            template:"<div>{{ taskName }}</div>",
            data:function(){
                return {
                    taskName:"任务名称"
                }
            }
        });

        new task().$mount("task");
    </script>
</body>

2.3.3 使用$mount

  在实例中没有el选项时,可通过mount挂载。

  mount:挂载,将vue实例挂靠在某个dom元素上的一个过程。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>libing.vue</title>
    <script src="node_modules/vue/dist/vue.min.js"></script>
</head>

<body>
    <div id="app"></div>
    <script>
        var home = Vue.extend({
            template: "<div>标题</div>"
        });

        new home().$mount("#app");
    </script>
</body>

</html>

3. 组件通信

3.1 props:父组件向子组件传递数据

  prop 是组件用来传递数据的自定义特性,在组件上注册自定义属性。

  prop特性注册成为组件实例的属性。

   props :父组件向子组件传递数据。

  一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

3.1.1 静态props

  示例:

<div id="app">
    <home text="主页"></home>
</div>
<script>
    var homeTpl = Vue.extend({
        props:["text"],
        template: "<div>{{text}}</div>"
    });

    Vue.component('home', homeTpl);

    new Vue({
        el: "#app"
    });
</script>

3.1.2 动态props

  使用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件。

<div id="app">
    <home v-bind:text="text"></home>
</div>
<script>
    var homeTpl = Vue.extend({
        props: ["text"],
        template: "<div>{{text}}</div>"
    });

    Vue.component('home', homeTpl);

    new Vue({
        el: "#app",
        data: {
            text: "主页"
        }
    });
</script>

  由于HTML Attribute不区分大小写,当使用DOM模板时,camelCase的props名称要转为kebab-case。

<div id="app">
    <home warning-text="提示信息"></home>
</div>
<script>
    Vue.component('home', {
        props: ['warningText'],
        template: '<div>{{ warningText }}</div>'
    });

    var vm = new Vue({
        el: "#app"
    });
</script>

  传递的数据可以是来自父级的动态数据,使用指令v-bind来动态绑定props的值,当父组件的数据变化时,也会传递给子组件。

<div id="app">
    <home v-bind:warning-text="warningText"></home>
</div>
<script>
    Vue.component('home', {
        props: ['warningText'],
        template: '<div>{{ warningText }}</div>'
    });

    var vm = new Vue({
        el: "#app",
        data: {
            warningText: '提示信息'
        }
    });
</script>

注:prop 是单向传递,当父组件的属性变化时,将传递给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态。

  示例:

<template>
  <li>{{ id }}-{{ text }}</li>
</template>
<script>
export default {
  name: "TodoItem",
  props: ["id", "text"]
};
</script>
TodoItem.vue

相关文章:

  • 2021-08-20
  • 2021-09-08
  • 2021-06-02
  • 2021-09-11
  • 2021-11-28
  • 2021-11-03
  • 2021-11-23
猜你喜欢
  • 2022-12-23
  • 2021-12-21
  • 2022-01-08
  • 2021-12-21
  • 2021-08-19
  • 2021-07-10
  • 2021-09-01
相关资源
相似解决方案