Vue.js (vuejs.org)

Bootstrap可视化布局系统 (bootcss.com)

MyBatis入门学习-KuangStudy-文章

一 前端体系

  1. 此课程的重点

    1. 前端的话,页面我不会再给大家多讲了。重点难就难在,这些框架怎么使用,比如说前端化工程。
  2. java全栈工程师:
    1. 后台开发:主打
    2. 前端:html、css、js、jquery、bootstrap、layui、vue、react......
    3. 运维:项目发布;服务器如何运行一个项目?
  3. 前端组成,3要素
    1. html:结构层
    2. css:表现层。如改颜色、加边框、定位......
      1. CSS预处理器

        1. 业务:css不是编程语言,而是标记语言。语法不够强大,没有变量和合理的样式复用机制。
        2. 需求:
          1. 解决上面的问题。
          2. 作用:提供 CSS 缺失的样式层复用机制、减少冗余代码,提高样式代码的可维护性和开发效率。
        3. 思想(路):CSS 预处理器定义了一种新的语言,这种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件(即程序本身并不是css言语写的,但这个程序运行的结果,它会产生一个css文件,即用程序的方式去编。类似于java程序编译打包完成,会产生一个.jar包一样。),然后开发者就只要使用这种语言进行 CSS 的编码工作。
             转化成通俗易 懂的话来说就是“用一种专门的编程语言,进行 Web 页面样式设计,再通过(前端)编译器转化为正常的 CSS 文件,以供项目使用”。
        4. 流(原):如淘宝每年都会有年中618、双11、双12是吧,而这3个购物节使用的css样式肯定不一样是吧。那怎么办呢?每到一个购物节,阿里的那些开发人员,肯定不会直接把css写死在页面中,这样写死地改来改去会非常消耗人力和时间,很麻烦。那到底怎么办呢?他们会想一些办法,跟编程一样,写一个程序让程序自动输出css。每到一个购物节,就去改程序,自动输出新的css样式即可。动态输出css(如定时输出),这就是所谓的css预处理器。
        5. 常用的css预处理器有哪些:
          1. SASS:基于 Ruby,通过服务端处理,功能强大。解析效率高。需要学习 Ruby 语言,上手难度高于 LESS。
          2. LESS:基于 NodeJS,通过客户端处理,使用简单。功能比 SASS 简单,解析效率也低于 SASS,但在实际开发中足够了,所以如果我们后台人员如果需要的话,建议使用 LESS。
          3. 总结:几乎现在专业的前端都在用LESS写,如果做为一个前端还在用css写,那你效率会很低。
    3. javascript:行为层
      1. Native:最早,是原生JS开发。

        1. 原生 JS 开发,也就是让我们按照 ECMAScript(ES)标准的开发的。
        2. 目前的情况:最高版本是es9,最流行的是es6,但很多浏览器还停留在es5,而且对于大多数浏览器厂商的最高版本也只是部分支持es6。对于不支持es6的浏览器(低版本)来说怎么办呢?开发时可以使用es6规范去开发,但需要用webpack打包工具把es6的代码降级成为es5,如let转var。
      2. TypeScript微软的标准
        1. 业务:javascript的缺陷
        2. 需求:解决这些缺陷
        3. 流(原):很神奇,微软的TypeScript编写的程序,运行的结果是变成一堆javascript代码。和上面的less一样,你用less编写的程序,运行的结果是不是生成css了。
    4. 常用的javascript构架:
      1. jquery:就是一个类库。
      2. Angular:mvvm
        1. 如何理解:“将后台的 MVC 模式搬到了前端并增加了模块化开发的念”?

          1. mvc的3要素分别是,m(模型)、v(视图)、c(控制器)。
          2. 原来的前端:只有一个v(视图),即html + css + js。后面ajax出现了,使用ajax(Axios)以后,可以与后台进行通信、交互。而视图的数据(data,即m(模型))都是我们后端给它渲染过去的
          3. Angular前端:在前端实现了mvc架构(模式),称为mvvm,其中m(模型)、v(视图)、vm(view model,即数据双向绑定)
      3. React:虚拟化dom
        1. 原来的dom操作:是通过js(如document.getElementByTag/getElementById等),对dom树进行CRUD,或者在获取dom对象以后对dom对象的文档、css进行一定的调整。
        2. 虚拟dom:最大的特点是它利用了内存,利用内存来缓存一些dom元素,并在内存中操作dom,有效地提高了前端的渲染率。 你们都听过,vuejs的“计算属性、计算属性缓存 vs 方法”这2个东西是吧。以前学计算属性的时候,老师是不是跟你们讲了虚拟dom。“计算属性“是vue的特色,是vue独有的。而“计算属性“这个特色是怎么来的?就是利用虚拟dom来的。
      4. Vue:mvvm + 虚拟化dom
        1. 渐进式:就是逐步实现新特性的意思,比如vuejs会慢慢去实现es6的规范、慢慢去实现模块化的规范、慢慢实现虚拟化dom、慢慢模块化、慢慢路由、慢慢状态管理等等。
        2. vue集成了Angular和React的优点,即说明了vue中也有mvvm、也有虚拟化dom。
        3. 后端学习它并不会觉得很难,因为它是模块化开发的
      5. Axios
        1. 前端的通信框架,只做通信(soc原则),相当于ajax、jquery ajax
    5. 前端流行的UI框架
      1. Ant-Design
      2. ElementUI:主要特点是桌面端支持较多
      3. iview:主要特点是移动端支持较多
      4. ice
      5. Bootstrap
      6. AmazeUI
    6. javascript构建工具
      1. babel:一般更多地是用于编译TypeScript
      2. webpack:模块打包工具,一般会用它来打包咱们的前端程序
    7. 总结:前端也在发展(css框架成百上千、javascript的框架也成面上千),但发展的很乱,但始终有一些是流行的、受到行业追捧的东西。
  4. 前端知识,6要素
    1. 逻辑

      1. 判断:判断一下这东西该不该展示
      2. 循环
    2. 事件
      1. 那我们刚才跟你说的那堆javascript代码(BOM、DOM操作),它是在干嘛?是不是叫做事件呀。事件的话那就非常多了,但总的来说就两类:浏览器事件(BOM)和标签事件(DOM)。BOM事件,说得难听一点,其实也就两个window事件、document(文档)事件。DOM事件常见的:增、删、遍历、修改节点元素内容。
      2. 那么前端所说的事件,有没有框架来做呀?有呀,比如jquery(库)封装了大量的事件、vuejs、React......
    3. 视图:应该怎么画才好看
      1. 前端所说的视图视图说白了就是:第1点:给用户看;第2点:刷新后台,就是做这两件事情而已。
      2. 前端所说的视图由谁来做?html、cs、js呀。
      3. 其实前端最难的是css,一个像素都不能错,不然不好看。
      4. 基于html、css衍生出很多我们熟知的前端视图框架:bootstrap、layui、Vue-Ui即vue相关的视图组件框架库(如飞冰ice.work、Element-Ui)......
    4. 网络通信
      1. xhr:原生javascript
      2. ajax:jquery封装
      3. axios框架:vuejs
    5. 页面跳转:
      1. 路由(转发):vue自己开发的组件:vue-router,来控制页面跳转的。
    6. 状态管理:
      1. 状态管理:就是vue会把所有的东西统一管理,这就是vuex来做的。
  5. Vue概述
    1. 前端3大框架:vue、AngularJS、React.js。
    2. vue是一个渐进式的前端框架。
    3. Vue 的核心库只关注视图层,这句话什么意思?其中视图层,就是html、css、js做的东西吧。而网络通信,vue用管吗?不用。使用的是axios框架,去管网络通信的部分。页面跳转,vue用得着管吗?也不用。使用的是vuejs自己开发的组件vue-router,去管页面跳转的部分。状态管理,vue用得着管吗?那也不用。使用的是,vuex来做的。也就是说vue只关注视图层的意思是,vue只跟上面的这3个(html、css、js)打交道。
         Vue只关注视图层,并遵守一个原则,叫做soc原则(Separation of concerns,关注点分离原则,关注点分离 - 中文维基百科【维基百科中文版网站】 (cljtscd.com))。也就是说,它会把它的关注点分得特别散,vue只管视图层。
  6. webpack
    1. 原理:最高版本是es9,最流行的是es6,但很多浏览器还停留在es5,而且对于大多数浏览器厂商的最高版本也只是部分支持es6。对于不支持es6的浏览器(低版本)来说怎么办呢?开发时可以使用es6规范去开发,但需要用webpack打包工具把es6的代码降级成为es5,如let转var。webpack把es6的代码打包成浏览器能够认识的代码。
              我们后台有没有打包工具?有,maven就是我们后台的打包工具(构建、管理、打包工具),maven就是把java源代码打包成服务器能够认识的程序。

二 前端:三端统一开发

  1. 混合开发(Hybrid App)

    1. 主要目的是实现一套代码三端统一(PC、Android:.apk、IOS:.ipa)并能够调用到设备底层硬件(如:传感器、GPS、摄像头等),打包方式主要有以下两种:

      1. 云打包:HBuild -> HBuildX ,DCloud出品;API Cloud
      2. 本地打包:Cordova(前身是 PhoneGap)
  2. 微信小程序
    1. 详见微信官网,这里就是介绍一个方便微信小程序UI开发的框架:WeUI。

三 后端技术:前端所需后端技术

        前端人员为了方便开发也需要掌握一定的后端技术,但我们 Java 后台人员知道后台知识体系极其庞大复 杂,所以为了方便前端人员开发后台应用,就出现了 NodeJS 这样的技术。
        NodeJS 的作者已经声称放弃 NodeJS(说是架构做的不好,再加上笨重的 node_modules,可能让作者不爽了吧),开始开发全新架构的 Deno。
        既然是后台技术,那肯定也需要框架和项目管理工具,NodeJS 框架及项目管理工具如下:
  1. Express:NodeJS 框架
  2. Koa:Express 简化版
  3. NPM:项目综合管理工具,类似于 Maven。npm install(安装)其实就相当于java maven下载依赖包,且进行包管理。
  4. YARN:NPM 的替代方案,类似于 Maven 和 Gradle 的关系。

四 前后端分离的演变史

  1. 第1阶段,2005年之前(web 1.0):后端为主的 MVC 时代,如springmvc

    1. 流程

      1. 发起请求到前端控制器( DispatcherServlet )
      2. 前端控制器请求 HandlerMapping 查找 Handler ,可以根据 xml 配置、注解进行查找
      3. 处理器映射器 HandlerMapping 向前端控制器返回 Handler
      4. 前端控制器调用处理器适配器去执行 Handler
      5. 处理器适配器去执行 Handler
      6. Handler 执行完成给适配器返回 ModelAndView
      7. 处理器适配器向前端控制器返回 ModelAndView , ModelAndView 是 SpringMVC 框架的一个底层对象,包括 Model 和 View
      8. 前端控制器请求视图解析器去进行视图解析,根据逻辑视图名解析成真正的视图( JSP )
      9. 视图解析器向前端控制器返回 View
      10. 前端控制器进行视图渲染,视图渲染将模型数据(在 ModelAndView 对象中)填充到 request 域
      11. 前端控制器向用户响应结果
      12. 注:图里面的所有东西,只有一个controller是开发者需要做的而已。
    2. 缺点
      1. 前后端职责纠缠不清
  2. 第2阶段:2005年(web 2.0):基于 AJAX 带来的 SPA 时代
  3. 第3阶段:now现在:大前端时代,即前端为主的 MV* 时代
    1. MV*

      1. MVC(同步通信为主):Model、View、Controller
      2. MVP(异步通信为主):Model、View、Presenter
      3. MVVM(异步通信为主):Model、View、ViewModel
    2. 1 ~ 1.8 ~ 3
    3. 分布式、微服务、大数据
  4. 第4阶段:NodeJS 带来的全栈时代
    1. 如nodejs前后端都可以做了。
    2. 但nodejs永远都不可能干掉java,因为js语言有它天生的弊端。

五 MVVM模式

1 MVVM模式的组成部分

  1. 从上图可知道MVVM的组成部分:

    1. V - View

      1. HTML
      2. CSS
      3. Template(如jsp、Thymeleaf,通过${ooo}(#{ooo},即Template模板)获取数据
    2. 双向数据绑定
      1. M层(数据)会通过VM层去跟V层(前端,即html、css、Template)进行双向数据绑定。

        1. 情况1:VM层会去监听M层(数据),如果M层(数据)发生了改变,那么V层也要发生变化。M是1,V显示为1;当M变成2,V显示为2。
        2. 情况2:VM层会去监听V层(前端,即html、css、Template),如果V层(前端,即html、css、Template)发生了改变,那么M层(数据)也要发生变化。
    3. VM - ViewModle
      1. JavaScript
      2. Runtime:即时运行。当M变成2,V及时显示为2。
      3. Compiler:即时编译。当M变成2,V及时显示为2。
    4. ajax & json
      1. ajax请求java业务逻辑(数据库),java业务逻辑(数据库)返回json数据。
    5. M - Model
      1. java业务逻辑层

        1. 数据库
  2. mvvm双向数据绑定的工作流程:
    1. 第一步:v层(view)与vm层(viewModel)进行双向数据绑定(操作虚拟dom,页面显示快、流畅;区别于js使用document来操作真实的dom元素,页面显示卡顿。)
    2. 第二步:vm层通过ajax访问java后台(数据库),java后台(数据库)返回json数据。

六 第一个vue程序(vue是MVVM 模式的实现者,他的核心就是实现了 DOM 监听 与 数据绑定)

  1. 环境准备

    1. 第一步:创建vue工程(文件夹)
    2. 第二步:使用vscode的open project(目录)打开工程
    3. 第三步:官网下载vue.js
      1. 开发版本

        1. 包含完整的警告和调试模式:https://vuejs.org/js/vue.js
        2. 删除了警告,30.96KB min + gzip:https://vuejs.org/js/vue.min.js
      2. CDN​​​​​​(在线,即在线的CDN)
        1. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"> </script>​​​​​​:min.js是压缩版的,就一行代码。
        2. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>​​​​​​:这个是完整版的代码。
    4. 注   意:如果是idea,需要安装vue插件
  2. 开发
    1. 第一步:新建demo1.html
    2. 第二步:导包(要用vue,就要导包),使用在线的cdn方式:<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>​​​​​​
    3. 第三步:<script></script>
      1. 第1步:创建vue对象(VM层,监听,即双向数据绑定)

        1. 第(1)步:el:绑定元素,相当于document.getElementById()
        2. 第(2)步:data对象:键值对(M层,即数据)
        3. 第(3)步:method方法:方法必须定义在method中。键值对。
    4. 第四步:html标签(V层
      1. 第1步:使用{{}}({{}},即Template模板),获取data对象中的数据
    5. 第五步:浏览器
      1. 第1步:演示双向数据绑定

七 基础语法

  1. 指令:v- 开头

    1. v-bind:除了使用插值表达式{{}}进行数据渲染,也可以使用 v-bind指令,它的简写的形式就是一个冒号(:)

      1. 手动:我们在控制台操作对象属性,界面可以实时更新!
      2. 自动:我们还可以使用 v-bind 来绑定元素特性 !
      3. 案例:
            <body><div id="app"><!--如果要将模型数据绑定在html属性中,此时title中显示的是模型数据--><h1 v-bind:title="message">鼠标悬停几秒钟查看此处动态绑定的提示信息!</h1><!-- v-bind 指令的简写形式: 冒号(:) --><h1 :title="message">我是标题</h1></div><script>new Vue({el: '#app',data: {message: '页面加载于 ' + new Date().toLocaleString()}})</script></body>
    2. v-if 系列
      1. v-if
      2. v-else-if
      3. v-else
      4. 案例
        <body><div id="app"><!--=== 三个等号在 JS 中表示绝对等于(就是数据与类型都要相等)--><h1 v-if="type === 'A'">A</h1><h1 v-else-if="type === 'B'">B</h1><h1 v-else-if="type === 'C'">C</h1><h1 v-else>who</h1></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script>var vm = new Vue({el: '#app',data: {type: 'A'}})</script>
        </body>
    3. v-for
      <body><div id="app"><li v-for="item in items">{{ item.message }}</li></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script>var vm = new Vue({el: '#app',data: {//items数组items: [{message: '狂神说Java'},{message: '狂神说前端'}]}});
      </script>
      </body>

八 事件:v-on,我们可以使用 v-on 指令 (简写为 @) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript(方法、函数)。

<body><div id="app"><!--在这里我们使用了 v-on 绑定了 click 事件并指定了名为 sayHi 的方法--><button v-on:click="sayHi">点我</button><!-- v-on 指令的简写形式 @ --><button @click="sayHi">点我</button></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script>var vm = new Vue({el: '#app',data: {message: 'Hello World'},// 方法必须定义在 Vue 实例的 methods 对象中// 这里必须传递一个事件对象eventmethods: {sayHi: function (event) {// `this` 在方法里指向当前 Vue 实例alert(this.message);}}});</script>
</body>

九 双向数据绑定:Vue.js的精髓之处:v-model

  1. Vue.js的精髓之处:

    1. Vue.js是一个MVVM框架,即数据双向绑定。

      1. 即当数据发生变化的时候,视图也就发生变化。
      2. 而当视图发生变化的时候,数据也会跟着同步变化。
  2. 在表单中使用双向数据绑定
    1. 你可以用v-model指令在表单<input> 、<textarea> 及<select>元素上创建双向数据绑
      定。
    2. 它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
    3. 案例1:<input>、<textarea>
      <!DOCTYPE html>
      <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说java</title><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script></head><body><div id="app">输入的文本:<input type="text" v-model="message"> <br/>输入的文本是:{{message}}</div><script>new Vue({el: '#app',data: {message: '123'}})</script></body>
      </html>
    4. 案例2:<redio>、<checkbox>
      <!DOCTYPE html>
      <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说java</title><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script></head><body><div id="app">性别:男<input type="radio" value="男" v-model="kuangshen"> 女<input type="radio" value="女" v-model="kuangshen"><br/> 选中的是:{{kuangshen}}</div><script>new Vue({el: '#app',data: {kuangshen: '女' //将Vue实例的数据作为数据来源}})</script></body>
      </html>
    5. 案例3:<select>
      <!DOCTYPE html>
      <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说java</title><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script></head><body><div id="app">下拉框:<select v-model="kuangshen"><option value="" disabled>--请选择--</option><option>A</option><option>B</option><option>C</option></select><br/>选择中的值:{{kuangshen}}</div><script>new Vue({el: '#app',data: {kuangshen: 'B'}})</script></body>
      </html>
    6. 注意1: v-model会忽略所有表单元素的value、checked、selected 特性的初始值,而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!
  3. 注意事项
    1. 注意1:值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的,非UI控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用vuex ,那么数据流也是单项的,这时就会和双向数据绑定有冲突。
    2. 注意2:在Vue.js中,如果使用vuex,实际上数据还是单向的,之所以说是数据双向绑定,这是用的UI控件来说,对于我们处理表单,Vue.js的双向数据绑定用起来就特别舒服了。即两者并不互斥,在全局性数据流使用单项,方便跟踪;局部性数据流使用双向,简单易操作。

十 组件

  1. 业务:通常一个应用会以一棵嵌套的组件树的形式来组织(这和我们嵌套 HTML 元素的方式类似)。
  2. 需求:组件可复用(html标签是复用的)。
  3. 思路、想:组件是可复用的 Vue 实例,说白了就是一组可以重复使用的模板,跟 html / JSTL 的自定义标签(如自定义一个标签<kuangshen></kuangshen>,然后可以复用在html页面中)、Thymeleaf 的 th:fragment 等框架有着异曲同工之妙。
  4. 组织结构:
  5. 案例1:
    <!DOCTYPE html>
    <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说java</title><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script></head><body><div id="app"><ul><!-- 有点类似自定义标签 --><kuangshen-component-li></kuangshen-component-li></ul></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script>// 先注册组件Vue.component('kuangshen-component-li', { // 名称template: '<li>Hello li</li>'         // 模板,其实就是由多个html标签组成的});// 再实例化 Vuevar vm = new Vue({el: '#app'});</script></body>
    </html>
  6. 案例2:

    <!DOCTYPE html>
    <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说java</title><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script></head><body><div id="app"><ul><!--第一步:写上组件<kuangshen-component-li></kuangshen-component-li>,即代表template属性中的内容。问题:template属性中<li>标签之间要求有数据?答:而数据从items数组来。 --><!--第二步:v-for="item in items"循环获取items数组中的每个数据,每一项数据的别名都叫item。--><!--第三步:使用v-bind获取for循环中的每一个数据(item),并绑定组件对象中props属性列表中的参数panshengbo。--><kuangshen-component-li v-for="item in items" v-bind:panshengbo="item"></kuangshen-component-li></ul></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script>Vue.component('kuangshen-component-li', { //第四步:问题:直接写'<li>{{panshengbo}}</li>'是获取不了数据“panshengbo”的,我们需要通过一个参数去接收,即props。//        props:['panshengbo']用于接收传输过来的数据。//        如果你不用props,你是无法直接接收外面的数据的。props:['panshengbo'],//第五步:template的<li>中使用{{panshengbo}}来传输过来的每个数据。template: '<li>{{panshengbo}}</li>'    });var vm = new Vue({el: '#app',data:{items:["java","linux","前端"]}});</script></body>
    </html>
  7. 与vue的关系:

    1. 如下图,是xxx.vue文件的组织形式:

    2. 从上面的xxx.vue文件的组织方式、组件基础的知识,可以看出,xxx.vue和组件都有一个共同的标签,那就是<template>吧。到此,总算和vue粘一点边了。

十一 vue的生命周期(钩子函数)

官方文档:https://cn.vuejs.org/v2/guide/instance.html#生命周期图示
  1. 在 Vue 的整个生命周期中,它提供了一系列的事件(开始创建、初始化数据、编译模板、挂载 DOM、渲染→更新→渲染、卸载等)。
  2. 可以让我们在事件触发时注册 JS 方法,可以让我们 用自己注册的 JS 方法控制整个大局。
  3. 在这些事件响应方法中的 this 直接指向的是 Vue 的实例。

十二 axios异步通信

  1. Axios 概述
    1. 原因:

      1. 少用 jQuery,因为它操作Dom太频繁!
    2. 定义:
      1. 【官网】易用、简洁且高效的http库
    3. 作用:
      1. Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架,它的主要作用就是实现 AJAX 异步通信。
    4. 特点:
      1. 从浏览器中创建 XMLHttpRequests
      2. 从 node.js 创建 http 请求
      3. 支持 Promise API [ JS中链式编程 ]
      4. 拦截请求和响应
      5. 转换请求数据和响应数据
      6. 取消请求
      7. 自动转换 JSON 数据
      8. 客户端支持防御 XSRF(跨站请求伪造)
    5. 地址:
      1. GitHub:https://github.com/axios/axios
      2. 中文文档:http://www.axios-js.com/
    6. 注意事项
      1. idea设置为支持es6规范的(不然代码会报编译异常)
      2. 浏览器必须是支持es6规范的
  2. 案例1:data.json、demo7.html 只取数据
    {"name":"狂神说java","url": "http://baidu.com","page": "1","isNonProfit":"true","address": {"street": "含光门","city":"陕西西安","country": "中国"},"links": [{"name": "B站","url": "https://www.bilibili.com/"},{"name": "4399","url": "https://www.4399.com/"},{"name": "百度","url": "https://www.baidu.com/"}]}
    <!DOCTYPE html>
    <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说Java</title></head><body><div id="app"></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script type="text/javascript">var vm = new Vue({el:'#app',mounted() { //  第一步:钩子函数//  第二步:axiosn发送异步请求,获取json文件的数据,并在控制台打印axios.get('data.json').then(response => (console.log(response.data)));}});</script></body>
    </html>
  3. 案例2:data.json demo7.html 渲染数据
    <!DOCTYPE html>
    <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说Java</title></head><body><div id="app"><div>{{info.name}}</div><div>{{info.address.street}}</div><!-- 数据绑定到属性 --><a v-bind:href="info.url">听我</a></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script type="text/javascript">var vm = new Vue({el:'#app',data(){ //  功能相当于data属性return{//  这个地方只是摆格式,并没有真正的数据。//  而且这里的格式,必须和json字符串格式一样info:{name:null,url:null,address:{street:null,city:null,country:null}}}},mounted() { //  第一步:钩子函数//  第二步:axios发送异步请求,获取json文件的数据,并且数据取名为info//  第三步:data(){return中的info}用于接收axios返回的数据axios.get('data.json').then(response => (this.info = response.data));}});</script></body>
    </html>
  4. 注意事项
    1. vue的闪烁事件
    2. 谷歌浏览器报:Access to XMLHttpRequest at ‘fileDxxxxx.json‘ from origin ‘null‘ has been blocked by CORS问题解决

十三 计算属性

  1. 定义:计算(动词)+   属性(名词)
  2. 需求:
    1. 内存中运行:虚拟Dom,速度快
    2. 计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;
  3. 解决方案:计算属性
  4. 思想路:
    1. 将计算出来的结果保存到一个属性中,可以想象成缓存!
  5. 案例
    <!DOCTYPE html>
    <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说Java</title></head><body><div id="app"><div>{{message}}</div><!-- 调用方法 --><div>{{currentTime1()}}</div><!-- 计算属性(区别于调用方法) --><div>{{currentTime2}}</div></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script type="text/javascript">var vm = new Vue({el:'#app',data: {//  方案1:普通属性(注意区别于计算属性)message: 'Hello Vue'},methods: {//  方案2:调用方法currentTime1: function () {return Date.now();}},computed: {//   方案3:计算属性(注意区别于普通属性)//currentTime2 ,这是一个属性!不是方法currentTime2: function () {this.message;//  优点:此数据被改变后,计算属性会自动重新计算return Date.now();}}});//注意:methods和computed中的方法名可重名,重名后只会调用methods中的方法</script></body>
    </html>

十四 插槽slot:内容分发

  1. 思想路

    1. 正常情况下,我们会直接使用数据渲染整个页面。
    2. 特殊情况下,页面只会变某个部。此时可以在页面中留出两个口(这两个口就叫做插槽),方便在里面插入东西,而且是动态地可拔插,重点是复用性。如下图所示:
  2. 案例:比如准备制作一个待办事项组件(todo),该组件由待办标题(todo-title)和待办内容(todo-items)组成,但这三个组件又是相互独立的,该如何操作呢?
    1. 数据写死

      <!DOCTYPE html>
      <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说Java</title></head><body><div id="app"><!-- 第四步:使用插槽 --><todo><todo-title></todo-title><todo-items></todo-items></todo></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script type="text/javascript">//  第一步: 定义一个待办事项的组件Vue.component('todo_0', {template: '<div>\<div>待办事项</div>\<ul>\<li>学习狂神说Java</li>\</ul>\</div>'});//  第二步: 我们需要让待办事项的标题和值实现动态绑定,怎么做呢? 我们可以留出2个插槽(标题插槽、列表插槽)!//  1、将上面的代码留出2个插槽(标题插槽、列表插槽),即 slotVue.component('todo', {template: '<div>\<slot></slot>\<ul>\<slot></slot>\</ul>\</div>'});//  2、定义一个名为 todo-title 的待办标题组件 和 todo-items 的待办内容组Vue.component('todo-title', {template: '<div>标题</div>'});Vue.component('todo-items', {template: '<li>java lanaguage123</li>'});var vm = new Vue({el:'#app'});</script></body>
      </html>
    2. 使用自定义的数据

      <!DOCTYPE html>
      <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说Java</title></head><body><div id="app"><!-- 第四步:将这些值,通过插槽插入 --><todo><todo-title slot="todo-title" title="秦老师系列课程"></todo-title><todo-items slot="todo-items" v-for="(item, index) in todoItems"v-bind:item="item" v-bind:index="index"></todo></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script type="text/javascript">//  第一步: 定义一个待办事项的组件Vue.component('todo_0', {template: '<div>\<div>待办事项</div>\<ul>\<li>学习狂神说Java</li>\</ul>\</div>'});//  第二步: 我们需要让待办事项的标题和值实现动态绑定,怎么做呢? 我们可以留出2个插槽(标题插槽、列表插槽)!//  1、将上面的代码留出2个插槽(标题插槽、列表插槽),即 slotVue.component('todo', {template: '<div>\<slot name="todo-title"></slot>\<ul>\<slot name="todo-items"></slot>\</ul>\</div>'});//  2、定义一个名为 todo-title 的待办标题组件 和 todo-items 的待办内容组Vue.component('todo-title', {props: ['title'],                           //  接收传到组件的动态数据:title属性template: '<div>{{title}}</div>'            //  使用title属性});//这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!Vue.component('todo-items', {props: ['item', 'index'],                    //  接收传到组件中的动态:item、index属性template: '<li>{{index + 1}}. {{item}}</li>' //  使用item、index属性});//  3、实例化 Vue 并初始化数据var vm = new Vue({el:'#app',data: {todotitle:"学生选课",todoItems: ['狂神说Java1', '狂神说运维', '狂神说前端']}});</script></body>
      </html>

十五 自定义事件内容分发

  1. 业务:点击“删除”按钮,把li列表中的项目删除

    1. 方案1:缺点组件中无法调用vue实例中的方法,只能调用本组件中定义的方法:

      <!DOCTYPE html>
      <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说Java</title></head><body><div id="app"><todo><todo-title slot="todo-title" title="秦老师系列课程"></todo-title><todo-items slot="todo-items" v-for="item in todoItems"v-bind:item="item"></todo></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script type="text/javascript">Vue.component('todo_0', {template: '<div>\<div>待办事项</div>\<ul>\<li>学习狂神说Java</li>\</ul>\</div>'});Vue.component('todo', {template: '<div>\<slot name="todo-title"></slot>\<ul>\<slot name="todo-items"></slot>\</ul>\</div>'});Vue.component('todo-title', {props: ['title'],                           template: '<div>{{title}}</div>'            });Vue.component('todo-items', {props: ['item', 'index'],   //  调用成功  template: '<li>{{item}}<button @click="remove">删除</button></li>',  //  调用失败              //template: '<li>{{index + 1}}. {{item}}<button @click="removeItems">删除</button></li>', methods:{remove:function(){alert(111);}}});var vm = new Vue({el:'#app',data: {todotitle:"学生选课",todoItems: ['狂神说Java1', '狂神说运维', '狂神说前端']},methods:{// 该方法可以被模板中自定义事件触发removeTodoItems: function (index) {console.log("删除 " + this.todoItems[index] + " 成功");// splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目// 其中 index 为添加/删除项目的位置,1 表示删除的数量this.todoItems.splice(index, 1);}}});</script></body>
      </html>
    2. 方案2:理一下思路:
      <!DOCTYPE html>
      <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"xmlns:v-model.trim="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>狂神说Java</title></head><body><div id="app"><todo><todo-title slot="todo-title" title="秦老师系列课程"></todo-title><todo-items slot="todo-items" v-for="(item, index) in todoItems"v-bind:item="item" v-bind:index="index"                            v-on:remove="removeTodoItems(index)"><!-- v-on:用于绑定vm实例中的方法--> <!-- 自定义事件的名称:removeTodoItems。--><!-- 参数:(index)。 --></todo></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script><script type="text/javascript">Vue.component('todo_0', {template: '<div>\<div>待办事项</div>\<ul>\<li>学习狂神说Java</li>\</ul>\</div>'});Vue.component('todo', {template: '<div>\<slot name="todo-title"></slot>\<ul>\<slot name="todo-items"></slot>\</ul>\</div>'});Vue.component('todo-title', {props: ['title'],                           template: '<div>{{title}}</div>'            });Vue.component('todo-items', {props: ['item', 'index'],   template: '<li>{{index + 1}}. {{item}}<button @click="remove">删除</button></li>',  methods:{//  自定义事件内容分发。//  使用调用此方法时,实际上调用的是vm实例中的removeTodoItems方法。remove:function(index){// 这里的 remove 是自定义事件的名称,需要在 HTML 中使用 v-on:remove 的方式指派this.$emit('remove', index);}}});var vm = new Vue({el:'#app',data: {todotitle:"学生选课",todoItems: ['狂神说Java1', '狂神说运维', '狂神说前端']},methods:{// 该方法可以被模板中自定义事件触发removeTodoItems: function (index) {console.log("删除 " + this.todoItems[index] + " 成功");// splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目// 其中 index 为添加/删除项目的位置,1 表示删除的数量this.todoItems.splice(index, 1);}}});</script></body>
      </html>

十六 第一个vue-cli项目

  1. 脚手架定义

    1. 以前,我们在搭建一个项目的时候,项目开始前会用SSM做骨架。如果把SSM做的骨架抽出来,那它便成了一个脚手架。脚手架的作用是:基于脚本手(骨架),我们可以进行快速地进行开发。就好比咱们在idea中创建 Maven 项目时可以选择创建一个骨架项目(模板项目),这个骨架项目(模板项目)就是脚手架,使得我们的开发更加的快速;如下图所示:
  2. vue-cli定义
    1. vue官方提供的一个脚手架,用于快速生成一个 vue 的项目模板:

      1. 预先定义好的目录结构及基础代码:
        1. 统一的目录结构跟咱们的maven项目一样,.java类一定要写在/src/main/java这个目录下面。你的配置文件,一定是放在项目根目录的resources目录下面。
        2. 统一的基础代码跟maven一样,如maven会自动生成程序入口类。
        3. 本地调试:跟maven一样。
        4. 热部署:跟maven一样。
        5. 单元测试:跟maven一样。
        6. 集成打包上线:  跟maven一样。
  3. ​​​​​​npm与maven的区别与联系
    1. npm去下载那些安装的时候,npm干的就是maven干的事情呀,你可以把npm想象成maven的包管理模块。但npm跟maven也是有区别的:npm更偏向于linux系统的操作,如果以前使用linux的话,你会发现npm的很多操作命令和linux命令都差不多,包括在线安装一些东西呀等等。
  4. vue-cli环境搭建
    1. 第一步:安装Node.js(自带npm,可直接用npm了。自动帮我们配置环境变更,Add to Path。)
      1. node -v 
      2. npm -v
      3. 全局安装 npm install xxx的默认目录是:
    2. 第二步:安装Git(不是必须)
    3. 第三步:安装node.js淘宝镜像加速器(cnpm)。我们是不是听了好多次镜像加速器这个东西啦,那个maven是不是也是这样的。maven的中央仓库本来是在国外的,用了阿里巴巴的镜像加速器,就快很多,不然你从国外的maven中央仓库下载,那得多慢呀。同理,npm下载安装的东西,也是国外的仓库地址。如果你想加快一点速度,那只能用国内的cnpm,还是阿里的东西。但cnpm它有一些问题,有些用cnpm下载安装的包,放到项目里是能用,但在打包的时候可能就会发生各种莫名其妙的错误。所以能用npm就尽量用,实在不行再用cnpm
    4. 第四步:安装vue -cl
      1. # 测试是否安装成功
        # 查看可以基于哪些模板创建 vue 应用程序,通常我们选择 webpack
        vue list
        1. browserify
        2. browserify-simple
        3. pwa
        4. simple
        5. webpack:一般的vue项目,我们都会通过webpack来创建。因为vue是基于es6的开发,但真正网站使用时很多还是基于es5的,我们通过使用webpack把es6的语法降级(转换)成大多数浏览器都支持的es5语法。
        6. webpack-simple
  5. 创建运行,第1个vue-clie程序:相当于java程序中的helloworld
    1. 第一步:管理员模式下,cmd命令输入框
    2. 第二步:cd进入到某个目录
    3. 第三步:执行命令vue init webpack myvue ,即初始化一个webpack的vue项目,效果是在该目录下自动生成一个vue - webpack项目(名字叫myvue):
    4. 第四步:cd myvue
    5. 第五步:npm install:在当前目录下,安装此webpack模板的vue项目的所有依赖环境。npm install安装哪些呢?它根据的是配置文件pack.json中要求的进行安装的。安装的目录是,项目根目录下的node_modules目录:
    6. 第六步:等待npm install加载安装完成,说明这个项目初始化完毕了,初始化完毕就可以直接运行了。但这只是一个基础的前端工程,就相当于java的helloword。
      1. 修复:npm audit fix(run 'npm audit fix' to fix them,or 'npm audit' for details)
    7. 第七步:npm run dev。用于启动并运行此项目,相当于我们使用命令启动tomcat并开启8080端口那样。
      1. 第1步:告诉我们,自动编译整个项目,编译之后才能打包,即 xx building modules xxx
      2. 第2步:告诉我们,自动打包整个项目,打包之后才能启动并运行, webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
      3. 第3步:告诉我们,编译并打包完成,DONE  Compiled successfully in 3221ms
      4. 第4步:告诉我们,访问的路径:Your application is running here: http://localhost:8080
    8. 第八步:访问此前端项目:Your application is running here: http://localhost:8080,前端项目的首页是vuejs的标识,而tomcat项目的首页是一个猫。
    9. 第九步:停止项目:ctrl + c   Y,相当于tomcat的shutdown
  6. 项目详解,第1个vue-clie程序
    1. 第一步:使用vs code打开项目(文件夹),因为它是一个前端项目
    2. 第二步:查看项目的结构
      1. build目录:构建

        1. build.js ---- 这个地方就是一些构建的一些信息,最终我们会用npm命令执行它是吧。
        2. check-version.js ---- 检查所有东西的版本,如检查npm、node.js版本。
        3. webpack.base.conf.js ---- webpack基本配置。webpack是不是就是咱们打包相关的,我们运行(npm run dev)之前,就是使用它来打包的。
        4. webpack.dev.conf.js ----- webpack开发环境配置
        5. webpack.prod.conf.js ---- webpack生产环境配置
      2. config目录:配置目录,包括端口号等。我们初学可以使用默认的。
        1. dev.env.js:开发环境变量
        2. prod.env.js:生产环境变量
        3. index.js:配置变量
      3. node_modules目录:包含我们使用npm install下载安装的东西,即这个程序运行起来需要的所有组件。相当于咱们java里面的lib目录,只是这里下载的不是.jar包,而是一些依赖。
      4. src目录:放源码的地方
        1. assets​:资源文件,比如存放 css,图片等资源。
        2. component​:组件文件夹,用来存放 vue 的公共组件(注册于全局,在整个项目中通过关键词便可直接输出)。
        3. app.vue​:是项目的主组件,所有页面都是在该组件下进行切换的。
        4. main.js:入口文件(入口程序)。是项目的入口文件,作用是初始化 vue 实例,并引入所需要的插件。
      5. static目录:静态资源目录,如图片、字体等。
      6. index.html:项目的首页入口文件,你可以添加一些 meta 信息或统计代码啥的。
      7. package.json:node配置文件,记载着一些命令、依赖及其版本、简要的项目描述信息
        1. 比如,npm run dev命令
    3. 附1:package.json详解
      {// 项目/模块名称,长度必须小于等于 214 个字符,不能以"."(点)或者"_"(下划线)开头,不能包含大写字母"name": "myvue",// 项目版本"version": "1.0.0",// 项目描述"description": "project",// 作者"author": "Demo_Null",// 是否私有,设置为 true 时,npm 拒绝发布"private": true,// 执行 npm 脚本命令简写,执行前面的简写就代表执行后面的命令"scripts": {"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js","start": "npm run dev","unit": "jest --config test/unit/jest.conf.js --coverage","e2e": "node test/e2e/runner.js","test": "npm run unit && npm run e2e","lint": "eslint --ext .js,.vue src test/unit test/e2e/specs","build": "node build/build.js"},// 生产环境下,项目运行所需依赖"dependencies": {"vue": "^2.5.2","vue-router": "^3.0.1"},// 开发环境下,项目所需依赖"devDependencies": {"autoprefixer": "^7.1.2","babel-core": "^6.22.1","babel-eslint": "^8.2.1","babel-helper-vue-jsx-merge-props": "^2.0.3","babel-jest": "^21.0.2","babel-loader": "^7.1.1","vue-style-loader": "^3.0.1","vue-template-compiler": "^2.5.2","webpack": "^3.6.0","webpack-bundle-analyzer": "^2.9.0","webpack-dev-server": "^2.9.1","webpack-merge": "^4.1.0"},// 项目运行的平台"engines": {"node": ">= 6.0.0","npm": ">= 3.0.0"},// 供浏览器使用的版本列表"browserslist": ["> 1%","last 2 versions","not ie <= 8"]
      }
    4. 附2:index.js 详解
      'use strict'                                              //---严格的语法const path = require('path')                              //---node.js路径模块module.exports = {dev: {// PathsassetsSubDirectory: 'static',                         //---配置静态目录的地方。相当于tomcat目录中的web-info目录。assetsPublicPath: '/',proxyTable: {},// Various Dev Server settingshost: 'localhost', // can be overwritten by process.env.HOSTport: 8080,                                           //---配置端口号 autoOpenBrowser: false,//项目运行时是否自动打开浏览器errorOverlay: true,// 浏览器错误提示notifyOnErrors: true,// 跨平台错误提示poll: false, // 使用文件系统获取文件改动的通知devServer.watchOptions https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-// Use Eslint Loader?// If true, your code will be linted during bundling and// linting errors and warnings will be shown in the console.useEslint: false,// If true, eslint errors and warnings will also be shown in the error overlay// in the browser.showEslintErrorsInOverlay: false,/*** Source Maps*/// https://webpack.js.org/configuration/devtool/#developmentdevtool: 'cheap-module-eval-source-map', // 增加调试,该属性为原始源代码// If you have problems debugging vue-files in devtools,// set this to false - it *may* help// https://vue-loader.vuejs.org/en/options.html#cachebustingcacheBusting: true, // 使缓存失效cssSourceMap: true // 代码压缩后bug定位将非常困难,引入SourceMap记录压缩前后的位置信息记录,当产生错误时直接定位到压缩前的位置},//生产环境build: {// Template for index.htmlindex: path.resolve(__dirname, '../dist/index.html'),// 编译输入的index.html文件// PathsassetsRoot: path.resolve(__dirname, '../dist'),// 编译输出的静态资源路径(项目打包时的文件)assetsSubDirectory: 'static',// 编译输出的二级目录assetsPublicPath: '/',// 编译发布的根目录,可配置为资源服务器域名或CDN域名/*** Source Maps*/productionSourceMap: true, // 是否开启cssSourceMap// https://webpack.js.org/configuration/devtool/#productiondevtool: '#source-map', // 增加调试,该属性为原始源代码// Gzip off by default as many popular static hosts such as// Surge or Netlify already gzip all static assets for you.// Before setting to `true`, make sure to:// npm install --save-dev compression-webpack-pluginproductionGzip: false,// 是否开启gzipproductionGzipExtensions: ['js', 'css'], // 需要使用gzip压缩文件的扩展名// Run the build command with an extra argument to// View the bundle analyzer report after build finishes:// `npm run build --report`// Set to `true` or `false` to always turn it on or offbundleAnalyzerReport: process.env.npm_config_report  // 打包分析}
      }
      //原文链接:https://blog.csdn.net/yhj198927/article/details/124044693
    5. 附3:build.js 详解
      'use strict'                                            //---严格模式
      require('./check-versions')()                           //---npm和node版本检查并立即执行,请看我的check-versions配置文件解释文章process.env.NODE_ENV = 'production'                     //---process是node中的global全局对象的属性,process是node中的全局变量,env设置环境变量。此设置环境为生产环境productionconst ora = require('ora')                              //---ora是一个命令行转圈圈动画插件,好看用的
      const rm = require('rimraf')                            //---rimraf插件是用来执行UNIX命令rm和-rf的用来删除文件夹和文件,清空旧的文件
      const path = require('path')                            //---node.js路径模块
      const chalk = require('chalk')                          //---chalk插件,用来在命令行中输入不同颜色的文字
      const webpack = require('webpack')                      //---引入webpack模块使用内置插件和webpack方法
      const config = require('../config')                     //---引入config下的index.js配置文件,此配置文件我之前介绍了请自行查阅,主要配置的是一些通用的选项
      const webpackConfig = require('./webpack.prod.conf')    //---下面是生产模式的webpack配置文件,请看我的webpack.prod.conf解释文章const spinner = ora('building for production...')       //---开启转圈圈动画
      spinner.start()                                         //---开始执行加载动画//---调用rm方法,第一个参数的结果就是 dist/static,表示删除这个路径下面的所有文件
      rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {if (err) throw err                                   //---如果删除的过程中出现错误,就抛出这个错误,同时程序终止webpack(webpackConfig, (err, stats) => {             //---没有错误,就执行webpack编译//---这个回调函数是webpack编译过程中执行spinner.stop()                                     //---停止转圈圈动画if (err) throw err                                 //---如果有错误就抛出错误process.stdout.write(stats.toString({              //---没有错误就执行下面的代码,process.stdout.write和console.log类似,输出对象//---stats对象中保存着编译过程中的各种消息colors: true,                                    //---增加控制台颜色开关modules: false,                                  //---不增加内置模块信息children: false,                                 //---不增加子级信息chunks: false,                                   //---允许较少的输出chunkModules: false                              //---不将内置模块的信息加到包信息}) + '\n\n')if (stats.hasErrors()) {console.log(chalk.red('  Build failed with errors.\n'))process.exit(1)}//---以上就是在编译过程中,持续打印消息//---下面是编译成功的消息console.log(chalk.cyan('  Build complete.\n'))console.log(chalk.yellow('  Tip: built files are meant to be served over an HTTP server.\n' +'  Opening index.html over file:// won\'t work.\n'))})
      })
      // end
      // 注: 如果你想自己编写一个高质量的脚手架工具,建议你:
      // 去补习nodejs,然后补习 es6,然后再来看webpack官方文档,然后自己独立编写一个和vue-cli类似的脚手架,如果上面的东西看不懂,更要这样做
      // vue-cli还有一部分内容是关于代码测试的,可以说这块内容的复杂度不亚于webpack,这些内容对nodejs要求比较熟悉,说白了就是基础弱的很难入门,但是测试这块内容也是非常有价值的,可以借助无界面的浏览器解析引擎,通过一句命令就可以把你的代码在不同的平台上运行,还能指出问题所在,所以,我会渐渐的转战nodejs去了,后续的文章将很多是关于nodejs的文章,如果感兴趣的可以关注我的文章,一起学习探讨
      //原文链接:https://blog.csdn.net/song854601134/article/details/120598334
    6. 附4:webpack.base.conf.js 详解,我们maven里面build result是不是也干这个事情,build result可以过滤xml让xml出去呀。也就是说此文件所配置的东西就是跟打包相关的信息,是不是跟maven特别像呀。
      'use strict'
      const path = require('path')                          //---引入nodejs路径模块
      const utils = require('./utils')                      //---引入utils工具模块,具体查看我的博客关于utils的解释,utils主要用来处理css-loader和vue-style-loader的
      const config = require('../config')                   //---引入config目录下的index.js配置文件,主要用来定义一些开发和生产环境的属性
      const vueLoaderConfig = require('./vue-loader.conf')  //---vue-loader.conf配置文件是用来解决各种css文件的,定义了诸如css,less,sass之类的和样式有关的loaderfunction resolve (dir) {                              //---此函数是用来返回当前目录的平行目录的路径,因为有个'..'return path.join(__dirname, '..', dir)
      }module.exports = {context: path.resolve(__dirname, '../'),entry: {app: './src/main.js'                              //---入口文件是src目录下的main.js},output: {path: config.build.assetsRoot,                    //---输出路径是config目录下的index.js中的build配置中的assetsRoot,也就是dist目录filename: '[name].js',                            //---项目输出文件名称,这里使用默认的name也就是main。publicPath: process.env.NODE_ENV === 'production' //---上线地址,也就是真正的文件引用路径,如果是production生产环境,其实这里都是 '/'? config.build.assetsPublicPath: config.dev.assetsPublicPath},resolve: {// resolve是webpack的内置选项,顾名思义,决定要做的事情,也就是说当使用 import "jquery",该如何去执行这件事// 情就是resolve配置项要做的,import jQuery from "./additional/dist/js/jquery" 这样会很麻烦,可以起个别名简化操作extensions: ['.js', '.vue', '.json'], // 省略扩展名,也就是说.js,.vue,.json文件导入可以省略后缀名,这会覆盖默认的配置,所以要省略扩展名在这里一定要写上alias: {//后面的$符号指精确匹配,也就是说只能使用 import vuejs from "vue" 这样的方式导入vue.esm.js文件,不能在后面跟上 vue/vue.js'vue$': 'vue/dist/vue.esm.js',// resolve('src') 其实在这里就是项目根目录中的src目录,使用 import somejs from "@/some.js" 就可以导入指定文件,是不是很高大上'@': resolve('src')}},//  以下是一些静态资源过滤规则,通过条件进行过滤//  module用来解析不同的模块module: {rules: [{test: /\.(js|vue)$/,// 也就是说,对.js和.vue文件在编译之前进行检测,检查有没有语法错误loader: 'eslint-loader',// 此选项指定enforce: 'pre'选项可以确保,eslint插件能够在编译之前检测,如果不添加此项,就要把这个配置项放到末尾,确保第一个执行enforce: 'pre',// include选项指明这些目录下的文件要被eslint-loader检测,还有一个exclude表示排除某些文件夹include: [resolve('src'), resolve('test')],// options表示传递给eslint-loader的参数options: {// formatter是参数的名称,eslint-friendly-formatter是eslint的一个报告总结插件,也就是说eslint的检测报告非常难看懂,这个插件就是整理这些报告方便查阅的formatter: require('eslint-friendly-formatter')}},{test: /\.vue$/,// 对vue文件使用vue-loader,该loader是vue单文件组件的实现核心,专门用来解析.vue文件的loader: 'vue-loader',// 将vueLoaderConfig当做参数传递给vue-loader,就可以解析文件中的css相关文件options: vueLoaderConfig},{test: /\.js$/,// 对js文件使用babel-loader转码,该插件是用来解析es6等代码loader: 'babel-loader',// 指明src和test目录下的js文件要使用该loaderinclude: [resolve('src'), resolve('test')]},{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,// 对图片相关的文件使用 url-loader 插件,这个插件的作用是将一个足够小的文件生成一个64位的DataURL// 可能有些老铁还不知道 DataURL 是啥,当一个图片足够小,为了避免单独请求可以把图片的二进制代码变成64位的// DataURL,使用src加载,也就是把图片当成一串代码,避免请求,神不神奇??loader: 'url-loader',options: {// 限制 10000 个字节一下的图片才使用DataURLlimit: 10000,// 下面这个应该是指将[name].[hash:7].[ext]对应的图片使用url-loader测试吧,这个我是真不知道干啥的,如果知道// 的兄弟,一定要留言给我啊,拜谢name: utils.assetsPath('img/[name].[hash:7].[ext]') // 这个函数执行结果是 /img/[name].[hash:7].[ext]// 不知道吧 name 设置成 /img/[name].[hash:7].[ext] 意欲何为,猜测应该是输出图片的路径或者是解析图片的路径}},{test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,// 字体文件处理,和上面一样loader: 'url-loader',options: {limit: 10000,name: utils.assetsPath('fonts/[name].[hash:7].[ext]')}}]}
      //原文链接:https://blog.csdn.net/song854601134/article/details/120598344?spm=1001.2014.3001.5502
    7. 附5:vue项目结构是怎么样的?详解vue目录结构! (w3cschool.cn)

十七 webpack学习使用(vuejs中的写法,就是这里的模块化处理)

  1. 业务

    1. 伴随着移动互联网的大潮,当今越来越多的网站已经从网页模式进化到了WebApp模式。也就是说,已经把网站当做一个单独的应用,并运行在浏览器里面
    2. javascript模块化的演进
      1. 第1阶段:<script>标签

        1. 如<script src="module1.js"><script>。这是最原始的javascript文件加载方式,它把每一个文件都看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在window对象中,不同模块的调用都是一个作用域。缺陷明显,所以需要一些规范。
      2. 第2阶段:CommonsJS —— export & inport & require —— 同步阻塞加载
        1. 服务器端的NodeJS遵循CommonsJS规范,该规范核心思想是允许模块通过require方法来同步加载所需依赖的其它模块,然后通过exports或module.export1来导出需要暴露的接口。有优点,也有缺点。

          1. 优点:
               ●服务器端模块便于重用
               ●NPM中已经有超过45万个可以使用的模块包
               ●简单易用
          2. 缺点:
            ●同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的。更理想的方式是,异步非阻塞的模块加载方式。
            ●不能非阻塞的并行加载多个模块
      3. 第3阶段:AMD —— define & require —— 异步非阻塞加载
      4. 第4阶段:CMD —— defind & export —— 模块的加载逻辑偏重
      5. 第5阶段:ES6模块 —— inport(导入) & export(暴露) & module(模块) —— 编译时错误检查
        1. ES6规范大家知道,现在的javascript基本上都是面对ES6规范在做的。但是浏览器不在ES5规范。        
             EcmaScript6标准增加了JavaScript语言层面的模块体系定义。ES6模块的设计思想是尽量静态化,使编译时就能确定模块的依赖关系,以及输入和输出的变量,增加编译检查与异常抛出(解决变量冲突),增加运行时异常(提供更多的错误信息)。CommonsJS和AMD模块,都只能在运行时确定这些东西,编译时啥都没做。
      6. 大家期望的模块化
        1. 可以兼容多种模块风格,尽量可以利用已有的代码,不仅仅只是JavaScript模块化,还有CSS、图片、字体等资源也需要模块化。
      7. webpack模块化处理
        1. webpack是一款模块加载器兼打包工具,它能把各种资源,如JS、JSX、ES6、SASS、LESS、图片等都作为模块来处理和使用。
  2. 需求
    1. 为了支持较低版本的浏览器,es6 转 es5。
    2. 依赖管理
  3. 流原
    1. webpack依赖管理功能原理

      1. 同maven depandence。
    2. webpack编译打包原理
      1. 前端的一键打包:当webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph,package.json中的依赖),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。“依赖关系图”这个像啥?是不是像我们的maven呀。父子依赖,对不对,一个父项目里面有子项目,子项目中依赖(dependence)了很多很多的东西。
      2. 同理 —— maven的一键打包命令:maven package命令一键生成jar 或 war包,不用我们手动在命令行一步一步去做了。
  4. 分类
    1. webpack在vue项目中的使用方式

      1. 自动化构建(编译打包)

        1. 在vue项目中有一个build目录,build目录下有一个webpack.base.conf.js文件,就是通过此文件对webpack的设置进行自动化构建(编译打包)。那么我们来看一下,怎么手动去做这件事情。。。。。。
      2. 手动构建(编译打包)
  5. 环境搭建
    1. 第一步:安装webpack

      1. npm install webpack -g,打包工具,全局的在哪个目录下安装都行,如果安装失败就改用cnpm去安装
      2. npm install webpack-cli -g,客户端,全局的在哪个目录下安装都行,如果安装失败就改用cnpm去安装
    2. 第二步:测试安装成功
      1. webpack -v
      2. webpack-cli -v
    3. 第三步:webpack版本调整
      1. 咱们来看pack.json里面,里面写了1个webpack版本。我们安装的webpack肯定是最新版本的webpack吧,而pack.json中写的版本往往不是最新的。因为版本不一致,所以在使用webpack进行打包时,可能会有一些东西打包不进去。这时,我们可能需要在pack.json中,调一调一某些依赖的版本,升一升版本,或者降一降版本。
    4. 第四步:配置webpack —— 创建webpack.config.js配置文件
      1. 了解:这些东西咱们不管,理解一下就好了

        1. entry,入口文件,指定WebPack用哪个文件作为项目的入口 —— 就只有一个,即我们的main.js。
        2. output,输出,指定WebPack把处理完成的文件放置到指定路径 —— 就是我们使用webpack打包完成后,会自动生成(输出)一个文件,你要把这个文件放到哪个位置。
        3. module,模块,用于处理各种类型的文件 —— 我们打包是不是要把一些模块打进去呀,我们的java程序也是这样的,生成.jar包的时候需要把它此java项目所有的依赖都安上去再打包。
        4. plugins,插件,如:热更新、代码重用等 —— plugins是一些插件,你要是放插件,它也可以实现啊。
        5. resolve,设置路径指向 ——
        6. watch,监听,用于设置文件改动后直接打包 —— 
  6. webpack的使用
    1. 狂神文档参考:
    2. 自己的详细操作步骤
      1. 第一步:在某个目录下创建一个文件夹webpack-study
      2. 第二步:使用vs code工具打开它webpack-study
      3. 第三步:vs code操作
        1. 第1步:创建 —— 一个名为modules的目录,用于放置JS模块等资源文件。
        2. 第2步:暴露 —— 在modules目录下创建模块文件,如hello.js, 用于编写JS模块相关代码。
          //  哈哈 这个地方是给你补es6的语法啊//  第一步:exports,暴露一个方法(此方法执行完,会在前端生成一个h1标签,文字加粗)
          exports.sayHi = function(){document.write("<h1>狂神的es666</h1>")
          }
          exports.sayHi1 = function(){document.write("<h1>狂神的es6661</h1>")
          }
          exports.sayHi2 = function(){document.write("<h1>狂神的es6662</h1>")
          }
          exports.sayHi3 = function(){document.write("<h1>狂神的es6663</h1>")
          }
        3. 第3步:引入(使用)—— 在modules目录下创建一个名为main.js的入口文件,用于打包时设置entry属性
          // 第一步:require,引入/使用/加载(一个包)。这里的模块名是hello,不用在后面加.js。就像java中import类时,不会有.java结尾。
          var hello = require("./hello");
          // 第二步:调用方法
          hello.sayHi();
          hello.sayHi1();
          hello.sayHi2();
          hello.sayHi3();
        4. 第4步:打包编码与设置 —— 在项目目录下创建webpack.config.js配置文件,使用webpack命令打包
          //  前端一直在抄袭我们 模仿我们
          //  module.exports把这些模块(main.js、hello.js)编译》导出》打包
          module.exports = {entry:"./modules/main.js",     // 程序入口main.js。相当于java springboot程序的Application.java(入口程序)的那个main()方法output:{filename:"./js/bundle.js"  // 输出到js目录(自动生成)下的bundle.js(自动生成)}
          }
        5. 第5步:打包操作完成 —— vscode终端中输入打包命令"webpack":
          1. bundle.js:经过编译(es6 》es5)、打包、压缩。
        6. 第6步:使用index.html —— 我们编写的代码(hello.js、main.js)经过打包出来能用了(bundle.js),我们在index.html中使用一下:
          <!DOCTYPE html>
          <html><head><meta charset="UTF-8"><title>狂神说Java</title><!-- 导入编译、打包完成的bundle.js,并使用 --></head><body><!-- 这就是前端的模块化开发 --><script src="dist/js/bundle.js"></script></body>
          </html>

十八 vue-router路由(转发)

  1. 业务

    1. 在讲完webpack(exports、require)以后,大家就能够看懂vue的工程了。
    2. vue遵循的是soc原则,vue本身只关注视图层,而vue工程中路由(即多个页面跳转,即以后我们后端中的重定向、转发的事情将由前端来做)的功能是使用vue-router路由组件(vue自带的)来实现的。
  2. 需求:多个页面之间的跳转(后端的重定向、转发事情将由前端来做)
  3. 思想路
    1. Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。这句话的意思是,我们可以直接使用vue-router,直接import即可。
    2. 包含的功能有:
      1. 嵌套的路由/视图表 —— 也就是说,从vue的角度来看,一个页面是很多很多的组件 + 很多插槽组成(相当于html时期,一个一个div的嵌套)的。不同的页面中,只有一部分的组件的内容是变化的,此时我们可以把这一部分的组件路由到另一个组件,用另一个组件来代替它,再完成内容的渲染就行了。
      2. 模块化的、基于组件的路由配置 —— 
      3. 路由参数、查询、通配符 —— 
      4. 基于 Vue.js 过渡系统的视图过渡效果 —— 
      5. 细粒度的导航控制 —— 
      6. 带有自动激活的 CSS class 的链接 —— 
      7. HTML5 历史模式或 hash 模式,在 IE9 中自动降级 —— 
      8. 自定义的滚动条行为 —— 
  4. 环境搭建  & 依赖(如axios、vue-router)的安装、导入、使用
    1. 第一步:新建vue工程(把src目录下多余的东西都删除掉),整理后得到的基础工程:

      // main.jsimport Vue from 'vue'            //  从vue那个组件里面,给它导过来
      import App from './App'          //  导入app组件Vue.config.productionTip = falsenew Vue({el: '#app',components: { App },template: '<App/>'
      })
      
      // app.vue<template><div id="app"></div>
      </template><script>export default {name: 'App',components: {}
      }
      </script><style>
      #app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
      }
      </style>
      
    2. 第二步:安装 —— vue-router(安装的原理,即把模块放到node_modules目录下。这相当于在java的项目中,把第三方的jar包放到lib目录下一样

      1. 第1步:管理员运行cmd

      2. 第2步:cd到此项目根目录下

      3. 第3步:执行npm install vue-router --save-dev命令

      4. 报错:peer vue@"^3.2.0" from vue-router@4.1.2

    3. 第三步:详解 —— 安装后的vue-router,在“node_modules”目录下找,如下图所示:

      1. 从目录结构可以看出vue-router是一个标准的前端工程。

    4. 第四步:导入 —— 安装完成后,如果需要在App.vue中使用vue-router组件,那么就直接使用import关键字导入即可(相当于java中用import导入某个类),如下图所示: 

    5. 第五步:显示声明使用 —— 上面只是把vue-router导入进来,但vue中需要显示地声明。

      //  main.jsimport Vue from 'vue'               //  从vue那个组件里面,给它导过来
      import App from './App'             //  导入app组件
      import VueRouter from 'vue-router'  //  从安装的vue-router模块中导进来//  from 'vue-router'是导入进来前的名字//  import VueRouter是导入进来后使用的qkpbVue.config.productionTip = false//  显示地声明使用vue-router,使用的名字是导入进来后的名字
      Vue.use(VueRouter);new Vue({el: '#app',components: { App },template: '<App/>'
      })

  5. 自定义组件的编写、导出、导入、使用(演示使用的项目的项目结构如下图)
    1. 第一步:编写&导出:在components目录下存放我们自己编写的组件Content.vue:

      <!-- 组件的组成部分 -->
      <!-- 第一部分:页面 -->
      <template><div><h1>内容页</h1></div>
      </template><!-- 第二部分:一般是vue对象的一些东西,一般使用export进行导出 -->
      <script>export default {name: "Content"}
      </script><!-- 第三部分:页面样式 -->
      <style></style>
    2. 第二步:导入&使用:在App.vue中使用:
      <template><div id="app"></div>
      </template><script>
      //  第一步:先导入
      import Content from "./components/Content.vue"
      export default {name: 'App',components: {//  第二步:再使用Content}
      }
      </script><style>
      #app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
      }
      </style>
      
  6. 使用vue-router实现路由(重定向、转发)
    1. 第一步:编写&导出:在components目录下存放我们自己编写的组件Main.vue  和 Content.vue :

      <template><div><h1>首页</h1></div>
      </template>
      <script>export default {name: "Main"}
      </script>
      <style></style>
      <!-- 组件的组成部分 -->
      <!-- 第一部分:页面 -->
      <template><div><h1>内容页</h1></div>
      </template><!-- 第二部分:一般是vue对象的一些东西,一般使用export进行导出 -->
      <script>export default {name: "Content"}
      </script><!-- 第三部分:页面样式 -->
      <style></style>
    2. 第二步:在src目录下创建一个router文件夹,专门用于放在关于路由的东西
    3. 第三步:配置路由 —— 在router文件夹下面,创建路由的主配置文件index.js,专门用于编写路由规则:
      // 导入vue
      import Vue from 'vue'
      // 导入路由插件
      import Router from 'vue-router'
      // 导入上面定义的组件
      import Content from '../components/Content'
      import Main from '../components/Main'
      // 显示声明使用路由
      Vue.use(Router);// 导出新配置的路由
      export default new Router({routes: [{// 路由路径,即只要你在浏览器地址栏输入的路径是“/content”,表明就要使用些路由。// 使用哪个路由 & 跳转到哪个组件,由name和component属性决定path: '/content',// 路由名称name: 'content',// 跳转到哪个组件component: Content},{//如何配置两个路由(假如  首页)path: '/main',name: 'main',component: Main}]
      });

      从上面的代码可以看出,vue-router相当于我们java的什么呀?相当于我们springmvc项目controller类中的@RquestMapping注解,RquestMapping本身的作用就是接收前端的一个请求,并指定要方法处理的一些数据,最后要求方法跳转到另一个页面。vue-router其实也是干这么一个事情。

    4. 第四步:起用路由 —— 在前端工程的入口程序main.js中配置:

      import Vue from 'vue'
      import App from './App'
      // 第一步:导入上面创建的路由主配置文件所在的目录,并且取名为“router”
      import router from './router'
      Vue.config.productionTip = false
      new Vue({el: '#app',// 第二步:使用(配置的)路由(表),vue会自动扫描里面的路由配置router,components: { App },template: '<App/>'
      })
      
    5. 第五步:演示路由功能 —— 在 App.vue 中使用路由:

      <template><div id="app"><!--router-link: 默认会被渲染成一个 <a> 标签,to 属性为指定链接router-view: 用于渲染路由匹配到的组件--><router-link to="/main">首页</router-link><router-link to="/content">内容</router-link><router-view></router-view></div>
      </template><script>
      export default {name: 'App'
      }
      </script><style>
      </style>
      
    6. 第六步:验证

      1. 第1步:npm run dev 访问

      2. 第2步:点击可以跳转

十九 vue + elementui

  1. 业务

    1. vue前端工程现在没有自己好看的页面,我们可以使用vue+elementui构建比较好看的页面。
  2. 需求:网站快速成型工具
  3. 解决方案:
    1. vue + elementui
    2. 推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
  4. element-ui官网解读:组件 | Element
    1. element-ui的这些组件用起来和bootstrap的组件是一样的。
    2. 建议学习“element-ui(组件化开发,桌面化应用) + layui(弹窗)”用于代替“bootstrap(样式化开发,桌面化应用) + layui(弹窗)”。
  5. hellowor:vue + elementui
    1. 第一步:环境搭建 & 初始化项目

      1. 第一次创建项目

        1. 第1步:npm install vue-cli -g,全局安装vue脚手架
      2. 第二次创建项目
        1. 第1步:cmd管理员
        2. 第2步:cd来到工作空间
        3. 第3步:vue init webpack hello-vue,初始化一个webpack项目,项目名称是hello-vue:
    2. 第二步:安装各种插件和组件
      1. 第1步:准备

        1. 进入工程目录(cmd 管理员身份):cd hello-vue
      2. 第2步:安装vue-router
        1. npm install vue-router --save-dev
        2. peer vue@"^3.2.0" from vue-router@4.1.6  》npm i vue-router@3
      3. 第3步:安装element-ui 
        1. npm i element-ui -s
      4. 第4步:安装所有的依赖
        1. npm install
      5. 第5步:安装SASS加载器
        1. cnpm方式

          1. cnpm install sass-loader node-sass --save-dev

            1. 这句命令安装了两个,一个是sass-loader,另一个是node-sass。
            2. 你们可以拆成两名命令,也可以合成一句命令,也就是说你要安装多个组件可以一句命令安装完。
            3. 这里使用cnpm的时候,是因为老师使用npm安装时失败了。淘宝的镜像再怎么着都比国外(npm)的快。
          2. 业务/需求:我们之前聊过,前端的一些东西不能用纯css来写,是不是它就用SASS呀,你要通过SASS去编辑生成啊。就是css嘛,使用SASS编辑生成css。
          3. Error: Cannot find module ‘diagnostics_channel,cnpm的版本过高 》npm uninstall -g cnpm 》npm install cnpm@7.1.0 -g 》cnpm install sass-loader node-sass --save-dev
        2. npm方式
          1. peer webpack@"^5.0.0" from sass-loader@13.2.0 》npm i sass-loader@7
          2. node-sass pip 安装报错,提示缺少python2 (shuzhiduo.com) 》npm install node-sass@6
      6. 第6步:测试
        1. npm run dev
    3. 第三步:编号开发
      1. 第1步:整理项目

        1. 第(1)步:使用vs code打开项目
        2. 第(2)步:删除src下默认的文件:assets/logo.png(默认的图片)、components/HelloWorld.vue(默认的组件)
        3. 第(3)步:整理src/App.vue
          <template><div id="app"></div>
          </template><script>
          export default {name: 'App',
          }
          </script><style>
          #app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
          }
          </style>
          
        4. 第(4)步:静态资源文件放在static吧,放在其它地方不可见啊
        5. 第(5)步:新建src/router目录,用于放路由
        6. 第(6)步:新建src/views目录,用于放置视图,也可以叫视图组件(视图也是组件的一部分,但分得细一点,视图一般用于交互的)。这里的views目录用于存放视图组件,而components目录用于存放功能性组件,这样分工是不是就更加明确了。
      2. 第3步:编码
        1. 第(1)步:在views目录下创建Main.vue视图

          <template><h1>首页</h1>
          </template><script>
          export default {name: 'Main',
          }
          </script><style>
          </style>
        2. 第(2)步:在views目录下创建Login.vue视图(直接去ElementUI官网中拿的,不是我自己写的)。
          ​
          <template><div><!-- el开头的就是element的组件(这里是表单) --><el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box"><h3 class="login-title">欢迎登录</h3><el-form-item label="账号" prop="username"><el-input type="text" placeholder="请输入账号" v-model="form.username"/></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" placeholder="请输入密码" v-model="form.password"/></el-form-item><el-form-item><!--登录按钮,绑定了click事件,调用onSubmit方法--><el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button></el-form-item></el-form><!--这里是一个提示框,即如果我们输入错误,就会弹窗--><el-dialogtitle="温馨提示":visible.sync="dialogVisible"width="30%":before-close="handleClose"><span>请输入账号和密码</span><span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
          </span></el-dialog></div>
          </template><script>export default {name: 'Login',data(){return{form:{username:'',password:''},//  表彰验证,需要在el-form-item元素中增加prop属性rules:{username:[{required:true,message:'账号不可为空',trigger:'blur'}],password:[{required:true,message:'密码不可为空',trigger:'blur'}]},//  对话框显示和隐藏dialogVisible:false}},methods:{onSubmit(formName) {//   为表单绑定验证功能this.$refs[formName].validate((valid) => {if(valid){//  使用vue-router路由到指定页面,该方式称之为编程式导航this.$router.push("/main");}else{this.dialogVisible = true;return false;}})}}}
          </script><style scoped>.login-box{border: 1px solid #DCDFE6;width: 350px;margin: 108px auto;padding: 35px 35px 15px 35px;border-radius: 5px;-webkit-border-radius:5px;-moz-border-radius:5px;box-shadow: 0 0 25px #909339;}.login-title{text-align: center;margin: 0 auto 40px auto;color: #303133;}
          </style>​
        3. 第(3)步:路由index.js(那这个登录表单想要用怎么办?是不是要配置到路由里面去呀。组件写完它是独立的吧,独立的东西就要通过路由把它们交互起来)。

          //第一步:引入(导入)
          import Vue from 'vue'
          import Router from 'vue-router'   //  其中名称Router可以随便取,只要后面的vue-router对即可
          import Main from '../views/Main'  //  导入Main组件
          import Login from '../views/Login'//  导入Login组件//第二步:显示地使用它
          Vue.use(Router)//第三步:导出一个接口
          export default new Router({routes:[//  放置(配置)各种各样的路由{path:'/main',//    请求链接component:Main// 路由(转发)到此组件},{path:'/login',//    请求链接component:Login// 路由(转发)到此组件}]
          });
        4. 第(4)步:main.js。路由配置到哪里去?配置到main.js里面去吧。

          import Vue from 'vue'
          import App from './App'
          //第一步:要想使用路由,那就让路由去扫描相应的包(router目录)吧,这样子的话它就会把所有配置好的路由给加载进来
          import router from './router'
          //第二步:elementui还没导入,我们是不是要把它导入进来呀。名字'element-ui'去哪里找呀?是不是去node_modules里面找呀
          import Element from 'element-ui'
          //第三步:导入elementui对应的css。官网案例拷贝。
          //说明它导入了一个css吧,是不是就需要SASS编辑器吧,这就是我们刚才导入SASS的原因。
          import 'element-ui/lib/theme-chalk/index.css';//第四步:安装路由(显示地使用路由)
          Vue.use(router);
          //第五步:安装ElementUI(显示地使用ElementUI)
          Vue.use(ElementUI);//第六步:配置Router和ElementUI
          new Vue({el: '#app',router,//  配置router。render: h => h(App)//  配置ElementUI。官网拷贝。
          })
          
        5. 第(5)步:App.vue修改:

          <template><div id="app"><router-link to='/login'>login</router-link><router-link to='/main'>main</router-link><!--剩下的就是把路由到页面展示出来就好了--><router-view></router-view></div>
          </template><script>
          export default {name: 'App'
          }
          </script><style>
          </style>
          
      3. 第3步:测试

        1. npm run dev

      4. 附:排错,SASS版本过高

        1. 第(1)步:来到包版本管理文件pack.json,它里面有所有组件(插件)的版本吧。在里面找到SASS loader,看到是8.0.0版本的,所以版本太高了,所以这里我们把它的版本号改成7.3.1的版本。

        2. 第(2)步:由于pack.json中修改了版本,所以在终端重新npm install一下。npm install才是安装它吧,你改了不重新安装没有用的。

二十 嵌套路由

  1. 业务与需求

    1. 如上图所示,有两个请求,外面都是一样。

      1. 左边那个图表明,如果我请求User下面的profile,它会显示profiel的内容。
      2. 右边那个图表明,如果我请求User下面的posts,它会显示posts的内容。
      3. 但是其它页面是不变的,这里它只变局部吧。只变局部,对于vue来说真的是太轻松了,对不对。为什么会轻松呀?因为vue是component组件拔插,对不对,意思就是说把这个组件放进去就可以了。 在vue中可以通过路由去实现这样的功能。
  2. 案例演示------------------------------------------------------------------------------
    1. 第一步:在src/views目录下创建user目录(模拟:用户管理模块)
    2. 第二步:在src/views/user目录下创建Profile.vue(模拟:用户管理模块中的,个人信息页面)。
      <template><h1>个人信息Profile</h1>
      </template><script>
      export default {name: 'UserProfile'
      }
      </script><style>
      </style>
    3. 第三步:在src/views/user目录下创建List.vue(模拟:用户管理模块中的,用户列表页面)。
      <template><h1>用户列表List</h1>
      </template><script>
      export default {name: 'UserList'
      }
      </script><style>
      </style>
    4. 第四步:src/views/Main.vue修改。关键是我们想把UserProfile.vue和UserList.vue展示出来吧。是不是应该展示在Main.vue(这里增加侧边栏)里面吧。
      <template><div><el-container><el-aside width="200px"><el-menu :default-openeds="['1']"><el-submenu index="1"><template solt="title"><i class="el-icon-caret-right"></i>用户管理</template><el-menu-item-group><el-menu-item index="1-1"><!-- 通过router-link把用户个人信息放进去 --><router-link to="/user/profile">个人信息</router-link></el-menu-item><el-menu-item index="1-2"><!-- 通过router-link把用户列表放进去 --><router-link to="/user/list">用户列表</router-link></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="2"><template solt="title"><i class="el-icon-caret-right"></i>内容管理</template><el-menu-item-group><el-menu-item index="2-1">分类管理</el-menu-item><el-menu-item index="2-2">内容列表</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><el-container><el-header style="text-align: right; font-size: 12px"><el-dropdown><i class="el-icon-setting" style="margin-right:15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人信息</el-dropdown-item><el-dropdown-item>退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></el-header><el-main><!-- 它会把主页的东西展示在这里 --><!-- 即上面的两个router-link吧。 --><!-- 总结:一个页面中肯定有一个router-view,展示的内容是router-link指向的组件。 --><router-view/></el-main></el-container></el-container></div>
      </template><script>export default {name: "Main"}
      </script><style scoped lang="scss">.el-header {background-color: #048bd1;color: #333;line-height: 60px;}.el-aside {color: #333;}
      </style>
    5. 第五步:index.js。我们定义了3个组件,所以我们要把它导到路由组件里面去。
      //第一步:引入(导入)
      import Vue from 'vue'
      import Router from 'vue-router'   //  其中名称Router可以随便取,只要后面的vue-router对即可
      import Main from '../views/Main'  //  导入Main组件
      import Login from '../views/Login'//  导入Login组件
      import UserList from '../views/user/List'
      import UserProfile from '../views/user/Profile'//第二步:显示地使用它
      Vue.use(Router)//第三步:导出一个接口
      export default new Router({routes:[//  放置(配置)各种各样的路由{//  正常的(非嵌套)路由path:'/main',component:Main,//  嵌套路由children:[{path:'/user/profile',//    请求链接component:UserProfile// 路由(转发)到此组件},{path:'/user/list',//    请求链接component:UserList// 路由(转发)到此组件} ]},{path:'/login',component:Login}]
      });
    6. 第六步:测试
      1. npm run dev
      2. http://localhost:8080/
    7. 报错:<style scoped lang="scss">改成<style scoped>

二十一 参数传递及重定向

  1. 参数传递

    1. 业务

      1. 点击左侧导航栏的“个人信息”菜单,要求每个登录的人,展示不同的个人信息。
    2. 需求
      1. 第一步:接收前端的参数
      2. 第二步:请求的方式会是:localhost:8080/user/profile?userId=xxx
    3. 解决方案
      1. <router-link to>
    4. 案例:没有解偶:在你的组件中使用 $route 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 props 配置来解除这种行为:
      1. 传参 ——  组件,Main.vue

        <template><div><el-container><el-aside width="200px"><el-menu :default-openeds="['1']"><el-submenu index="1"><template solt="title"><i class="el-icon-caret-right"></i>用户管理</template><el-menu-item-group><el-menu-item index="1-1"><!-- 不传参 --><!--<router-link to="/user/profile">个人信息</router-link>--><!-- 传参:name传递的是路由名称,params传递的是组件参数列表 --><router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link></el-menu-item><el-menu-item index="1-2"><router-link to="/user/list">用户列表</router-link></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="2"><template solt="title"><i class="el-icon-caret-right"></i>内容管理</template><el-menu-item-group><el-menu-item index="2-1">分类管理</el-menu-item><el-menu-item index="2-2">内容列表</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><el-container><el-header style="text-align: right; font-size: 12px"><el-dropdown><i class="el-icon-setting" style="margin-right:15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人信息</el-dropdown-item><el-dropdown-item>退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></el-header><el-main><router-view/></el-main></el-container></el-container></div>
        </template><script>export default {name: "Main"}
        </script><style scoped lang="scss">.el-header {background-color: #048bd1;color: #333;line-height: 60px;}.el-aside {color: #333;}
        </style>
      2. 接收参数 —— 路由,index.js

        import Vue from 'vue'
        import Router from 'vue-router'
        import Main from '../views/Main'
        import Login from '../views/Login'
        import UserList from '../views/user/List'
        import UserProfile from '../views/user/Profile'Vue.use(Router)export default new Router({routes:[{path:'/main',component:Main,//  嵌套路由children:[{   //  其中的"/:id"用于接收参数path:'/user/profile/:id',name:"UserProfile",//“路由名称”用于<router-link>中的to属性用于传参数component:UserProfile},{path:'/user/list',component:UserList} ]},{path:'/login',component:Login}]
        });
      3. 页面展示“传递的参数” —— Profile.vue

        <template><div><h1>个人信息Profile</h1><!-- 获取参数(展示) -->{{$route.params.id}}</div>
        </template><script>
        export default {name: 'UserProfile'
        }
        </script><style>
        </style>
      4. 测试成功

        1. Module build failed Error Node Sass version 6.0.0 is incompatible with ^4.0.0

        2. "{{$route.params.id}}" outside root element will be ignored.

    5. 案例2:解偶(官网):通过 props 配置实现参数传递
      1. 狂神案例

        1. 传参 —— Main.vue不变,<router-link :to="{name:'UserProfile',params:{id:1}}">个人信息</router-link>
        2. 接收 —— index.js,声明使用props的方式
          import Vue from 'vue'
          import Router from 'vue-router'
          import Main from '../views/Main'
          import Login from '../views/Login'
          import UserList from '../views/user/List'
          import UserProfile from '../views/user/Profile'Vue.use(Router)export default new Router({routes:[{path:'/main',component:Main,children:[{   path:'/user/profile/:id',name:"UserProfile",props: true, // props参数传递,解偶component:UserProfile},{path:'/user/list',component:UserList}]},{path:'/login',component:Login}]
          });
        3. 页面展示“传递的参数” —— Profile.vue,通过组件去接收参数
          <template><div><h1>个人信息Profile</h1><!-- // props参数传递,解偶 -->{{id}}abc</div>
          </template><script>
          export default {// props参数传递,解偶,使用组件的方式接收参数props:['id'],name: 'UserProfile'
          }
          </script><style>
          </style>
      2. 官方文档
        1. 我们可以将下面的代码

          const User = {template: '<div>User {{ $route.params.id }}</div>'
          }
          const routes = [{ path: '/user/:id', component: User }]
        2. 替换成

          const User = {// 请确保添加一个与路由参数完全相同的 prop 名props: ['id'],template: '<div>User {{ id }}</div>'
          }
          const routes = [{ path: '/user/:id', component: User, props: true }]
    6. 总结:

      1. 在正常情况下,我们应该是传递一个对象,用对象作为参数吧。现在我们学会了单个参数(userId)的传递,那么同理,传递一个(甚至多个)对象也是用同样的方法,以此类推罢了。

  2. 重定向
    1. 怎么能够实现重定向呢?

      1. 浏览器地址栏url不变的跳转,叫做转发。浏览器地址栏url变化的跳转,叫重定向。
      2. 重定向的意思就是从一个path,跳转到另外一个path。
    2. 案例
      1. 第一步:index.js,修改路由配置文件

        import Vue from 'vue'
        import Router from 'vue-router'
        import Main from '../views/Main'
        import Login from '../views/Login'
        import UserList from '../views/user/List'
        import UserProfile from '../views/user/Profile'Vue.use(Router)export default new Router({routes:[{path:'/main',component:Main,children:[{   path:'/user/profile/:id',name:"UserProfile",},{path:'/user/list',component:UserList},{path:'/goHome',//  重定向,第一步:redirect:'/main'redirect:'/main'}  ]},{path:'/login',component:Login}]
        });
      2. 第二步:Main.vue,修改
        <template><div><el-container><el-aside width="200px"><el-menu :default-openeds="['1']"><el-submenu index="1"><template solt="title"><i class="el-icon-caret-right"></i>用户管理</template><el-menu-item-group><el-menu-item index="1-1"><router-link to="/user/profile">个人信息</router-link></el-menu-item><el-menu-item index="1-2"><router-link to="/user/list">用户列表</router-link></el-menu-item><!-- 第二步:传参 --><el-menu-item index="1-3"><router-link to="/goHome">返回首页</router-link></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="2"><template solt="title"><i class="el-icon-caret-right"></i>内容管理</template><el-menu-item-group><el-menu-item index="2-1">分类管理</el-menu-item><el-menu-item index="2-2">内容列表</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><el-container><el-header style="text-align: right; font-size: 12px"><el-dropdown><i class="el-icon-setting" style="margin-right:15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人信息</el-dropdown-item><el-dropdown-item>退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></el-header><el-main><router-view/></el-main></el-container></el-container></div>
        </template><script>export default {name: "Main"}
        </script><style scoped lang="scss">.el-header {background-color: #048bd1;color: #333;line-height: 60px;}.el-aside {color: #333;}
        </style>

二十二 404和路由钩子

  1. 业务需求1:

    1. 情况:在登录页面中输入什么样的用户名和密码都可以跳转到主页。
    2. 想要的:跳转到主页以后,应该显示当前登录人的信息。
    3. 案例:跳转到主页以后,应该显示当前登录人的信息。
      1. 传参:Login.vue

        <template><div><el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box"><h3 class="login-title">欢迎登录</h3><el-form-item label="账号" prop="username"><el-input type="text" placeholder="请输入账号" v-model="form.username"/></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" placeholder="请输入密码" v-model="form.password"/></el-form-item><el-form-item><el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button></el-form-item></el-form><el-dialogtitle="温馨提示":visible.sync="dialogVisible"width="30%":before-close="handleClose"><span>请输入账号和密码</span><span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
        </span></el-dialog></div>
        </template><script>export default {name: 'Login',data(){return{form:{username:'',password:''},rules:{username:[{required:true,message:'账号不可为空',trigger:'blur'}],password:[{required:true,message:'密码不可为空',trigger:'blur'}]},dialogVisible:false}},methods:{onSubmit(formName) {this.$refs[formName].validate((valid) => {if(valid){//  跳转到主页以后,应该显示当前登录人的信息。//  第一步:传参this.$router.push("/main/"+this.form.username);}else{this.dialogVisible = true;return false;}})}}}
        </script><style scoped>.login-box{border: 1px solid #DCDFE6;width: 350px;margin: 108px auto;padding: 35px 35px 15px 35px;border-radius: 5px;-webkit-border-radius:5px;-moz-border-radius:5px;box-shadow: 0 0 25px #909339;}.login-title{text-align: center;margin: 0 auto 40px auto;color: #303133;}
        </style>
      2. 接收参数:index.js

        import Vue from 'vue'
        import Router from 'vue-router'
        import Main from '../views/Main'
        import Login from '../views/Login'
        import UserList from '../views/user/List'
        import UserProfile from '../views/user/Profile'Vue.use(Router)export default new Router({routes:[{//  跳转到主页以后,应该显示当前登录人的信息。//  第二步:接收参数path:'/main/:name',component:Main,//  第三步:获取并展示参数//  第3-1步:声明使用props方式接收参数props:true,children:[{   path:'/user/profile/:id',name:"UserProfile",props: true, component:UserProfile},{path:'/user/list',component:UserList}]},{path:'/login',component:Login}]
        });
      3. 获取数据并展示:Main.vue
        <template><div><el-container><el-aside width="200px"><el-menu :default-openeds="['1']"><el-submenu index="1"><template solt="title"><i class="el-icon-caret-right"></i>用户管理</template><el-menu-item-group><el-menu-item index="1-1"><router-link :to="{name: 'UserProfile',params: {id: 1}}">个人信息</router-link></el-menu-item><el-menu-item index="1-2"><router-link to="/user/list">用户列表</router-link></el-menu-item><el-menu-item index="1-3"><router-link to="/goHome">返回首页</router-link></el-menu-item></el-menu-item-group></el-submenu><el-submenu index="2"><template solt="title"><i class="el-icon-caret-right"></i>内容管理</template><el-menu-item-group><el-menu-item index="2-1">分类管理</el-menu-item><el-menu-item index="2-2">内容列表</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><el-container><el-header style="text-align: right; font-size: 12px"><el-dropdown><i class="el-icon-setting" style="margin-right:15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item>个人信息</el-dropdown-item><el-dropdown-item>退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown><!-- 第三步:获取并展示参数 --><!-- 第3-3步:获取并展示数据 --><span>{{name}}</span></el-header><el-main><router-view/></el-main></el-container></el-container></div>
        </template><script>export default {//  第三步:获取并展示参数//  第3-2步:使用props属性接收参数props:['name'],name: "Main"}
        </script><style scoped lang="scss">.el-header {background-color: #048bd1;color: #333;line-height: 60px;}.el-aside {color: #333;}
        </style>
      4. 测试

        1. http://localhost:8080/

  2. 业务需求2:去掉链接中的" # "

    1. 解决方案 —— 路由模式与404:

    2. 配置过程

      1. 第一步:index.js路由管理器

        import Vue from 'vue'
        import Router from 'vue-router'
        import Main from '../views/Main'
        import Login from '../views/Login'
        import UserList from '../views/user/List'
        import UserProfile from '../views/user/Profile'Vue.use(Router)export default new Router({//  去掉链接中的" # ",history模式mode:'history',routes:[{path:'/main/:name',component:Main,props:true,children:[{   path:'/user/profile/:id',name:"UserProfile",props: true, component:UserProfile},{path:'/user/list',component:UserList}]},{path:'/login',component:Login}]
        });
      2. 第二步:测试

  3. 业务需求3:纯前端处理404

    1. 第一步:NotFound.vue,在src/views目录下创建新组件

      <template><div id="app"><h1>大兄弟404了</h1></div>
      </template><script>
      export default {name: 'NotFound'
      }
      </script><style>
      </style>
    2. 第二步:index.js,写完组件第一种事情就是把组件配置到路由上去

      import Vue from 'vue'
      import Router from 'vue-router'
      import Main from '../views/Main'
      import Login from '../views/Login'
      import UserList from '../views/user/List'
      import UserProfile from '../views/user/Profile'
      //  第一步:导入进来
      import NotFound from '../views/NotFound'Vue.use(Router)export default new Router({mode:'history',routes:[{path:'/main/:name',component:Main,props:true,children:[{   path:'/user/profile/:id',name:"UserProfile",props: true, component:UserProfile},{path:'/user/list',component:UserList}]},{path:'/login',component:Login},{//  第二步:配置404的路由path:'*', // 测试1:拦截除以上请求之外的任何所有请求component:NotFound}]
      });
    3. 第三步:测试

  4. 业务需求4:路由钩子与异步请求

    1. beforeRouteEnter,就像咱们的过滤器(chain链)、拦截器一样,即进入这个路由之前要进行过滤一下。to、from、next,即从哪里来(相当于HttpRequest),到哪里去(相同于HttpResponse),往下一个走(相当于chain链)。

    2. beforeRouteLeave,离开某个路由之前干什么事,即离开某个路由之前又过滤一便。

    3. 案例演示1:在钩子函数中使用异步请

      1. 第一步:安装axios和vue-axios组件(插件), npm install axios -s      npm install vue-axios -s
      2. 第二步:main.js要导入axios、vue-axios,不然你安装的组件是无法使用的

        1. import axios from 'axios';

        2. import VueAxios from 'vue-axios'

        3. 完整代码:

          import Vue from 'vue'
          import App from './App'
          import router from './router'
          import ElementUI from 'element-ui'
          import 'element-ui/lib/theme-chalk/index.css';
          //  第一步:安装Axios , cnpm install axios -s
          //  第二步:main.js引用Axios
          //    第2-1步:引入
          import axios from 'axios';
          import VueAxios from 'vue-axios'
          //    第2-2步:声明使用
          Vue.use(VueAxios,axios)
          Vue.use(router);
          Vue.use(ElementUI);new Vue({el: '#app',router,render: h => h(App)
          })
          
      3. 第三步:准备数据:只有我们的static目录下的文件是可以被访问到的,所以我们就把静态文件放入该目录下。

        1. //静态数据存放的位置:static/mock/data.json

        2. 完整代码:

          {"name":"狂神说java","url": "http://baidu.com","page": "1","isNonProfit":"true","address": {"street": "含光门","city":"陕西西安","country": "中国"},"links": [{"name": "B站","url": "https://www.bilibili.com/"},{"name": "4399","url": "https://www.4399.com/"},{"name": "百度","url": "https://www.baidu.com/"}]}
      4. 第四步:Profile.vue:在beforeRouteEnter中进行异步请求

        <template><div><h1>个人信息Profile</h1>{{id}}abc</div>
        </template><script>
        export default {props:['id'],name: 'UserProfile',//  路由钩子与异步请求//  进入这个页面之前,先执行这段代码,使用axios加载数据beforeRouteEnter:(to,from,next)=>{console.log("进入路由之前,使用axios加载数据");next((vm)=>{//vm —— 可以直接获取到当前的对象实例。vm就可以调用它本身methods中定义的方法。vm.getData();})//next();// 如果没有这句放,就阻塞了。//next("/path") //跳转到指定路径//next(false)  //返回上一页},  //  离开这个页面之前,先执行这段代码。beforeRouteLeave:(to,from,next)=>{console.log("离开路由之前纟xx");next();// 如果没有这句放,就阻塞了。},methods:{getData:function(){//使用axios加载数据this.axios({//请求method:'get',//get方式url:'http://localhost:8080/static/mock/data.json'}).then(function(response){//response是响应的东西,响应回来的结果console.log(response);});}}
        }
        </script><style>
        </style>
      5. 第五步:测试

        1. ​​​​​​​直接访问data.json:localhost:8080/static/mock/data.json

        2. 访问主页:localhost:8080/main

        3. 访问个人信息页面:http://localhost:8080/user/profile/1 

附1:docsify(一键)帮助文档生成工具

附2:npm命令解释

附3:最终项目的完整结构图 

vue,狂神,狂神和飞哥,前端一直在抄袭后端相关推荐

  1. 前端大串讲,狂神,狂神和飞哥

    -大前端进阶 - 篇章学习-Kuang-Study-文章 (377条消息) Vue入门技能树 (csdn.net) npm install -g npm@9.2.0 一 概述 前端框架:vue.Rea ...

  2. 支付宝支付 第十二集:狂神、飞哥支付宝支付配置代码(免费资源,拿走不谢)

    支付宝支付 第十二集:狂神.飞哥支付宝支付配置代码(免费资源,拿走不谢) 一.资源 链接:https://pan.baidu.com/s/1S-VAAMxiaPkgb2XZMQYEjA 提取码:091 ...

  3. RabbitMQ狂神说笔记(RabbitMQ B站狂神说笔记、KuangStudy、学相伴飞哥)

    一. 引用文章 RabbitMQ狂神说笔记(B站狂神说笔记.KuangStudy.学相伴飞哥) RabbitMQ狂神说笔记(B站狂神说笔记.KuangStudy.学相伴飞哥)百度云盘地址,提取码:07 ...

  4. 飞哥:程序员完全没时间提升自己该怎么办?

    大家好,我是飞哥! 很多同学都和我说过一个问题,有心想扎实地提高技术能力,但无奈工作太忙没有时间该咋办.相信你的实际工作中可能也有过过类似的困境. 当你工作了以后,你会发现抽出时间来学习貌似是一件很困 ...

  5. element ui 前台模板_SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 前端篇(二):引入 element-ui 定义基本页面显示...

    前提: (1) 相关博文地址: SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 前端篇(一):搭建基本环境:https://www.cnblogs.com/l-y ...

  6. vue学习笔记-01-前端的发展历史(从后端到前端,再到前后端分离,再到全栈)

    vue学习笔记-01-前端的发展历史(从后端到前端,再到前后端分离,再到全栈)   这篇文章是博主在看vue-前端发展简史的时候做的笔记,以供后续学习复习 文章目录 vue学习笔记-01-前端的发展历 ...

  7. jpa 自定义sql if_跟飞哥学编程:SQL入门-:函数、存储过程和触发器

    最后不要忘记:SQL是一种结构化(Structured)的语言(Language),所以它具有 编程语言的特性 声明变量和赋值 所谓变量,可以是看成一个存储数据的容器,所有它里面存储的值是可以变化的. ...

  8. Vue学习笔记(四)—— 前端路由

    介绍 本文主要介绍路由的相关知识,当然主要是以Vue的路由为主要介绍对象. 有兴趣的朋友可以看看之前的文章: Vue学习笔记(一)-- 常用特性 Vue学习笔记(二)-- 组件开发 Vue学习笔记(三 ...

  9. sql找出2000-3000年中的闰年。_跟飞哥学编程:SQL入门-4-查询和条件

    为了教学方便,我们先引入一个关键字: SELECT 使用SELECT,可以查询得到表数据,比如: SELECT 其中,星号(*)代表所有列.运行上述SQL语句,返回的就是Student表的所有行所有列 ...

最新文章

  1. 剑指offer:面试题16. 数值的整数次方
  2. 算法---删除排序链表中的重复元素 II
  3. 富文本编辑器 - wangEditor 表情
  4. java多参方法_Java中多参数方法进阶
  5. Mac忘记root密码(Mac OS Sierra忘记root密码如何重置)
  6. nsdictionary获取值_objective-c – 在NSDictionary中获取值
  7. JAVA深复制(深克隆)与浅复制(浅克隆)
  8. winxp制作服务器,你要知道的WinXP服务器操作系统安装的方法
  9. java byte数组与int,long,short,byte转换
  10. 全面规范的软件需求可以规避项目风险
  11. GB28181协议--心跳
  12. Apache ShenYu源码阅读系列-Divide插件
  13. IP地址分为几类?各如何表示?IP地址的主要特点是什么?
  14. Deep Learning for UAV-based Object Detection andTracking: A Survey(论文翻译)
  15. 集合 -- 如何安全删除 HashMap 中的元素
  16. picker多选 vant_浅谈vant组件Picker 选择器选单选问题
  17. PHP 图片上传 图片压缩
  18. 2022黑马Python学习笔记
  19. 二维码和条形码简单实现
  20. kali攻击wifi、破解wifi密码详细教程(二)

热门文章

  1. java前锋,编程语言世界里的最佳“11人”
  2. Apache MPM介绍
  3. 《ServiceComb设计揭秘》直播干货
  4. Pipenv永久配置镜像源与python版本
  5. centos7防火墙基本命令
  6. JQ表格排序,数字排序
  7. 【imessage苹果家庭推】最新版软件安装登录设备上的iMessages
  8. webStorm正则替换
  9. 90后世界五百强新青年,每年沪漂8个月,长住7天酒店,如何做到不焦虑不躺平?
  10. 智力游戏(黑白子交换)