zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Vue组件化编程④

2023-09-27 14:26:45 时间

单文件组件

这也就意味着我们需要把一个个的组件写成.vue文件。我们知道组件由三个部分组成,部分html代码、css、js。在vue文件中为我们提供了三种标签,去完成每部分的内容:
在这里插入图片描述

由此我们可以看出非单文件组件的一个弊病:css样式不能跟着组件走
就拿我们前面写过的代码来说:
在这里插入图片描述
如果要定义样式还需要去head标签里面写一个style标签,然后再找到要定义标签的元素,再开始写样式。

我们现在尝试把上图中的student组件放入到vue文件中去:

<template>
    <div>
        <h2 class="stu">学生名称:{{studentName}}</h2>
        <h2>学生年纪:{{studentAge}}</h2>
            
    </div>
</template>

<script>
    const student = Vue.extend({
        data(){
            return {
                studentName:'张三',
                studentAge:18
            }
        }
    })
	export default { 
    	student
	}
</script>

<style>
    .stu{
        background-color:red;
    }
</style>

记得要暴露东西,否则引入了之后没有可以用的

如果组件没有样式,我们可以不要style标签,上面代码中的样式是我临时加的

还可以更简洁一点,我们知道Vue.extend()是有简便写发的,然后我们再给组件添加一个名字:

<template>
    <div>
        <h2 class="stu">学生名称:{{studentName}}</h2>
        <h2>学生年纪:{{studentAge}}</h2>
            
    </div>
</template>

<script>
    export default {
        name:'Student',
        data(){
            return {
                studentName:'张三',
                studentAge:18
            }
        }
    }

</script>

<style>
    .stu{
        background-color:red;
    }
</style>

接下来我们将以下代码按照单文件组建的方式进行编写:

<body>
    <div id="root">
        <app></app>
    </div>

    
</body>
<script>


    //创建student组件
    const student = Vue.extend({
        template:`
        <div>
            <h2>学生名称:{{studentName}}</h2>
            <h2>学生年纪:{{studentAge}}</h2>
            
        </div>
        `,
        data(){
            return {
                studentName:'张三',
                studentAge:18
            }
        }
    })


    //创建school组件
    const school = Vue.extend({
        name:'NEFU',
        template:`
        <div>
            <h2>学校名称:{{schoolName}}</h2>
            <h2>学校地址:{{schoolAddress}}</h2>
            <hr>            
        </div>
        `,
        data(){
            return {
                schoolName:'NEFU',
                schoolAddress:'哈尔滨',
            }
        },
    })

    //创建app组件
    const app = Vue.extend({
        components:{
            school,
            student
        },
        template:`
            <div>
                <hello></hello>
                <school></school>
                <student></student>
            </div>

        `
    })

    new Vue({
        el:'#root',
        //注册组件
        components:{
            app
        },
        
    })
</script>

文件结构:
在这里插入图片描述
App.vue:

<template>
    <div>
        <School></School>
        <Student></Student>
    </div>
</template>

<script>
        import School from './School.vue'
        import Student from './Student.vue'
        const app = Vue.extend({
        components:{
            School,
            Student
        },
    })
export default {
    app
}
</script>

<style>

</style>

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="root"></div>
    <script type="text/javascript" src="../VueEnvironment/vue.js"></script>
    <script src="./main.js"></script>
</body>
</html>

注意这里的引入顺序和位置。不能放在head里面去引入,此时结构还没有被加载!

其实我们这里的引入是没有多大意义的,我们后期会借助脚手架来进行编译。

main.js:

import App from './App.vue'

new Vue({
    template:`
        <App></App>
    `,
    el:'#root',
    //注册组件
    components:{
        App
    },
    
})

main.js文件中一般放着vm的代码。并且一般只有App.vue能与他直接对话!

School.vue:

<template>
        <div>
            <h2>学校名称:{{schoolName}}</h2>
            <h2>学校地址:{{schoolAddress}}</h2>
            <hr>            
        </div>
</template>

<script>
    const school = Vue.extend({
        name:'NEFU',
        data(){
            return {
                schoolName:'NEFU',
                schoolAddress:'哈尔滨',
            }
        },
    })
export default {
    school
}
</script>

<style>

</style>

Student.vue:

<template>
    <div>
        <h2 class="stu">学生名称:{{studentName}}</h2>
        <h2>学生年纪:{{studentAge}}</h2>
            
    </div>
</template>

<script>
    export default {
        name:'Student',
        data(){
            return {
                studentName:'张三',
                studentAge:18
            }
        }
    }

</script>

<style>
    .stu{
        background-color:red;
    }
</style>

做完这一切之后,我们直接打开index.html文件是没有用的,我们还需要一个强大的工具–脚手架.

附:ES6模块化复习

概述

在 ES6 前, 实现模块化使用的是 RequireJS 或者 seaJS(分别是基于 AMD 规范的模块化库, 和基于 CMD 规范的模块化库)。

ES6 引入了模块化,其设计思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量。

ES6 的模块化分为导出(export) @与导入(import)两个模块。

特点

ES6 的模块自动开启严格模式,不管你有没有在模块头部加上 use strict;。

模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等。

每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域。

每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取。

export 与 import

基本用法

模块导入导出各种类型的变量,如字符串,数值,函数,类。

  • 导出的函数声明与类声明必须要有名称(export default 命令另外考虑)。
  • 不仅能导出声明还能导出引用(例如函数)。
  • export 命令可以出现在模块的任何位置,但必需处于模块顶层。
  • import 命令会提升到整个模块的头部,首先执行。
/*-----export [test.js]-----*/
let myName = "Tom";
let myAge = 20;
let myfn = function(){
    return "My name is" + myName + "! I'm '" + myAge + "years old."
}
let myClass =  class myClass {
    static a = "yeah!";
}
export { myName, myAge, myfn, myClass }
 
/*-----import [xxx.js]-----*/
import { myName, myAge, myfn, myClass } from "./test.js";
console.log(myfn());// My name is Tom! I'm 20 years old.
console.log(myAge);// 20
console.log(myName);// Tom
console.log(myClass.a );// yeah!

建议使用大括号指定所要输出的一组变量写在文档尾部,明确导出的接口。
函数与类都需要有对应的名称,导出文档尾部也避免了无对应名称。

as 的用法

export 命令导出的接口名称,须和模块内部的变量有一一对应关系。

导入的变量名,须和导出的接口名称相同,即顺序可以不一致。

/*-----export [test.js]-----*/
let myName = "Tom";
export { myName as exportName }
 
/*-----import [xxx.js]-----*/
import { exportName } from "./test.js";
console.log(exportName);// Tom
使用 as 重新定义导出的接口名称,隐藏模块内部的变量
/*-----export [test1.js]-----*/
let myName = "Tom";
export { myName }
/*-----export [test2.js]-----*/
let myName = "Jerry";
export { myName }
/*-----import [xxx.js]-----*/
import { myName as name1 } from "./test1.js";
import { myName as name2 } from "./test2.js";
console.log(name1);// Tom
console.log(name2);// Jerry

不同模块导出接口名称命名重复, 使用 as 重新定义变量名。

import 命令的特点

  • 只读属性:不允许在加载模块的脚本里面,改写接口的引用指向,即可以改写 import 变量类型为对象的属性值,不能改写 import 变量类型为基本类型的值。
  • 单例模式:多次重复执行同一句 import 语句,那么只会执行一次,而不会执行多次。import 同一模块,声明不同接口引用,会声明对应变量,但只执行一次 import 。
  • 静态执行特性:import 是静态执行,所以不能使用表达式和变量。

export default 命令

  • 在一个文件或模块中,export、import 可以有多个,export default 仅有一个。
  • export default 中的 default 是对应的导出接口变量。
  • 通过 export 方式导出,在导入时要加{ },export default 则不需要。
  • export default 向外暴露的成员,可以使用任意变量来接收。
var a = "My name is Tom!";
export default a; // 仅有一个
export default var c = "error"; 
// error,default 已经是对应的导出变量,不能跟着变量声明语句
 
import b from "./xxx.js"; // 不需要加{}, 使用任意变量接收