Vue组件

什么是组件化?


  1. 将一个复杂的问题拆分成很多个可以处理的小问题,再将其放入整体当中,很大的问题也会迎刃而解。
  2. 组件是构成页面中独立结构单元,主要以页面结构的形式存在。
  3. 不同组件也具有基本交互功能,根据业务逻辑实现复杂的项目功能。
  4. 组件化也是类似的思想:
    • 如果将一个页面中的所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展。
    • 但是如果将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那之后的整个页面的管理和维护就变得非常容易。
  5. 组件可以实现复杂的页面结构,提高代码的可复用性。

Vue 组件化思想


  1. 组件化是 Vuejs 中的重要思想。

    • 它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。

    • 任何的应用都可以被抽象成一颗组件树。

    在这里插入图片描述

  2. 组件化思想的应用:

    • 有了组件化的思想,我们在之后的开发中就要充分利用它。
    • 尽可能将页面拆分成一个个小的、可复用的组件。
    • 这样让我们的代码更加方便组织和管理,并且扩展性也更强。

注册组件的基本步骤


  1. 组件的使用分为三个步骤:

    • 创建组件构造器。
    • 注册组件。
    • 使用组件。
  2. 注册组件的步骤:

    • 调用 Vue.extend() 方法创建组件构造器
    • 调用 Vue.component() 方法注册组件
    • 在 Vue 实例中的作用范围内使用组件
    <div id="app">
        <!-- 3. 使用组件 -->
        <my-cpn></my-cpn>
    </div>
    
    <script src="../js/vue.js"></script>
    
    <script>
    	// 1. 创建组件构造器
        const myComponent = Vue.extend({
            template: `
    			<div>
        			<h2>组件标题</h2>
    				<p>我是组件中的一个段落内容</p>
        		</div>
    		`
        })
        
        // 2. 注册组件,并且定义组件标签的名称
        Vue.component('my-cpn',myComponent)
        
        let app = new Vue({
            el: 'app'
        })
    </script>
    
  3. 查看运行结果:

    • 和直接使用一个 div 看起来并没有什么区别。
    • 但是我们可以设想,如果很多地方都要显示这样的信息,我们是不是就可以直接使用<my-cpn></my-cpn>来完成呢?

注册组件步骤解析


  1. Vue.extend() :

    • 调用 Vue.exted() 创建的是一个组件构造器。
    • 通常在创建组件构造器时,传入 template 代表自定义组件的模板。
    • 该模板就是在使用到组件的地方,要显示的 HTML 代码。
    • 事实上,这种写法在 Vue2.x 的文档中几乎已经看不到了,会直接使用语法糖,但是很多资料话是会提到,而且这种方式也是后面的基础。
  2. Vue.component() :

    • 调用 Vue.component() 是将刚才注册的组件构造器注册为一个组件,并且给他起一个组件的标签名称。
    • 所以需要传递两个参数:
      • 注册组件的标签名。
      • 组件构造器。
  3. 组件必须挂载在某个 Vue 实例下,否则它不会生效。

    • 下面使用三次,第三次不会生效。
    <div id="app">
    	<!-- 3.使用组件 -->
        <my-cpn></my-cpn>
        <div>
        	<my-cpn></my-cpn>
        </div>
    </div>
    <!-- 这个并不会渲染出来,因为它没有在new Vue挂载的实例 #app 之下 -->
    <my-cpn></my-cpn>
    

全局组件和局部组件


全局组件

  1. 当通过调用 Vue.component() 注册组件时,组件的注册是全局的。

    • 这就意味着该组件可以在任意 Vue 实例下使用。
    <div id="app1">
      <my-cpn></my-cpn>
    </div>
    <div id="app2">
      <my-cpn></my-cpn>
    </div>
    <script>
    // 创建组件构造器
    const myComponent = Vue.extend({
      template: `
      <div>
        <h2>组件标题</h2>
        <p>组件正文的内容</p>
      </div>
      `
    })
    
    // 注册组件
    Vue.component('my-cpn', myComponent)
    const app1 = new Vue({
      el: '#app1',
    })
    const app2 = new Vue({
      el: '#app2',
    })
    </script>
    

局部组件

  1. 如果注册的组件是挂载在某个实例中,那么就是一个局部组件

    • 通过 Vue 实例的 components 属性在实例中注册组件。

    • 在下面这个例子中,app2 中的组件并没有渲染出来,而且会报错。

    <div id="app1">
      <my-cpn></my-cpn>
    </div>
    <div id="app2">
      <my-cpn></my-cpn>
    </div>
    <script>
    // 创建组件构造器
    const myComponent = Vue.extend({
      template: `
      <div>
        <h2>组件标题</h2>
        <p>组件正文的内容</p>
      </div>
      `
    })
    const app1 = new Vue({
      el: '#app1',
      // 在实例内部注册组件
      components: {
        'my-cpn': myComponent
        // 另外一种写法:myCpn: myComponent,这种写法效果和上面的相同。
        // 如果在注册组件的时候使用了驼峰命名,那么在使用的时候需要转换成短横线分隔命名。 
      }
    })
    const app2 = new Vue({
      el: '#app2',
      // components: {
      //   'my-cpn': myComponent
      // }
    })
    

父组件和子组件


  1. 在前面见到了组件树:

    • 组件和组件之间存在层级关系。
    • 而其中最重要的关系就是父子组件的关系。
  2. 父子组件关系的代码组成:

    <div id="app">
       <parent-cpn></parent-cpn>
     </div>
     <script>
       // 创建一个子组件构造器
       const childComponent = Vue.extend({
         template: `
         <div>
           <p>我是子组件的内容</p>
         </div>
         `
       })
       // 创建一个父组件构造器
       const parentComponent = Vue.extend({
         template: `
           <div>
             我是父组件的内容
             <h2>我是父组件的一个标题</h2>
             <child-cpn></child-cpn>
           </div>
           `,
         components: {
           // 在父组件中注册子组件
           'child-cpn': childComponent
         }
       })
       const app = new Vue({
         el: '#app',
         // 在实例中注册父组件
         components: {
           'parent-cpn': parentComponent
         }
       })
    
  3. 父子组件错误用法:

    • 当子组件注册到父组件的 components 时,Vue 会编译好父组件的模块。
    • 该模板的内容已经决定了父组件将要渲染的 HTML (相当于父组件中已经有了子组件中的内容了。)
    • 是只能在父组件中被识别的。
    • 类似这种用法,是会被浏览器忽略的。

注册组件语法糖


  1. 在上面注册组件的方式会有些繁琐。
    • 为了简化这个过程,提供了注册的语法糖。
    • 主要是省去了调用Vue.extend()的步骤,而是可以直接使用一个对象来代替。

全局组件注册语法糖

Vue.component('my-cpn',{
  template: `
		<div>
			<h2>组件标题</h2>
			<p>组件正文的内容</p>
		</div>
	`
})

局部组件注册语法糖

// 注册局部组件
let app = new Vue({
  el: 'app',
  components: {
    'my-cpn': {
  		template: `
				<div>
					<h2>组件标题</h2>
					<p>组件正文的内容</p>
				</div>
			`
	}
})

模板的分离写法


  1. 除了 Vue 组件的注册过程比较复杂,还有 template 模板的写法也比较麻烦。

  2. 如果将其中的 HTML 分离出来,然后挂载到对应的组件上,必然结构会变得清晰。

  3. Vue 提供了两种方案来定义 HTML 模块内容。

    • 使用标签。

      <div id="app">
        <my-cpn></my-cpn>
      </div>
      <script type="text/x-template" id="myCpn">
        <div>
          <h2>组件标题</h2>
          <p>组件内容</p>
        </div>
      </script>
      <script>
        const app = new Vue({
          el: '#app',
          // 注册组件
          components:{
            myCpn:{
              template:'#myCpn'
            }
          }
        })
      </script>
      
    • 使用标签。

      <div id="app">
        <my-cpn></my-cpn>
      </div>
      <template id="myCpn">
        <div>
          <h2>组件标题</h2>
          <p>组件内容</p>
        </div>
      </template>
      <script>
        const app = new Vue({
          el: '#app',
          // 注册组件
          components: {
            myCpn: {
              template: '#myCpn'
            }
          }
        })
      </script>
      

组件可以访问 Vue 实例数据吗?


  1. 组件是一个单独功能模块的封装。
    • 这个模板有属于自己的 HTML 模板,也应该有自己的数据 data。
  2. 组件不能访问 Vue 实例中的数据,而且即使可以访问,如果把所有的数据都放在 Vue 实例中,Vue 实例就会变得非常臃肿。
  3. 结论:Vue 组件应该有自己保存数据的地方。

组件数据的存放

  1. 组件对象也有一个 data 属性(也可以有 methods 等属性)。
  2. 只是这个 data 必须是一个函数。
  3. 而且这个函数返回一个对象,对象内部保存着数据。

组件的 data 为什么必须是一个函数?

  • 因为函数在每一次调用的时候都会形成一个新的对象,这样就不会对同时使用多次组件的数据产生影响。

父子组件的通信


  1. 子组件是不能引用父组件或者 Vue 实例的数据的。

  2. 但是,在开发中,往往一些数据确实需要从上层传递到下层:

    • 比如在一个页面中,我们从服务器请求到了很多的数据。
    • 其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。
    • 这时,并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)
  3. Vue 官方提供了两种方法进行父子间的通信。

    • 通过 props 向子组件传递数据。
    • 通过事件向父组件发送消息。

    在这里插入图片描述

  4. 在真实的开发中,Vue 实例和子组件的通信父组件和子组件的通信过程是一样的。

父传子:props

  1. 基本用法:

    • 在组件中,使用选项 props 来声明需要从父级接收到的数据。
    • props 的传值有两种方式:
      • 方法一:字符串数组,数组中的字符串就是传递时的名称。
      • 方法二:对象,对象可以设置传递时的类型,也可以设置默认值。
    <div id="app">
      <cpn :cmovies="movies" :cmessage="message"></cpn>
    </div>
    <template id="cpn">
      <div>
        <ul>
          <li v-for="item in cmovies">{{item}}</li>
        </ul>
        <h2>{{cmessage}}</h2>
      </div>
    </template>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: '我来了!',
          movies: ['我在时间尽头等你', '你的婚礼', '我要我们在一起']
        },
        // 注册组件
        components: {
          Cpn: {
            template: '#cpn',
            props: ['cmovies', 'cmessage'],
            data() {
              return {}
            }
          }
        }
      })
    </script>
    

props 数据验证


  1. 在前面,我们的 props 选项是使用一个数组。

  2. 除了数组之外,我们也可以使用对象,当需要对 props 进行类型验证时,就需要对象写法了。

  3. 验证都支持哪些数据类型呢?

    • String
    • Number
    • Boolean
    • Array
    • Object
    • Data
    • Function
    • Symbol
  4. 当有自定义构造函数时,验证也支持自定义的类型。

    function Person(firstName,lastName){
      this.firstName = firstName
      this.lastName = lastName
    }
    
    Vue.component('blog-post',{
      props: {
        author: Person
      }
    })
    

子传父:$emit()

  1. props 用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中。

  2. 这时,我们需要自定义事件来完成。

    • 当子组件需要向父组件传递数据时,就用到自定义事件。
    • v-on 不仅仅用来监听 DOM 事件,也可以用于组件间的自定义事件。
  3. 自定义事件的流程:

    • 在子组件中,通过 $emit() 来触发事件。
    • 在父组件中,通过 v-on 来监听子组件事件。
    <div id="app">
      <child-cpn @increment="changeTotal" @decrement="changeTotal"></child-cpn>
      <h2>点击次数:{{total}}</h2>
    </div>
    
    <template id="childCpn">
      <div> 
        <button @click="increment">+1</button>
        <button @click="decrement">-1</button>
      </div>
    </template>
    
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          total: 0
        },
        methods: {
          changeTotal(counter) {
            this.total = counter
          }
        },
        // 注册子组件
        components:{
          'child-cpn':{
            template:'#childCpn',
            data(){
              return{
                counter:0
              }
            },
            methods:{
              increment(){
                this.counter++
                // 将子组件的 increment 事件和 counter 通过 $emit() 发射出去
                this.$emit('increment',this.counter)
              },
              decrement(){
                this.counter--
                // 将子组件的 decrement 事件和 counter 通过 $emit() 发射出去
                this.$emit('decrement',this.counter)
              }
            }
          }
        }
      })
    </script>
    

父访问子

  1. 有时候需要父组件直接访问子组件,子组件访问父组件,或者是子组件访问根组件。

    • 父组件访问子组件:使用 $children 或 $refs 。
    • 子组件访问父组件:使用 $parent .
  2. 先来看一下 $children 的访问。

    • this.$children 是一个数组类型,它包含所有子组件对象。
    • 通过一个遍历,取出所有子组件的 message 状态。
    <div id="app">
      <parent-cpn></parent-cpn>
    </div>
    <!-- 父组件template -->
    <template id="parentCpn">
      <div>
        <child-cpn1></child-cpn1>
        <child-cpn2></child-cpn2>
        <button @click="showChildCpn">显示所有子组件信息</button>
      </div>
    </template>
    <!-- 子组件template -->
    <template id="childCpn1">
      <h2>我是子组件1</h2>
    </template>
    <template id="childCpn2">
      <h2>我是子组件2</h2>
    </template>
    
    <script>
      Vue.component('parent-cpn', {
        template: '#parentCpn',
        methods: {
          showChildCpn() {
            for (let i = 0; i < this.$children.length; i++) {
              console.log(this.$children[i].message);
              // 输出的结果是子组件中的 message 中的内容。
            }
          }
        },
        components: {
          childCpn1: {
            template: '#childCpn1',
            data() {
              return {
                message: '我是子组件1'
              }
            }
          },
          childCpn2: {
            template: '#childCpn2',
            data() {
              return {
                message: '我是子组件2'
              }
            }
          }
        }
      })
      const app = new Vue({
        el: '#app',
      })
    </script>
    

子访问父

  1. 子访问父使用 $parent 。

  2. 这种访问方式在开发中不会常用。

    <div id="app">
      <cpn></cpn>
    </div>
    <template id="cpn">
     <div>
       <h2>我是子组件</h2>
       <button @click="btnClick">访问父组件</button>
     </div>
    </template>
      
    <script>
      const app = new Vue({
        el: '#app',
        data:{
          message:'我是父组件的内容'
        },
        components:{
          'cpn':{
            template:'#cpn',
            methods:{
              btnClick(){
                console.log(this.$parent.message);
                // 输出结果是 Vue 实例中的 message 中的内容
              }
            }
          }
        }
      })
    </script>
    

访问根组件

  1. 使用 $root 访问根组件,一般也不常用。
  2. 使用方法参照父子访问的方法。

插槽


  1. 组件的插槽是为了让我们封装的组件更加具有扩展性。
  2. 让使用者可以决定组件内部的一些内容到底展示什么。
  3. 例子:
    • 移动网页中的导航栏:
      • 移动开发中,几乎每个页面都有导航栏。
      • 导航栏我们必然会封装成一个插件,比如 nav-bar 组件。
      • 一旦有了这个组件,我们就可以在多个页面中复用了。

如何封装这类组件呢?slot

  1. 如何去封装这类的组件呢?
    • 他们有很多区别,但是也有很多共性。
    • 如果每一个单独封装一个组件,显然不合适,比如每个页面都返回,这部分内容我们就要重复去封装。
    • 但是如果封装成一个,也不合理:有些左面是菜单,有些是返回,有些中间是搜索,有些是文字等等。
  2. 如何封装合适呢?抽取共性,保留不同。
    • 最好的封装方式就是将共性抽取到组件中,将不同暴露为插槽。
    • 一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容。
    • 是搜索框,还是文字,还是菜单,由调用者自己来决定。
  3. 这就是为什么我们要学习组件中的插槽 slot 的原因。

slot 基本使用

  1. 在子组件中,使用特殊元素就可以为子组件开启一个插槽。

  2. 该插槽插入什么内容取决于父组件如何使用。

  3. 中的内容表示,如果没有在该组件中插入任何其他内容,就默认显示该内容。

  4. 插槽的使用方法:

    <div id="app">
      <my-cpn>
        <h2>
          我是替换插槽的内容
        </h2>
        <p>
          我也是替换插槽的内容
        </p>
      </my-cpn>
    </div>
    
    <template id="myCpn">
    	<div>
        <slot>我是插槽中的默认内容</slot>
      </div>
    </template>
    <script>
    	Vue.component('my-cpn',{
        template:'#myCpn'
      })
      
      let app = new Vue({
        el: '#app'
      })
    </script>
    

具名插槽

  1. 当子组件的功能复杂时,子组件的插槽可能并非是一个。

    • 比如封装一个导航栏的子组件,就需要三个插槽,分别代表左边、中间、右边。
    • 那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?
    • 这个时候,就需要给插槽起一个名字。
  2. 如何使用具名插槽呢?

    • 非常简单,只要给 slot 元素一个 name 属性即可。
    <div>
      <!-- 没有传入任何内容 -->
      <my-cpn></my-cpn>
      <!-- 传入某一个内容 -->
      <my-cpn>
      	<span slot="left"></span>
      </my-cpn>
      <!-- 传入所有的内容 -->
      <my-cpn>
      	<span slot="left">我是返回</span>
        <span slot="center">我是标题</span>
        <span slot="right">我是菜单</span>
      </my-cpn>
    </div>
    
    <template id="myCpn">
    	<div>
        <slot name="left">我是左侧</slot>
        <slot name="center">我是中间</slot>
        <slot name="right">我是右侧</slot>
      </div>
    </template>
    
    <script>
    	Vue.component('my-cpn',{
        template: '#myCpn'
      })
      
      let app = new Vue({
        el: '#app'
      })
    </script>
    

作用域插槽


编译作用域

  1. 在学习插槽以前,先理解一个概念:编译作用域。

  2. 官方对于编译的作用域解析比较简单。

    <div id="app">
    	<cpn v-show="isShow"></cpn>
    </div>
    <template id="cpn">
        <div>
            <h2>我是组件标题</h2>
            <p>哈哈哈</p>
        </div>
    </template>
    <script src="../Vuecode/Vue.min.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                isShow: true
            },
            components: {
                cpn: {
                    template: '#cpn',
                    data() {
                        return {
                            isShow: false
                        }
                    }
                }
            }
        })
    </script>
    
  3. 下面的代码是否可以被渲染出来?

  • 中,使用了 isShow 属性。
  • isShow 属性即包含在组件中,又包含在 Vue 实例中。

答案:最终是可以渲染出来的,也就是使用的是 Vue 实例的属性。

  1. 为什么呢?
  • 官方给出了一条准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
  • 而我们在使用的时候,整个组建的使用过程是相当于在父组件中出现的。
  • 那么他的作用域就是父组件,使用的属性也是属于父组件的属性。
  • 因此,isShow 使用的是 Vue 实例的属性,而不是子组件的属性。

作用域插槽:准备

  1. 父组件替换插槽的标签,但是内容由子组件来提供。
  2. 先来提一个需求:
    • 子组件中包括一组数据,比如:pLanguages:[‘JavaScript’,‘Python’,‘Swift’,‘Go’,‘C++’]。
    • 需要在多个界面进行展示。
      • 某些界面是以水平方向——展示的。
      • 某些界面是以列表形式展示的。
      • 某些界面直接展示一个数组。
    • 内容在子组件,怎么让父组件进行展示?
      • 利用 slot 作用域插槽就可以了。

作用域插槽的使用

<div id="app">
    <cpn></cpn>
    <cpn>
      <template slot-scope="slot">
        <span>{{slot.data.join(' - ')}}</span>
      </template>
    </cpn>
    <cpn>
      <template slot-scope="slot">
        <span>{{slot.data.join(' * ')}}</span>
      </template>
    </cpn>
  </div>
  <template id="cpn">
    <div>
      <slot :data="pLanguages">
        <ul>
          <li v-for="item in pLanguages">{{item}}</li>
        </ul>
      </slot>
    </div>
  </template>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        isShow: true
      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              pLanguages: ['JavaScript', 'Python', 'Swift', 'Go', 'C++']
            }
          }
        }
      }
    })
  </script>

模块化开发


JavaScript 原始功能

  1. 在网页开发的早期,JavaScript 制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候的代码还是很少的。

    • 那个时候的代码直接写在

匿名函数的解决方案

  1. 可以使用匿名函数来解决重名问题。

    • 在 aaa.js 文件中,我们使用匿名函数。

      (function(){
          var flag = true
      })()
      
  2. 但是如果要在 main.js 文件中用到 flag 要怎么做?

    • 显然,另外一个文件中不容易使用,因为 flag 是一个局部变量。

使用模块作为出口

  1. 可以将需要暴露在外面的变量,使用一个模块作为出口。
    • 在匿名函数内部,定义一个对象。
    • 给对象添加各种需要暴露在外面的属性和方法(不需要暴露的直接定义即可)。
    • 最后将这个对象返回,并且在外面使用一个 ModuleA 接收。
  2. 在 main.js 中,只需要使用属于自己的模块的属性和方法即可。
;
var ModuleA = (function(){
    // 定义一个对象
    var obj = {}
    // 在对象内部添加变量和方法
    obj.flag = true
    obj.myFunc = function(info){
        console.log(info)
    }
    // 将对象返回
    return obj
})()
// 另外一个 js 文件

;
if(ModuleA.flag){
    console.log('小明是个天才')
}

ModuleA.myFunc('小明长得真帅')

console.log(ModuleA)
  1. 这就是模块最基础的封装,事实上模块的封装还有很多高级的话题。
    • 先认识一下为什么需要模块,以及模块的原始雏形。
    • 幸运的是,前端模块化开发已经有了很多既有的规范,以及对应的实现方案。
  2. 常见的模块化规范:
    • CommonJS、AMD、CMD、也有 ES6 的 Modules。

CommonJS(了解)

  1. 模块化有两个核心:导出和导入。

  2. CommonJS 的导出:

    module.exports = {
        flag:true
        test(a,b){
            return a + b
        }
    	demo(a,b){
            return a * b
        }
    }
    
  3. CommonJS 的导入:

    // CommonJS 模块
    let {test,demo,flag} = require('moduleA')
    
    // 等同于
    let _mA = require('moduleA')
    let test = _mA.test
    let demo = _mA.demo
    let flag = _mA.flag
    

ES6 模块化的导出和导入


export 的基本使用

  1. export 指令用于导出变量:

    // info.js
    export let name = 'why'
    export let age = 18
    export let height = 1.88
    
  2. 上面的代码还有另外一种写法:

    // info.js
    let name = 'why'
    let age = 18
    let height = 1.88
    
    export {name,age,height}
    

导出函数或类

  1. 上面主要是输出变量,也可以输出函数或者输出类。

    export function test(content){
        console.log(content)
    }
    export class Person {
        constructor(name,age){
            this.name = name
            this.age = age
        }
        
        run() {
            console.log(this.name + '在奔跑')
        }
    }
    
    // 另外一种写法
    function test(content){
        console.log(content)
    }
    class Person {
        constructor(name,age){
            this.name = name
            this.age = age
        }
        
        run() {
            console.log(this.name + '在奔跑')
        }
    }
    
    export {test,Person}
    

export default

  1. 某些情况下,一个模块中包含某个功能,我们不希望给这个功能命名,而且希望导入者可以自己来命名。

    • 这时可以使用 export default

      // info.js
      export default function(){
          console.log('default function')
      }
      
  2. 我们来到 main.js 中,这样使用就可以了

    • 这里的 myFunc 是自己命名的,你可以根据需要命名它对应的名字。

      import myFunc from './info.js'
      myFunc()
      
  3. 另外,需要注意:

    • export default 在同一个模块中,不允许同时存在多个。

import 使用

  1. 我们使用 export 指令导出了模块对外提供的接口,下面就可以通过 import 命令来加载对应的这个模块了。

  2. 首先,需要在 HTML 代码中引入两个 js 文件,并且类型要设置成 module。

    <script src="info.js" type="module"></script>
    <script src="main.js" type="module"></script>
    
  3. import 指令用于导入模块中的内容,比如 main.js 的代码。

    import {name,age,height} from "./info.js"
    
    console.log(name,age,height)
    
  4. 如果我们希望某个模块中所有的信息都导入,一个个导入显然有些麻烦。

    • 通过 * 可以导入模块中所有的 export 变量。

    • 但是通常情况下我们需要给 * 起一个别名,方便后续的使用。

      import * as info from './info.js'
      
      console.log(info.name,info.age,info.height,info.friends)
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值