美文网首页
Vue基础教程之-组件核心概念(四)

Vue基础教程之-组件核心概念(四)

作者: AC编程 | 来源:发表于2021-05-31 10:03 被阅读0次

一、模块化

1.1 为什么需要模块化

没有模块化的世界:全局变量污染、难以管理的依赖。
常见的模块化标准:CommonJS(node.js)、AMD(民间)、CMD(民间)、UMD(民间)、ES6 Module(官方)

1.2 全局变量污染

新建一个test.js文件,test.html文件,在html中用普通方式引入js代码,代码如下

var nickname = "AlanChen";

function test(){
    console.log("Hello "+nickname);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./test.js"></script>
</body>
</html>

变量nickname和方法test是全局的,是window全局变量,如下

全局变量污染
1.3 模块化方式解决全局变量污染

html采用模块化的方式引入js文件,<script src="./test.js" type="module"></script>,变量nickname和方法test就不再是全局的了。

模块化方式解决全局变量污染
1.4 模块化导出与导入

我们新建一个hello.js文件,并用 export default导出一个helloWorld函数,在test.jsimport该函数,代码如下

var helloTitle = "Hello World";

export default function helloWorld(){
    console.log(helloTitle);
}

import helloWorld from "./hello.js"

var nickname = "AlanChen";

function test(){
    console.log("Hello "+nickname);
}

// 测试

//有导出,可以访问
helloWorld();

//没有导出,无法访问
console.log(helloTitle);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./test.js" type="module"></script>
</body>
</html>
模块化导出与导入

二、组件概念

一个完整的网页是复杂的,如果将其作为一个整体来进行开发,将会遇到下面的问题:
1、代码凌乱臃肿
2、不易协作
3、难以复用

Vue推荐使用一种更加精细的控制方案:组件化开发。所谓组件化,即把一个页面中区域功能细分,每一个区域成为一个组件,每个组件包含:
1、功能(JS代码)
2、内容(模板代码)
3、样式(CSS代码)

三、组件开发

3.1 创建组件

组件是根据一个普通的配置对象创建的,所以要开发一个组件,只需要写一个配置对象即可,该配置对象和Vue实例的配置是几乎一样的。

        //组件配置对象
        var MyComp={
            data(){
                return {
                    // ...
                }
            },

            computed:{
                // ...
            },

            methods:{
                // ...
            },

            template: `...`
        }

值得注意的是,组件配置对象和Vue实例有以下几点差异:
1、无el
2、data必须是一个函数,该函数返回的对象作为数据
3、由于没有el配置,组件的虚拟DOM树必须定义在template或render中

3.2 注册组件

注册组件分为两种方式,一种是全局注册,一种是局部注册

3.2.1 全局注册

一旦全局注册了一个组件,整个应用中任何地方都可以使用该组件

全局注册

全局注册的方式是:

        //参数1:组件名称,将来在模板中使用组件时,会使用该名称
        // 参数2:组件配置对象
        // 该代码运行后,即可在模板中使用组件
        Vue.component("MyComp",MyComp);

在模板中,可以使用组件了

        <MyComp />
        <!--或-->
        <MyComp></MyComp>

但在一些工程化的大型项目中,很多组件都不需要全局使用。比如一个登录组件,只有在登录的相关页面中使用,如果全局注册,将导致构建工具无法优化打包,因此,除非组件特别通用,否则不建议使用全局注册。

3.2.2 局部注册

局部注册就是哪里要用到组件,就在哪里注册

局部注册

局部注册的方式是,在要使用组件的组件或实例中加入一个配置

        // vm:Vue实例
        var vm = new Vue({   
            el:"#app",  // css选择器

            // 注册组件(局部注册)
            components:{
                Title
            },

            template: `<Title></Title>`,
        });
3.3 应用组件

在模板中使用组件特别简单,把组件名当作html元素名使用即可。但要注意以下几点

1、组件必须有结束
组件可以自结束,也可以用结束标记结束,但必须要有结束

2、组件的命名
无论你使用哪种方式注册组件,组件的名称需要遵循规范。组件可以使用kebab-case短横线命名法,也可以使用PascalCase大驼峰命名法。下面两种命名均是可以的

var otherComp = {
    components:{
          "my-comp": myComp, //方式1
          MyComp: myComp //方式2
    }
}

实际上,使用小驼峰命名法,camelCase也是可以识别的,只不过不符合官方要求的规范。使用PascalCase方式命名还有一个额外的好处,即可以在模板中使用两种组件名。

四、组件树

一个组件创建好后,往往会在各种地方使用它。它可能多次出现在Vue实例中,也可能出现在其他组件中。于是就形成了一个组件树。

组件树

五、向组件传递数据

大部分组件要完成自身的功能,都需要一些额外的信息,比如一个头像组件,需要告诉它头像的地址,这就需要在使用组件时向组件传递数据。传递数据的方式有很多中,最常见的一种是使用组件属性component props,和Vue实例一样,使用组件时也会创建组件的实例,而组件的属性会被提取到组件实例中,因此可以在模板中使用。

首先在组件中申明可以接收哪些属性

var MyComp = {
    props: ["p1","p2","p3"],

   template: `
           <div>
               {{p1}}, {{p2}}, {{p3}}
           </div>
   `
}

在使用组件时,向其传递属性

var OtherComp = {
    componets: {
       MyComp
   },

   data(){
         return {
            a:1
         }
   },

   template: `
         <my-comp :p1="a"  :p2="2"  p3="3"
  `
}

注意:在组件中,属性是只读的,绝不可以更改,这叫单向数据流。哲学思想:谁的数据谁负责

属性不可更改

六、组件创建、注册、使用、属性传值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id ="app">
    </div>
    <script src="./vue.min.js" ></script>
    <script>

       //1、组件配置对象
        var Title = {

            //属性
            props: ["version"],

            data(){
                return {
                    title: "库存管理系统",
                };
            },
            template: `<h1>{{title}} {{version}}</h1>`,
        }

        //2、注册组件(全局注册)
       // Vue.component("Title",Title);


        // 3、使用组件
        // vm:Vue实例
        var vm = new Vue({   
            el:"#app",  // css选择器

            // 2、注册组件(局部注册)
            components:{
                Title
            },

            template: `<Title version="V1.0"></Title>`,
        });
    </script>
</body>
</html>

七、库存管理系统 demo

库存管理系统 demo-004

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="./lib/vue.min.js"></script>
    <script src="./src/main.js" type="module"></script>
</body>
</html>

main.js

import App from "./App.js";

new Vue({

    components:{
        App,
    },

    // template: `<App />`

    // render(h){
    //     return h(App);
    // }

    render:(h)=>h(App),

}).$mount("#app");

App.js


import Products from "./components/Products.js";

var template = `
<div>
    <h1>库存管理系统</h1>
    <Products />
</div>
`;

export default{
    components:{
        Products
    },

   template,
};

Products.js


var template = `
<ul>
    <li v-for="(item,i) in products">
        名称:{{item.name}} 
        <button @click="changeStock(item,item.stock-1)">-</button>
        <span v-if="item.stock>0">{{item.stock}}</span>
        <span v-else>无货</span>
        <button @click="changeStock(item,item.stock+1)">+</button>

        <button @click="remove(i)">删除</button>
     </li>
</ul>
`;

export default{
    template,

    data(){
        return {
            products:[
                {id:1,name:"iphone",stock:10},
                {id:2,name:"xiaomi",stock:10},
                {id:3,name:"huawei",stock:10},
            ],
        }
    },

    methods:{
        remove(i){
            this.products.splice(i,1);
        },
        changeStock(product,newStock){
            if(newStock<0){
                newStock = 0;
            }
            product.stock = newStock;
        }
    },
}

源码

源码 003、004

相关文章

  • Vue基础教程之-组件核心概念(四)

    一、模块化 1.1 为什么需要模块化 没有模块化的世界:全局变量污染、难以管理的依赖。常见的模块化标准:Commo...

  • vue组件三大核心概念详解

    vue组件三大核心概念详解

  • 深入理解Vue组件3大核心概念

    摘要: 搞懂Vue组件! 作者:浪里行舟 原文:详解vue组件三大核心概念 Fundebug经授权转载,版权归原作...

  • Vue原理

    vue原理相关 Vue核心概念 vue实例化 虚拟dom 模板编译 数据绑定(响应式) 组件化 MVVM mode...

  • Vue组件的tsx写法

    简述 组件(Component) 是vue框架中最核心的概念,所有逻辑都围绕组件展开,得组件者,得天下。 这里我主...

  • vue原理相关

    Vue核心概念 vue实例化 虚拟dom 模板编译 数据绑定(响应式) 组件化 MVVM model和view层通...

  • vue组件的核心概念

    最近在看极客时间的vue课程,算是做个小笔记吧 通常一个应用会以一棵嵌套的组件树的形式来组织: Vue组件就是一个...

  • vue(学习笔记三)——vue知识点汇总

    Vue简介 2014年诞生,2013年react,09年angularjs 作者: 尤雨溪 核心概念: 组件化 双...

  • vue学习

    vue核心是组件,组件是vue实例,没有el,其他data,computed等等方法都有。组件定义在vue中,用在...

  • Vuex 状态管理

    Vue组件间通信方式 Vuex核心概念和基本使用 购物车案例 模拟实现vuex 一、组件内的状态管理流程 状态管理...

网友评论

      本文标题:Vue基础教程之-组件核心概念(四)

      本文链接:https://www.haomeiwen.com/subject/xusssltx.html