[TOC]

03、前端开发基础知识.pdf
前端主要涉及到如下几个工具:VSCode(前面搭建基本环境已经装过了)、ES6、Node.js(前面搭建基本环境已经装过了)、Vue、Babel(了解)、Webpack(了解)

前端后端技术栈类比:
image.png

一、ES6

ECMAScript 6.0(以下简称 ES6,ECMAScript 是一种由 Ecma 国际(前身为欧洲计算机制造商 协会,英文名称是 European Computer Manufacturers Association)通过 ECMA-262标准化的脚本 程序设计语言)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了,并且 从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015,就是 ECMAScript6。 它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 每年一个新版本
ECMAScript 是浏览器脚本语言的规范,而各种我们熟知的 js 语言,如 JavaScript 则是 规范的具体实现。

新建一个前端项目ES6

1.1 let声明变量

新建一个let.html文件,然后使用快捷键shift+!直接生成html文档。
image.pngimage.png
let声明的变量有以下特点:

  1. let 声明的变量有严格局部作用域,var 声明的变量往往会越域
  2. let 只能声明一次,var 可以声明多次
  3. let 不存在变量提升,var 会变量提升

    <!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>
         // var 声明的变量往往会越域
         // let 声明的变量有严格局部作用域
         {
           var a = 1;
           let b = 2;
         }
         console.log(a); // 1
         console.log(b); // 报错 ReferenceError: b is not defined
    
         // var 可以声明多次
         // let 只能声明一次
         var m = 1
         var m = 2
         let n = 3
         let n = 4
         console.log(m) // 2
         console.log(n) // Identifier 'n' has already been declared
    
           // var 会变量提升
         // let 不存在变量提升
         console.log(x); // undefined
         var x = 10;
         console.log(y); //ReferenceError: y is not defined
         let y = 20;
     </script>
    </body>
    </html>
    

    image.pngimage.png

    1.2 const声明常量(只读变量)

    <!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>
         const a = 1;
         a = 3; //Uncaught TypeError: Assignment to constant variable.
     </script>
    </body>
    </html>
    

    1.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>
     <script>
           // **********数组解构**********
         let arr = [1,2,3];
         //以前我们想获取其中的值,只能通过角标。
         let a = arr[0];
         let b = arr[1];
         let c = arr[2];
         //ES6 可以这样:
         const [x,y,z] = arr;// x,y,z 将与 arr 中的每个位置对应来取值
         // 然后打印
         console.log(x,y,z);
    
           // **********对象解构**********
         const person = {
             name: "jack",
             age: 21,
             language: ['java', 'js', 'css']
         }
    
         // 解构表达式获取值,将 person 里面每一个属性和左边对应赋值
         const { name, age, language } = person;
         // 等价于下面
         // const name = person.name;
         // const age = person.age;
         // const language = person.language;
         // 可以分别打印
         console.log(name);
         console.log(age);
         console.log(language);
         // 可以一起打印
         console.log(language,age,language);
    
         //扩展:如果想要将 name 的值赋值给其他变量,可以如下,nn 是新的变量名
         const { name: nn, age, language } = person;
         console.log(nn);
         console.log(age);
         console.log(language);
     </script>
    </body>
    </html>
    

    1.4 字符串拓展

    ES6 为字符串扩展了几个新的 API:

  • includes():返回布尔值,表示是否找到了参数字符串。
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

image.png

字符串模板:
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行 字符串,还可以在字符串中加入变量和表达式。

<!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>
          //**********字符串模板**************
        // 1、多行字符串
        let ss = `
                <div>
                <span>hello world<span>
                </div>
                `
        console.log(ss)
        // 2、字符串插入变量和表达式。变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。
        let name = "张三";
        let age = 18;
        let info = `我是${name},今年${age + 10}了`;
        console.log(info)
        // 3、字符串中调用函数
        function fun() {
            return "这是一个函数"
        }
        let sss = `O(∩_∩)O 哈哈~,${fun()}`;
        console.log(sss); // O(∩_∩)O 哈哈~,这是一个函数
    </script>
</body>
</html>

1.5 函数优化

<!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>
        //****************函数参数默认值***************
        //在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
        function add(a, b) {
            // 判断 b 是否为空,为空就给默认值 1
            b = b || 1;
            return a + b;
        }
        // 传一个参数
        console.log(add(10));
        //现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
        function add2(a, b = 1) {
            return a + b;
        }
        // 传一个参数
        console.log(add2(10));

        /**********不定参数**************/
        function fun(...values) {
            console.log(values.length)
        }
        fun(1, 2) //2
        fun(1, 2, 3, 4) //4

        /*********箭头函数************/
        // 以前声明一个方法  一个参数
        // var print = function (obj) {
        // console.log(obj);
        // }
        // 可以简写为:
        var print = obj => console.log(obj);
        // 测试调用
        print(100);

        // 多个参数
        // 两个参数的情况:
        var sum = function (a, b) {
            return a + b;
        }
        // 简写为:
        //当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
        var sum2 = (a, b) => a + b;
        //测试调用
        console.log(sum2(10, 10));//20
        // 代码不止一行,可以用`{}`括起来
        var sum3 = (a, b) => {
            c = a + b;
            return c;
        };
        //测试调用
        console.log(sum3(10, 20));//30

        /********箭头函数结合解构表达式********/
        //需求,声明一个对象,hello 方法需要对象的个别属性
        //以前的方式:
        const person = {
            name: "jack",
            age: 21,
            language: ['java', 'js', 'css']
        }
        function hello(person) {
            console.log("hello," + person.name)
        }

        // 现在的方式  箭头函数+解构表达式
        // var hello2 = (obj) => {console.log("hello," + obj.name)};
        // obj用解构表达式即可直接获取传入对象的name属性
        var hello2 = ({ name }) => { console.log("hello," + name) };
        //测试   传入person对象,{name} 解构person的name属性,传入函数
        hello2(person);
    </script>
</body>

</html>

1.6 对象优化

ES6 给 Object 拓展了许多新的方法,如:

  • keys(obj):获取对象的所有 key 形成的数组
  • values(obj):获取对象的所有 value 形成的数组
  • entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:[[k1,v1],[k2,v2],...]
  • assign(dest, …src) :将多个 src 对象的值 拷贝到 dest 中。(第一层为深拷贝,第二层为浅 拷贝) ```html <!DOCTYPE html>
<a name="ZXbIr"></a> ## 1.7 数组中的map和reduce 数组中新增了 map 和 reduce 方法。html <!DOCTYPE html>

<a name="h2Sgz"></a>
## 1.8 Promise
在 JavaScript 的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致 JavaScript 的所
有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现。一旦有一连
串的 ajax 请求 a,b,c,d... 后面的请求依赖前面的请求结果,就需要层层嵌套。这种缩进和层
层嵌套的方式,非常容易造成上下文代码混乱,我们不得不非常小心翼翼处理内层函数与外
层函数的数据,一旦内层函数使用了上层函数的变量,这种混乱程度就会加剧......总之,这
种`层叠上下文`的层层嵌套方式,着实增加了神经的紧张程度。
```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>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
    <script>
        //1、查出当前用户信息
        //2、按照当前用户的id查出他的课程
        //3、按照当前课程id出查出分数
        //回调函数嵌套的噩梦:层层嵌套。
        // $.ajax({
        //     url: "mock/user.json",
        //     success(data) {
        //         console.log("查询用户:", data);
        //         $.ajax({
        //             url: `mock/user_corse_${data.id}.json`,
        //             success(data) {
        //                 console.log("查询到课程:", data);
        //                 $.ajax({
        //                     url: `mock/corse_score_${data.id}.json`,
        //                     success(data) {
        //                         console.log("查询到分数:", data);
        //                     },
        //                     error(error) {
        //                         console.log("出现异常了:" + error);
        //                     }
        //                 });
        //             },
        //             error(error) {
        //                 console.log("出现异常了:" + error);
        //             }
        //         });
        //     },
        //     error(error) {
        //         console.log("出现异常了:" + error);
        //     }
        // });


        // Promise可以封装异步操作
        // const promise = new Promise(function (resolve, reject) {
        //     // 执行异步操作
        //     if (/* 异步操作成功 */) {
        //         resolve(value);// 调用 resolve,代表 Promise 将返回成功的结果
        //     } else {
        //         reject(error);// 调用 reject,代表 Promise 会返回失败结果
        //     }
        // });

        // const promise = new Promise((resolve, reject) => {
        //     // 执行异步操作
        //     $.ajax({
        //         url: "mock/user.json",
        //         success: function (data) {
        //             console.log("查询用户成功:", data);
        //             resolve(data);
        //         },
        //         error: function (error) {
        //             reject(error);
        //         }
        //     });
        // });

        // 如果我们想要等待异步执行完成,做一些事情,我们可以通过 promise 的 then 方法来实现。
        // 如果想要处理 promise 异步执行失败的事件,还可以跟上 catch:
        // promise.then((obj) => {
        //     // 异步执行成功后的回调
        //     return new Promise((resolve, reject) => {
        //         $.ajax({
        //             url: `mock/user_corse_${obj.id}.json`,
        //             success: function (data) {
        //                 console.log("查询用户课程成功:", data);
        //                 resolve(data);
        //             },
        //             error: function (error) {
        //                 reject(error);
        //             }
        //         });
        //     })
        // }).then((data) => {
        //     console.log("上一步的结果:", data);
        //     $.ajax({
        //         url: `mock/corse_score_${data.id}.json`,
        //         success: function (data) {
        //             console.log("查询课程得分成功:", data);
        //         },
        //         error: function (error) {
        //         }
        //     });
        // })


        // 把promise的封装抽取出来
        function get(url, data) {
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: url,
                    data: data,
                    success: function (data) {
                        resolve(data);
                    },
                    error: function (error) {
                        reject(error);
                    }
                });
            })
        }

        get("mock/user.json")
            .then((data) => {
                console.log("用户查询成功~~~~~~:", data);
                return get(`mock/user_corse_${data.id}.json`);
            })
            .then((data) => {
                console.log("课程查询成功~~~~~~:", data);
                return get(`mock/corse_score_${data.id}.json`);
            })
            .then((data) => {
                console.log("课程成绩查询成功~~~~~~:", data);
            })
            .catch((err) => {
                console.log("出现异常~~~~~~:", data);
            });
    </script>
</body>

</html>

1.9 模块化

模块化就是把代码进行拆分,方便重复利用。类似 java 中的导包:要使用一个包,必须先 导包。而 JS 中没有包的概念,换来的是模块
模块功能主要由两个命令构成:exportimport

  • export命令用于规定模块的对外接口。
  • import命令用于导入其他模块提供的功能。

    二、Vue

    Vue官网

    2.1 MVVM思想

    M:即 Model,模型,包括数据和一些基本操作
    V:即 View,视图,页面渲染结果
    VM:即 View-Model,模型与视图间的双向操作(无需开发人员干涉)

在 MVVM 之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染 到 View 中。而后当用户操作视图,我们还需要通过 DOM 获取 View 中的数据,然后同步到 Model 中。
而 MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来,开发人员不用再关心 Model 和 View 之间是如何互相影响的:

  • 只要我们 Model 发生了改变,View 上自然就会表现出来。
  • 当用户修改了 View,Model 中的数据也会跟着改变。

把开发人员从繁琐的 DOM 操作中解放出来,把关注点放在如何操作 Model 上。
image.png

2.2 Vue入门

2.2.1 安装Vue

官网文档提供了 3 中安装方式:

  1. 直接 script 引入本地 vue 文件。需要通过官网下载 vue 文件。
  2. 通过 script 引入 CDN 代理。需要联网,生产环境可以使用这种方式:<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  3. 通过 npm 安装。这种方式也是官网推荐的方式,需要 nodejs 环境。

    2.2.2 创建示例项目

    管理员权限启动VSCode,先初始化项目:npm init -y,初始化完成后项目文件里会有一个package.json文件表示通过npm来管理,然后执行npm install vue
    image.png
    新建一个index.html,我们编写一段简单的代码。h1中要输出一句话:xx 非常nice。前面的xx是要渲染的数据。

    2.2.3 Vue声明式渲染&双向绑定&事件处理

    声明式渲染:

    首先通过 new Vue()来创建 Vue 实例,然后构造函数接收一个对象,对象中有一些属性:
  • el:是 element 的缩写,通过 id 选中要渲染的页面元素,本例中是一个 div
  • data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中
    • name:这里我们指定了一个 name 属性
  • 页面中的h2元素中,我们通过{{name}}的方式,来渲染刚刚定义的 name 属性。
    <body>
      <div id="app">
          <h1>xxxxx,非常nice</h1> 
          <h1>{{name}},非常nice</h1>  <!--声明式渲染-->
      </div>
        <script src="./node_modules/vue/dist/vue.js"></script>
      <script>
          //1、vue声明式渲染
          let vm = new Vue({
              el: "#app",  // el 即 element,该 vue 实例要渲染的页面元素
              data: {  // 渲染页面需要的数据
                  name: "zhangsan"
              }
          });
      </script>
    </body>
    
    通过控制台直接修改name的值,页面也会跟着变化。
    image.pngimage.png

双向绑定:

将元素与模型中的某个数据进行绑定,模型变化会引起视图变化,反之亦然。

<body>
    <div id="app">
        <!--双向绑定,输入几个人,就显示几个人点赞-->
        <input type="text" v-model="num">
        <h1>{{name}},非常nice,有{{num}}人为他点赞</h1>  <!--双向绑定-->
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        //1、vue声明式渲染
        let vm = new Vue({
            el: "#app",  // el 即 element,该 vue 实例要渲染的页面元素
            data: {  // 渲染页面需要的数据
                name: "zhangsan",
                num: 1
            }
        });
    </script>
</body>

image.png

事件处理:

给页面添加一个按钮:

<body>
    <div id="app">
        <!--双向绑定,输入几个人,就显示几个人点赞-->
        <input type="text" v-model="num">
        <h1>{{name}},非常nice,有{{num}}人为他点赞</h1>  <!--双向绑定-->

        <button v-on:click="num++">点赞</button>  <!--事件处理-->
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        //1、vue声明式渲染
        let vm = new Vue({
            el: "#app",  // el 即 element,该 vue 实例要渲染的页面元素
            data: {  // 渲染页面需要的数据
                name: "zhangsan",
                num: 1
            }
        });
    </script>
</body>

这里用v-on指令绑定点击事件,而不是普通的onclick,然后直接操作 num
image.png
未来我们会见到更多 v-xxx,这些都是 vue 定义的不同功能的指令。

使用总结

v-xx指令

  1. 创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板上(使用 Vue 实例管理 DOM)
  2. 指令来简化对dom的一些操作
  3. 声明方法来做更复杂的操作。methods里面可以封装方法。 ```html <!DOCTYPE html>

xxxxx,非常nice

{{name}},非常nice

{{name}},非常nice,有{{num}}人为他点赞


<a name="f6emz"></a> ## 2.3 Vue常用指令 什么是指令? - 指令 (Directives) 是带有 `v-` 前缀的特殊特性。 - 指令特性的预期值是:单个 JavaScript 表达式。 - 指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。 例如我们在入门案例中的 v-on,代表绑定事件。 <a name="ITcR9"></a> ### 2.3.1 插值表达式 <a name="RhFLa"></a> #### 花括号 格式:{{表达式}}<br />该表达式支持 JS 语法,可以调用 js 内置函数(必须有返回值)<br />表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:let a = 1 + 1;<br />可以直接获取 Vue 实例中定义的数据或函数 <a name="v9VoZ"></a> #### 插值闪烁 使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的`{{}}`, 加载完毕后才显示正确数据,我们称为插值闪烁。 <a name="jPxOS"></a> #### v-text 和 v-html 可以使用 v-text 和 v-html 指令来替代{{}}。<br />v-text:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出;<br />v-html:将数据输出到元素内部,如果输出的数据有 HTML 代码,会被渲染html <!DOCTYPE html>
{{msg}} {{1+1}} {{hello()}}

![image.png](https://cdn.nlark.com/yuque/0/2022/png/22423156/1641128766961-af979040-c87e-46bf-a1d0-c57fa38193fd.png#clientId=u1ef977ef-e979-4&from=paste&height=131&id=u4c90c143&margin=%5Bobject%20Object%5D&name=image.png&originHeight=175&originWidth=221&originalType=binary&ratio=1&size=4891&status=done&style=none&taskId=uae51eb18-12c7-4df2-b1b5-54095f703c1&width=166)不会出现插值闪烁,当没有数据是,会显示空白或者默认数据。 <a name="h4Gbx"></a> ### 2.3.2 v-bind html 属性不能使用双大括号形式绑定,我们使用 v-bind 指令给 HTML 标签属性绑定值;而且在将 `v-bind` 用于 `class` 和 `style` 时,Vue.js 做了专门的增强。html <!DOCTYPE html>
gogogo
你好
![image.png](https://cdn.nlark.com/yuque/0/2022/png/22423156/1641129025010-264e1909-7b95-4d6b-9e3f-61aa33fede9e.png#clientId=u1ef977ef-e979-4&from=paste&height=63&id=u91a97803&margin=%5Bobject%20Object%5D&name=image.png&originHeight=63&originWidth=178&originalType=binary&ratio=1&size=2578&status=done&style=none&taskId=u92c36037-b21a-49bc-b4e7-8e6271f9abf&width=178) <a name="Q4qlW"></a> ### 2.3.3 v-model 刚才的 v-text、v-html、v-bind 可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。接下来学习的 v-model 是双向绑定,视图(View)和模型(Model)之间会互相影响。<br />既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。目前v-model 的可使用元素有:input、select、textarea、checkbox、redio、components(Vue中自定义组件)基本上除了最后一项,其它都是表单的输入项。html <!DOCTYPE html>
精通的语言: java
PHP
Python
选中了 {{language.join(“,”)}}
![image.png](https://cdn.nlark.com/yuque/0/2022/png/22423156/1641129423619-d9c85578-052a-4338-81ec-3175dd6fab0a.png#clientId=u1ef977ef-e979-4&from=paste&height=179&id=u27a1ec69&name=image.png&originHeight=239&originWidth=749&originalType=binary&ratio=1&size=14209&status=done&style=none&taskId=u252bead8-8a0a-45dc-9392-493fd08d659&width=562) <a name="g2sKl"></a> ### 2.3.4 v-on <a name="bP9Pi"></a> #### 1. 基本用法 v-on 指令用于给页面元素绑定事件。语法: v-on:事件名="js 片段或函数名"html

有{{num}}个赞

另外,事件绑定可以简写,例如`v-on:click='add'`可以简写为`@click='add'` <a name="xTRkU"></a> #### 2. 事件修饰符 在事件处理程序中调用 `event.preventDefault()` 或 `event.stopPropagation()` 是非常常见的 需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑, 而不是去处理 DOM 事件细节。<br />为了解决这个问题,Vue.js 为 `v-on` 提供了事件修饰符。修饰符是由点开头的指令后缀来 表示的。<br />`.stop` :阻止事件冒泡到父元素<br />`.prevent`:阻止默认事件发生<br />`.capture`:使用事件捕获模式<br />`.self`:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)<br />`.once`:只执行一次 <a name="mGCKa"></a> #### 3. 按键修饰符 在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 `v-on` 在监听键盘事件时添 加按键修饰符。 <a name="jU7wy"></a> ### 其他指令以及计算属性和侦听器直接参考文档 <a name="eZvvF"></a> ## 2.4 组件化 在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。 例如可能会有相同的头部导航。但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。在 vue 里,所有的 vue 实例都是组件。html <!DOCTYPE html>

使用全局组件:
使用vue实例中的局部组件:

<a name="hw2Fv"></a>
## 2.5 生命周期钩子函数
<a name="JSy9n"></a>
### 2.5.1 生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模
板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于
不同的生命周期时,对应的函数就会被触发调用。
<br />生命周期:你不需要立马弄明白所有的东西。
<a name="fWFff"></a>
### 2.5.2 钩子函数
```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <span id="num">{{num}}</span>
        <button @click="num++">赞!</button>
        <h2>{{name}},有{{num}}个人点赞</h2>
    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        let app = new Vue({
            el: "#app",
            data: {
                name: "张三",
                num: 100
            },
            methods: {
                show() {
                    return this.name;
                },
                add() {
                    this.num++;
                }
            },
            beforeCreate() {
                console.log("=========beforeCreate=============");
                console.log("数据模型未加载:" + this.name, this.num);
                console.log("方法未加载:" + this.show());
                console.log("html模板未加载:" + document.getElementById("num"));
            },
            created: function () {
                console.log("=========created=============");
                console.log("数据模型已加载:" + this.name, this.num);
                console.log("方法已加载:" + this.show());
                console.log("html模板已加载:" + document.getElementById("num"));
                console.log("html模板未渲染:" + document.getElementById("num").innerText);
            },
            beforeMount() {
                console.log("=========beforeMount=============");
                console.log("html模板未渲染:" + document.getElementById("num").innerText);
            },
            mounted() {
                console.log("=========mounted=============");
                console.log("html模板已渲染:" + document.getElementById("num").innerText);
            },
            beforeUpdate() {
                console.log("=========beforeUpdate=============");
                console.log("数据模型已更新:" + this.num);
                console.log("html模板未更新:" + document.getElementById("num").innerText);
            },
            updated() {
                console.log("=========updated=============");
                console.log("数据模型已更新:" + this.num);
                console.log("html模板已更新:" + document.getElementById("num").innerText);
            }
        });
    </script>
</body>

</html>

image.png

三、Vue模块化开发

3.1 全局安装webpack、vue 脚手架

管理员打开cmd中执行:npm install webpack -gnpm install -g @vue/cli-init

3.2 初始化vue项目

创建一个新项目文件夹,然后以管理员身份启动cmd并cd到该路径下,执行vue init webpack 项目名称
报错:
这里我出现了报错:’vue’ 不是内部或外部命令,也不是可运行的程序,原因是因为全局安装路径没有加入到环境变量中(我在前面安装node.js的时候设置了全局安装目录)。
在cmd中执行:npm config list
如果没有指定目录会输出:buildin config undefined,prefix=”xxxxxx”
image.png
把prefix里面的路径配置到环境变量中即可。
Vue build的时候选Runtime+Compiler
image.png
image.png
然后按照提示先cd vue-demo,再npm run dev
image.png
然后访问:localhost:8080
image.png
通过VSCode打开我们的项目,在终端中输入npm run dev启动项目。

3.3 模块化开发

3.3.1 项目结构

目录/文件 说明
build 项目构建{webpack}相关代码
config 配置目录,包括端口号等
node_modules npm加载的项目依赖模块
src 开发目录,我们要做的事情都在这个目录里
- assets:放图片logo等
- components:目录里面放了一个组件文件,可以不用
- App.vue:项目入口文件,我们也可以直接将组件写在这,不用components目录
- main.js:项目的核心文件
static 静态资源目录,如图片字体
test 初始测试目录,可删除

image.png
运行流程:

  • 进入页面首先加载 index.html 和 main.js 文件。
  • main.js 导入了一些模块【vue、app、router】,并且创建 vue 实例,关联 index.html 页面的
    元素。使用了 router,导入了 App 组件。并且使用标签 引用了这个组件
  • 第一次默认显示 App 组件。App 组件有个图片和,所以显示了图片。 但是由于代表路由的视图,默认是访问/#/路径(router 路径默认使用 HASH 模式)。在 router 中配置的/是显示 HelloWorld 组件。
  • 所以第一次访问,显示图片和 HelloWorld 组件。

    3.3.2 Vue 单文件组件

    Vue单文件组件模板有三个部分:Template(编写模板)、Script(vue实例配置)、Style(样式)
    我们尝试写一个自己的组件Hello.vue,并且加入路由。点击跳转。需要使用to=”/foo”>Go to Foo标签 ```vue
``` 然后在router/index.js里面配置路由(main.js中导入的就是此路由): ```javascript import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Hello from '@/components/Hello' // 导入Hello.vue Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, { path: '/hello', // 设定访问路径 类似于springboot中的@RequestMapping name: 'hello', // 设定路由名称 component: Hello } ] }) ``` ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22423156/1641180048115-d1c15c9e-293e-4edb-817b-3ad8cc052349.png#clientId=u1ef977ef-e979-4&from=paste&height=200&id=u661bedc2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=399&originWidth=599&originalType=binary&ratio=1&size=25426&status=done&style=none&taskId=u186f9de1-18e5-4c3a-b326-857d5387d22&width=300)
然后我们在项目入口文件App.vue中设置超链接跳转路由,需要用到`Go to hello ` to="/xxxxx" 里面要填的就是我们在router/index.js里面配置的路由访问路径(path) ```vue ``` ### 3.3.3 导入 element-ui 快速开发 [https://element.eleme.cn/#/zh-CN/component/container](https://element.eleme.cn/#/zh-CN/component/container)
安装 element-ui: `npm i element-ui`
在 main.js 中引入 element-ui 就可以全局使用了: ```javascript import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) ``` ### 3.3.4 vscode 添加用户代码片段(快速生成 vue 模板) 文件-->首选项-->用户代码片段-->点击新建代码片段--取名 vue.json 确定 ```json { "生成 vue 模板": { "prefix": "vue", "body": [ "", "", "", "" ], "description": "生成 vue 模板" } } ``` 然后直接输入vue即可生成Vue模板。 ### 3.3.5 抽取main中的用户信息table 使用elementUI提供的Container布局容器示例,将main中的table抽取出来。我们想通过点击aside的用户列表显示用户信息。 #### 原始示例 ```vue
<a name="DpvNc"></a>
#### 新建一个Vue——MyTable.vue
直接通过之前的模板生成vue模板,然后将table抽取出来,作为一个单独的组件
```html
<template>
  <div>
    <!-- 抽取的table -->
    <el-table :data="tableData">
      <el-table-column prop="date" label="日期" width="140"> </el-table-column>
      <el-table-column prop="name" label="姓名" width="120"> </el-table-column>
      <el-table-column prop="address" label="地址"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';

export default {
  //import 引入的组件需要注入到对象中才能使用
  components: {},
  props: {},
  data() {
    //这里存放数据  抽取的实例中的数据
    const item = {
      date: "2016-05-02",
      name: "王小虎",
      address: "上海市普陀区金沙江路 1518 弄",
    };
    return {
      tableData: Array(20).fill(item),
    };
  },
  //计算属性 类似于 data 概念
  computed: {},
  //监控 data 中的数据变化
  watch: {},
  //方法集合
  methods: {},
  //生命周期 - 创建完成(可以访问当前 this 实例)
  created() {},
  //生命周期 - 挂载完成(可以访问 DOM 元素)
  mounted() {},
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有 keep-alive 缓存功能,这个函数会触发
};
</script>
<style lang='scss' scoped>
//@import url(); 引入公共 css 类
</style>

设置路由规则&启动NavMenu导航菜单的路由模式

在router/index.js中添加路由规则
image.png
添加后会报错:
image.png
原因是因为vue模板中生成的