首页前端开发VUEIDEA搭建vue-cli | vue-router | 排错思路、Webpack、Axios、周期、路由、异步、重定向

IDEA搭建vue-cli | vue-router | 排错思路、Webpack、Axios、周期、路由、异步、重定向

时间2023-07-05 12:18:02发布访客分类VUE浏览748
导读:Vue.js概述Vue 是一套用于构建用户界面的渐进式JavaScript框架。 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化...

Vue.js概述

Vue 是一套用于构建用户界面的渐进式JavaScript框架。 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用(SPA)提供驱动

MVVM模型

  • Model:模型层,表示JavaScript对象
  • View:视图层,表示DOM(HTML操作的元素)
  • ViewModel:连接视图层和数据的中间件,Vue.js就是MVVM中的ViewModel层的实现者


MVVM模型的特点:

低耦合:视图(View)可以独立Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变

可复用:可以将视图逻辑放在ViewModel中,让更多View重用这段视图逻辑

独立开发:开发人员可以专注于业务逻辑和数据开发(ViewModel),设计人员可以专注于页面设计

可测试:测试可以针对ViewModel编写


Hello Vue

!doctype html>
    
html lang="en">
    
head>
    
    meta charset="UTF-8">
    
    meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
    meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    title>
    Document/title>
    
    script src="../sources/vue.js">
    /script>
    
/head>
    
body>
    

!--view层 模板-->
    
div id="app">
    
    h1>
{
{
message}
}
    /h1>
    
/div>
    

script>

    var vm = new Vue({

        el: "#app",  //绑定元素
        //Model:数据
        data:{

            message:"Hello,Vue!"
        }

    }
    );
    
/script>
    
/body>
    
/html>
    

缩写 v-bind & v-on

  • v-bind缩写
!-- 完整语法 -->
    
a v-bind:href="url">
    .../a>
    

!-- 缩写 -->
    
a :href="url">
    .../a>
    

!-- 动态参数的缩写 (2.6.0+) -->
    
a :[key]="url">
     ... /a>
    
  • v-on缩写
!-- 完整语法 -->
    
a v-on:click="doSomething">
    .../a>
    

!-- 缩写 -->
    
a @click="doSomething">
    .../a>
    

!-- 动态参数的缩写 (2.6.0+) -->
    
a @[event]="doSomething">
     ... /a>
    

总结:

它们看起来可能与普通的 HTML 略有不同,但 :@ 对于 attribute 名来说都是合法字符,在所有支持 Vue 的浏览器都能被正确地解析。而且,它们不会出现在最终渲染的标记中


Vue的7个属性

el属性

指示vue编译器从什么地方开始解析 vue的语法

data属性

组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在data中

methods属性

放置页面中的业务逻辑,js方法一般都放置在methods中

template属性

设置模板,会替换页面元素

computed属性

用来计算,根据已经存在的属性计算出新的属性,对于同样的数据,会缓存

render属性

创建真正的Virtual Dom

watch属性

监听data中数据的变化


双向数据绑定

双向数据绑定,是指视图 View 的变化能实时地让数据模型 Model 发生变化,而数据的变化也能实时更新到视图层


  • 输入框双向数据绑定
!--view层 模板-->
    
div id="app">
    
    输入的文本:input type="text" v-model="message">
{
{
message}
}
    
/div>
    

script>

    var vm = new Vue({

        el: "#app",  //绑定元素
        //Model:数据
        data:{

            message:"同步更新"
        }

    }
    );
    
/script>
    
  • 单选框双向数据绑定
!--view层 模板-->
    
div id="app">
    
    性别:
    input type="radio" name="sex" value="男" v-model="wei_shuo">
     男
    input type="radio" name="sex" value="女" v-model="wei_shuo">
     女

    p>

        选中了谁:{
{
wei_shuo}
}
    
    /p>
    
/div>
    

script>

    var vm = new Vue({

        el: "#app",  //绑定元素
        //Model:数据
        data:{

            wei_shuo:""
        }

    }
    );
    
/script>
    
  • 下拉框双向数据绑定
!--view层 模板-->
    
div id="app">
    
        下拉框:
        select v-model="selected">
    
            option>
    ---请选择---/option>
    
            option value="A">
    A/option>
    
            option value="B">
    B/option>
    
            option value="C">
    C/option>
    
            option value="D">
    D/option>
    
        /select>
    
/div>
    

script>

    var vm = new Vue({

        el: "#app",  //绑定元素
        //Model:数据
        data:{

            selected:"---请选择---"
        }

    }
    );
    
/script>
    

组件

组件可以扩展 HTML 元素,封装可重用的代码;组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树


格式:

Vue.component('my-component-name', {
 /* ... */ }
    )

该组件名就是 Vue.component 的第一个参数

!--view层 模板-->
    
div id="app">
    

!--组件:传递给组件中的值;只能通过props参数接受-->
    
    wei_shuo v-for="item in items" v-bind:wei="item">
    /wei_shuo>
    

/div>
    

script>
    

    !--定义一个Vue组件component-->

    Vue.component("wei_shuo", {
    
        //接受参数
        props:['wei'],
        //模板
        template: 'li>
{
{
wei}
}
    /li>
'
    }
    );


    var vm = new Vue({

        el: "#app",  //绑定元素
        //Model:数据
        data: {

            items: ["Java","Linux","前端","后端"]
        }

    }
    );
    
/script>
    

Axios异步通讯

Axios是一个开源的可以用在浏览器和NodeJS的异步通讯框架,主要作用是实现AJAX异步通讯

特点:

浏览器创建XMLHttpRequests

从node.js创建http请求

支持Promise API(JS中链式编程)

拦截请求和响应

转换请求数据和响应数据

取消请求

自动转换JSON数据

客户端支持防御XSRF(跨站请求伪造)


背景

Vue.js是一个视图层框架,作者(尤雨溪)严格准守SoC(关注度分离原则),所以Vue.js并不包含AJAX的通讯功能,为了解决通信问题,作者单独开发了名为vue-resource的插件,2.0版本以后停止了对该插件的维护并推荐了Axios框架


Vue声明周期

Vue实例有完整的声明周期,开始创建、编译模板、挂载DOM、渲染-> 更新-> 渲染、卸载等一系列操作,也就是Vue实例从创建到销毁的过程,称为Vue的声明周期


声明周期钩子函数

创建前(beforeCreate)

Vue实例开始初始化时调用


创建后(created)

实例创建之后进行调用,此时尚未开始DOM编译


载入前(beforeMount)

依然得不到具体的DOM元素,但vue挂载的根节点已经创建


载入后(mounted)

在DOM文档渲染完毕之后进行调用


更新前(beforeUpdate)

data更新时触发


更新后(updated)

data更新时触发


销毁前(beforeDestroy)

销毁实例前进行调用,此时实例任然有效


销毁后(destroyed)

实例被销毁之后进行调用


  • 创建data.json文件
{

  "name": "wei_shuo",
  "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/"
    }

  ]
}
    
  • 引入vue.js和axios.js
script src="../sources/vue.js">
    /script>
    
script src="https://unpkg.com/axios/dist/axios.min.js">
    /script>
    
  • Vue.html文件
!doctype html>
    
html lang="en">
    
head>
    
    meta charset="UTF-8">
    
    meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
    meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    title>
    Document/title>
    
    script src="../sources/vue.js">
    /script>
    
    script src="https://unpkg.com/axios/dist/axios.min.js">
    /script>
    

    !--    v-cloak 解决闪烁问题 -->
    
    style>

        [v-clock]{
    
            display: none;

        }
    
    /style>
    
/head>
    
body>
    
div id="app" v-clock>
    
    div>
{
{
info.name}
}
    /div>
    
    div>
{
{
info.address.street}
}
    /div>
    
    a v-bind:href="info.url">
    点击/a>
    
/div>
    

script>

    var vm = new Vue({

        el: "#app",
        data() {

            return {

                //请求的返回参数,必须和json字符串一致
                info:{

                    name:null,
                    address:{

                        street:null,
                        city:null,
                        contry:null
                    }
,
                    url:null
                }

            }

        }
,
        mounted() {
      //钩子函数  链式编程
            axios.get('../data.json').then(response =>
     (this.info = response.data));

        }

    }
    )
/script>
    
/body>
    
/html>
    
/*
浏览器显示结果:
wei_shuo
陕西
点击
*/


内容分发(Slot插槽)

Vue.js中使用元素作为承载分发内容的出口,作者称为插槽,可以应用在组合组件的场景中

!doctype html>
    
html lang="en">
    
head>
    
    meta charset="UTF-8">
    
    meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
    meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    title>
    Document/title>
    
    script src="../sources/vue.js">
    /script>
    
/head>
    
body>
    
div id="app">
    
    todo>
    
        todo-title slot="todo-title" v-bind:title="title1">
    /todo-title>
    
        todo-items slot="todo-items" v-for="item1 in todoItems" :item="item1">
    /todo-items>
    
    /todo>
    
/div>
    
script>
    

    !--定义插槽-->

    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'],
        template: 'li>
{
{
item}
}
    /li>
'
    }
    );

    var vm = new Vue({

        el: "#app",
        data:{

            title1:"wei_shou列表",
            todoItems:['学习Java','学习Linux','学习Vue']
        }

    }
    )
/script>
    
/body>
    
/html>
    

自定义事件($emit)

自定义事件分发

格式: this.$emit('自定义事件名',参数)
this.$emit('remove', index);
    
!doctype html>
    
html lang="en">
    
head>
    
    meta charset="UTF-8">
    
    meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
    meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    title>
    Document/title>
    
    script src="../sources/vue.js">
    /script>
    
/head>
    
body>
    
div id="app">
    
    todo>
    
        todo-title slot="todo-title" v-bind:title="title1">
    /todo-title>
    
        todo-items slot="todo-items" v-for="(item1,index) in todoItems" :item="item1" v-bind:index="index"
                    v-on:remove="removeItems(index)" v-bind:key="index">
    /todo-items>
    
    /todo>
    
/div>
    
script>
    

    !--定义插槽-->

    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}
}
---{
{
item}
}
    button @click="remove">
    删除/button>
    /li>
',
        methods: {

            remove: function (index) {

                //自定义事件分发
                //this.$emit('自定义事件名',参数)
                this.$emit('remove', index)
            }

        }

    }
    );

    var vm = new Vue({

        el: "#app",
        data: {

            title1: "wei_shou列表",
            todoItems: ['学习Java', '学习Linux', '学习Vue'],
            removeItems: function (index) {
    
                console.log("删除" + this.todoItems[index] + "OK")
                this.todoItems.splice(index, 1);
    //一次删除一个元素
            }

        }

    }
    )
/script>
    
/body>
    
/html>
    

vue-cli项目

vue-cli是官方提供的一个脚手架,用于快速生成一个vue的项目模板;预先定义的目录结构及基础代码,使开发更加快速

功能:

  • 统一项目结构
  • 本地调试
  • 热部署
  • 单元测试
  • 集成打包上线


  • 创建Vue项目,新建目录
  • cmd目录窗进入创建的目录路径
  • 运行vue init webpack myvue命令初始化


等待5分钟左右,即可初始化完成

项目名称

? Project name (myvue)

项目描述

? Project description (A Vue.js project)

作者

? Author

构建(选择第一个即可:运行时编译)

? Vue build (Use arrow keys)

vue路由,以下n即是手动创建,y即是自动创建

? Install vue-router? (Y/n)

? Use ESLint to lint your code?(Y/n)

? Set up unit tests (Y/n)

? Setup e2e tests with Nightwatch? (Y/n)

No即不会自动npm install,yes就会自动npm install

? Should we run npm install for you after the project has been created? (recommended) (Use arrow keys)

Yes, use NPM

Yes, use Yarn

No, I will handle that myself

D:\Java\Vue-cli>
    vue init webpack myvue
? Project name (myvue)      
? Project description (A Vue.js project)
? Author 
? Vue build (Use arrow keys)
>
     Runtime + Compiler: recommended for most users
  Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are ONLY allowed in .vue files - re
nder functions are required elsewhere
? Install vue-router? No
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) (Use arrow keys)
>
     Yes, use NPM
  Yes, use Yarn
  No, I will handle that myself

  • 目录路径即会产生myvue目录


初始化运行

cd myvue

npm install

npm run dev


  • cmd窗口进入myvue路径
  • 执行npm install命令
  • 如果中途报错,安装命令窗口提示执行提示命令即可修复


  • 执行npm run dev 启动当前项目


  • cmd上面的cmd窗口别关闭,直接访问http://localhost:8080会出现如下页面


IDEA搭建vue-cli项目

  • 直接用IDEA——OPEN——myvue目录即可


Webpack学习

webpack 是代码编译工具,有入口、出口、loader 和插件。webpack 是一个用于现代JavaScript应用程序的静态模块打包工具,当 webpack 处理应用程序时,它会在内部构建一个依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。


安装Webpack

  • npm install webpack -g
  • npm install webpack-cli -g

测试安装成功

  • webpack -v
  • webpack-cli -v

配置

创建webpack.config.js配置文件

entry:入口文件,指定webpack用哪个文件作为项目入口

output:输出,指定webpack把处理完成的文件放置到指定路径

module:模板,用于处理各类类型的文件

plugins:插件,如:热更新、代码重用……

resolve:设置路径指向

watch:监听,用于设置文件改动后直接打包


webpack使用

  • 创建项目
  • 创建名为modules的目录,用于放置JS模板等资源文件
  • modules下创建模板文件,用于编写JS模板相关代码(hello.js)
//暴露一个方法
exports.sayHi = function () {
    
    document.write("h1>
    wei_shuo/h1>
")
}
    
  • modules下创建入口文件,用于打包时设置entry属性(main.js)
var hello = require("./hello");
    
hello.sayHi();
    
  • 项目目录下创建配置文件(webpack.config.js)
module.exports = {

    entry: './modules/main.js',
    output: {

        filename: "./js/bundle.js"
    }

}
    ;
    
  • 在IDEA终端使用webpack命令打包(bundle.js)
(()=>
{
var r={
    645:(r,t)=>
{
t.sayHi=function(){
    document.write("h1>
    wei_shuo/h1>
    >
")}
}
}
,t={
}
    ;
(function e(o){
    var i=t[o];
    if(void 0!==i)return i.exports;
var n=t[o]={
exports:{
}
}
    ;
return r[o](n,n.exports,e),n.exports}
)(645).sayHi()}
    )();
    
  • 项目目录下创建HTML页面,导入webpack打包后的JS文件(index.html)
!doctype html>
    
html lang="en">
    
head>
    
    meta charset="UTF-8">
    
    meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
    meta http-equiv="X-UA-Compatible" content="ie=edge">
    
    title>
    Document/title>
    
/head>
    
body>
    

!--前端的模块化开发-->
    
script src="dist/js/bundle.js">
    

/script>
    
/body>
    
/html>
    
  • 说明

参数 --watch 用于监听变化

webpack --watch


vue-router路由

Vue Router 是 Vue.js的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举

功能:vue-router官方

嵌套路由映射

动态路由选择

模块化、基于组件的路由配置

路由参数、查询、通配符

展示由 Vue.js 的过渡系统提供的过渡效果

细致的导航控制

自动激活 CSS 类的链接

HTML5 history 模式或 hash 模式

可定制的滚动行为

URL 的正确编码


安装vue-router

  • 基于第一个vue-cli进行测试学习;查看node_modules中是否存在vue-router
  • vue-router是一个插件包,所以需要用npm& cnpm进行安装


  • 打开IDEA终端,输入命令,安装vue-router
npm install vue-router --save-dev


  • 因为依赖关系报错则,使用如下安装命令
npm install --legacy-peer-deps vue-router --save-dev


  • 如果报错信息显示run npm audit fixto fix them,or npm audit for details;根据信息执行提示命令即可
npm audit fix
npm audit
  • 在项目main.js中导入,并使用
//导入安装的vue-router组件
import VueRouter from 'vue-router'

//显示声明使用VueRouter
Vue.use(VueRouter);
    


测试

  • IDEA终端运行项目
npm run dev
  • 如果出现报错
"export 'default' (imported as 'VueRouter') was not found in 'vue-router'


两种原因:

  • 路由格式编写错误

路由格式

routes: [{

    // 路径
    path: '/home',
    // 组件名
    component: Home
}
    ];
    
  • 对应版本不兼容

安装的时候默认安装最新版本可能与其他插件不兼容,推荐使用稳定版本vue-router@3.5.2

   卸载:npm uninstall vue-router
   下载&
    降级:npm install vue-router@3.5.2 --save-dev    //   @xxx 自己指定版本


  • 再次运行项目(npm run dev)


  • main.js 代码
import Vue from 'vue'
import App from './App'

//导入安装的vue-router组件
import VueRouter from 'vue-router'

//显示声明使用VueRouter
Vue.use(VueRouter);


Vue.config.productionTip = false

new Vue({

  el: '#app',
  components: {
 App }
    ,
  template: 'App/>
'
}
    )
  • App.vue代码
template>
    
  div id="app">
    
    h1>
    欢迎wei_shuo/h1>
    
  /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>
    


vue-router使用


创建公共组件目录components

目录components下创建vue组件

  • Content.vue
!--页面编写-->
    
template>
    
  h1>
    内容页面/h1>
    
/template>
    

!--vue对象-->
    
script>

export default {

  name: "Content"
}
    

/script>
    

!--scoped作用域,添加scoped只在当前页面生效-->
    
style scoped>
    

/style>
    
  • Main.vue
template>
    
  h1>
    首页/h1>
    
/template>
    

script>

export default {

  name: "Main"
}
    
/script>
    

style scoped>
    

/style>
    


创建存放路由的文件夹router

目录router创建router路由

  • index.js
//导入vue和vue-router组件
import Vue from "vue";
    
import VueRouter from "vue-router";
    
import Content from "../components/Content";
    
import Main from "../components/Main";
    
//安装路由
Vue.use(VueRouter);


//配置导出路由
export default new VueRouter({

  routes:[
    {

      //路由路径
      path:'/content',
      name:'content',
      //跳转组件
      component:Content
    }
,
    {

      //路由路径
      path:'/main',
      name:'content',
      //跳转组件
      component:Main
    }


  ]
}
    );
    


配置路由

在main.js中配置路由

import Vue from 'vue'
import App from './App'

//导入配置路由文件
import router from './router'   //自动扫描里面的路由配置

Vue.config.productionTip = false

new Vue({

  el: '#app',
  //配置路由
  router,
  components: {
 App }
    ,
  template: 'App/>
'
}
    )


使用路由

在App.vue中使用路由

template>
    
  div id="app">
    
    h1>
    欢迎wei_shuo/h1>
    
    !--跳转连接-->
    
    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>

#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>
    


vue-router使用流程

  • components目录下创建vue组件(wei.vue)
template>
    
  h1>
    wei/h1>
    
/template>
    

script>

export default {

  name: "wei"
}
    
/script>
    

style scoped>
    

/style>
    
  • 目录router创建router路由(index.js)
//导入vue和vue-router组件
import Vue from "vue";
    
import VueRouter from "vue-router";
    

//导入components目录中vue组件
import wei from "../components/wei"

//安装路由
Vue.use(VueRouter);


//配置导出路由
export default new VueRouter({

  routes:[
    {

      //路由路径
      path:'/wei',
      //name 可省略
      name:'content',
      //跳转组件
      component:wei
    }

  ]
}
    );
    
  • 在main.js中配置路由
template>
    
  div id="app">
    
    h1>
    欢迎wei_shuo/h1>
    

    !--跳转连接-->
    
    router-link to="/wei">
    wei/router-link>
    

    !--展示视图-->
    
    router-view>
    /router-view>
    

  /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>
    
  • 在App.vue中使用、导入配置路由
import Vue from 'vue'
import App from './App'

//导入配置路由文件
import router from './router'   //自动扫描里面的路由配置

Vue.config.productionTip = false

new Vue({

  el: '#app',
  //配置路由
  router,
  components: {
 App }
    ,
  template: 'App/>
'
}
    )


结果测试

  • 网页点击首页
  • 点击内容页面


  • 点击wei


Axios

Axios 是一个基于 promise(异步编程的一种解决方案)网络请求库,作用于node.js和浏览器中, 它是 isomorphic(即同一套代码可以运行在浏览器和node.js中);服务端它使用原生 node.js http 模块,,而在客户端 (浏览端)则使用 XMLHttpRequests

异步编程:异步编程是让程序并发运行的一种手段

功能:Axios中文网

从浏览器创建 XMLHttpRequests

从 node.js 创建http请求

支持Promise API

拦截请求和响应

转换请求和响应数据

取消请求

自动转换JSON数据

客户端支持防御XSRF


安装

$ npm install axios


Vue+ElementUI

Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库

Element官网


创建工程

  • 创建hello-vue工程
vue init webpack hello-vue



  • 安装依赖,需要安装vue-router、element-ui、sass-loader、node-sass四个插件
# 进入工程目录
cd hello-vue
# 安装 vue-router
npm install vue-router --save-dev
# 安装 element-ui
npm i element-ui -S
# 安装依赖
npm install
# 安装 SASS 加载器
cnpm install sass-loader node-sass --save-dev
# 启动测试
npm run dev
  • 安装 vue-router过程中如果报错依赖错误,则绕过依赖安装
npm install vue-router --save-dev --legacy-peer-deps


  • 安装element-ui报错依赖过程中如果报错依赖错误,则绕过依赖安装
npm i element-ui -S --save-dev --legacy-peer-deps


  • 安装依赖过程中如果报错依赖错误,则绕过依赖安装
npm install --save-dev --legacy-peer-deps


  • 安装 SASS 加载器WARNING是警告,可以忽略
cnpm install sass-loader node-sass --save-dev


  • 启动测试
npm run dev


  • 使用IDEA打开hello-vue项目


项目搭建


  • 创建页面目录(views)和前端路由目录(routers)
  • 页面目录(views)下创建
  • Main.vue(首页)
template>
    
  h1>
    首页/h1>
    
/template>
    

script>

export default {

  name: "Main"
}
    
/script>
    

style scoped>
    

/style>
    
  • 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-dialog
      title="温馨提示"
      :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 lang="scss" scoped>

.login-box {
    
  border: 1px solid #DCDFE6;
    
  width: 350px;
    
  margin: 180px auto;
    
  padding: 35px 35px 15px 35px;
    
  border-radius: 5px;
    
  -webkit-border-radius: 5px;
    
  -moz-border-radius: 5px;
    
  box-shadow: 0 0 25px #909399;

}


.login-title {
    
  text-align: center;
    
  margin: 0 auto 40px auto;
    
  color: #303133;

}
    
/style>
    
  • 前端路由目录(routers)下创建index.js
//导入vue和vue-router组件
import Vue from "vue";
    
import Router from 'vue-router'

//添加路由组件
import Main from "../views/Main";
    
import Login from "../views/Login";


//使用vue-router组件
Vue.use(Router)

//导出默认接口路由
export default new Router({

  routes:[
    {

      //路由路径
      path:'/main',
      //跳转组件
      component:Main
    }
,
    {

      //路由路径
      path:'/login',
      //跳转组件
      component:Login
    }

  ]
}
    );
    
  • main.js(入口js文件)
import Vue from 'vue'
import App from './App'

//导入配置路由文件,自动扫描里面的路由配置
import router from './routers'

//导入ElementUI
import Element from 'element-ui'
//导入ElementUI的CSS
import 'element-ui/lib/theme-chalk/index.css';
    

//安装路由
Vue.use(router);

//安装ElementUI
Vue.use(Element)

Vue.config.productionTip = false

new Vue({
    
  el: '#app',
  //路由
  router,
  //ElementUI
  render: h =>
 h(App)
}
    )
  • App.vue(根组件)
template>
    
  div id="app">
    
    router-view>
    /router-view>
    
  /div>
    
/template>
    

script>


export default {

  name: 'App'
}
    
/script>
    
  • IDEA终端运行
npm run dev


排错分析


排错一

  • 运行项目报错,this.getOptions is not a function,说明sass-loader版本太高
npm run dev
  • package.json文件中降低sass-loader版本


  • 更改完sass-loader版本,然后在终端使用npm install命令
  • 如果报错依赖无法解析如下


  • 则执行命令,如下所示则成功
npm install --legacy-peer-deps


排错二

Module build failed: Error: Node Sass version 8.0.0 is incompatible with ^4.0.0.
  • 错误来自sass-loader,因为node-sass @latest为v8.0.0,而sass-loader期望值为^ 4.0.0
  • 卸载5.0 重装系统提示需求版本即可(4.0.0)的就可以了
// 卸载node-sass
npm uninstall node-sass --legacy-peer-deps

// 然后安装需求版本
cnpm install node-sass@4.14.1 --legacy-peer-deps


排错三

Module build failed: Error: Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime (93)

查看本机安装的node版本安装对应的node-sass版本


  • 部分对应版本
node版本:v14.18.3
node-sass版本:4.7.2
sass-loader版本:7.3.1

node版本:16.13.1
node-sass版本:6.0.1
sass-loader版本:10.0.1
  • 查看自己的node版本,我的是node16,所以应安装node-sass 6.0+版本
D:\Java\Vue-cli\hello-vue>
    node -v
v16.18.0
  • 安装node-sass 6.0+版本(6.0.1)
  • package.json调整版本
"sass-loader": "^6.0.1"
  • 终端执行命令更新依赖项
npm install --legacy-peer-deps
  • 安装对应版本的node-sass
cnpm install node-sass@6.0.1 --legacy-peer-deps


排错四

"export 'default' (imported as 'Router') was not found in 'vue-router'
  • 原因一:路由格式编写错误
routes: [{

    // 路径
    path: '/home',
    // 组件名
    component: Home
}
    ];
    
  • 原因二:下载或者卸载已有版本
   卸载:npm uninstall vue-router
   下载&
    降级:npm install vue-router@3.5.2 --save-dev    //   @xxx 自己指定版本

降级之后,需要使用命令更新依赖

npm install --legacy-peer-deps

排错总结

  • 版本问题,更改package.json版本后,需要执行更新依赖的命令
npm install --legacy-peer-deps
  • 系统提示执行命令,可以直接执行即可
  • 错误多半是版本兼容错误,调整对应版本即可,如果是依赖错误的话,需要在命令后加上
--legacy-peer-deps


运行项目

  • 运行项目
npm run dev


vue项目目录分析

build:构建脚本目录


config:项目配置


node_modules:npm加载项目的依赖模块


src:源码目录


main.js——入口js文件

App.vue——根组件

components——共组件目录

assets——资源目录,这里的资源会被wabpack构建

routes——前端路由

store——应用级数据(state)

views——页面目录

static:静态资源目录,不会被webpack构建


package.json:npm包配置文件,定义项目的npm脚本、依赖包等信息


README.md:项目的说明文档,markdown格式


npm命令解析

  • 安装模块到项目下
npm install moduleName
  • -g:模块安装到全局
npm install -g moduleName
  • –save:模块安装到项目下,并在package文件的devDependencies结点写入依赖,-S 为缩写
npm install --save moduleName
  • –save-dev:将模块安装到项目目录下,并且在package文件devDependencies结点写入依赖,-D为缩写
npm install --save-dev moduleName


路由嵌套

嵌套路由(子路由),实际应用中,通常由多层嵌套的组件组合而成,同样的URL中各段动态路径也按某种结构对应嵌套的各层组件


/user/johnny/profile                     /user/johnny/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>
      | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+


项目结构

  • 创建页面目录(views)和前端路由目录(routers)
  • 页面目录(views)下创建,user目录
  • main.vue(首页)
template>
    
  div>
    
    el-container>
    
      el-aside width="200px">
    
        el-menu :default-openeds="['1']">
    

          el-submenu index="1">
    
            template slot="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-group>
    
          /el-submenu>
    

          el-submenu index="2">
    
            template slot="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-submenu index="3">
    
            template slot="title">
    i class="el-icon-caret-right">
    /i>
    系统管理/template>
    
            el-menu-item-group>
    
              el-menu-item index="3-1">
    系统信息/el-menu-item>
    
              el-menu-item index="3-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: #B3C0D1;
    
  color: #333;
    
  line-height: 60px;

}


.el-aside {
    
  color: #333;

}
    
/style>
    
  • ProFile.vue(个人信息)
template>
    
  h1>
    个人信息/h1>
    
/template>
    

script>

export default {

  name: "UserProFile"
}
    
/script>
    

style scoped>
    

/style>
    
  • List.vue(用户列表)
template>
    
  h1>
    用户列表/h1>
    
/template>
    

script>

export default {

  name: "UserList"
}
    
/script>
    

style scoped>
    

/style>
    
  • 前端路由目录(routers)下创建index.js
//导入vue和vue-router组件
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-router组件
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
    }

  ]
}
    );
    
  • main.js(入口js文件)
import Vue from 'vue'
import App from './App'

//导入配置路由文件,自动扫描里面的路由配置
import router from './routers'

//导入ElementUI
import Element from 'element-ui'
//导入ElementUI的CSS
import 'element-ui/lib/theme-chalk/index.css';
    

//安装路由
Vue.use(router);

//安装ElementUI
Vue.use(Element)

Vue.config.productionTip = false

new Vue({
    
  el: '#app',
  //路由
  router,
  //ElementUI
  render: h =>
 h(App)
}
    )
  • App.vue(根组件)
template>
    
  div id="app">
    
    router-view>
    /router-view>
    
  /div>
    
/template>
    

script>


export default {

  name: 'App'
}
    
/script>
    
  • IDEA终端运行


路由模式

  • hash:带路径#符号,如:http://localhost/#/login
  • history:路径不带#符号,如:http://localhost/login
export default new Router({

  mode:'history',
  routes: [
  ]
}
    );
    


参数传递& 重定向


参数传递

  • Main.vue
!--插入的地方 name:传递组件名 params:传递参数-->

router-link v-bind:to="{
name:'UserProFile',params:{
id:1}
}
    ">
    个人信息/router-link>
    
  • ProFile.vue
template>
    
  div>
    
    h1>
    个人信息/h1>

    !--{
{
 方式一:$route.params.id }
}
    -->

    {
{
id}
}
    
  /div>
    
/template>
    

script>

export default {

 //方式二: 
  props:['id'],
  name: "UserProFile"
}
    
/script>
    

style scoped>
    

/style>
    


重定向

//导出默认接口路由
export default new Router({

  mode:'history',
  routes: [
    //重定向
    {

      path:'/goHome',
      redirect:'/main'  //重定向路径
    }

  ]
}
    );
    


404页面

  • views页面目录,创建404页面
  • NotFound.vue
template>
    
  div>
    
    h1>
    404,你的页面走丢了!/h1>
    
  /div>
    
/template>
    

script>

export default {

  name: "NotFound"
}
    
/script>
    

style scoped>
    

/style>
    
  • index.js配置
import NotFound from "../views/NotFound"


//导出默认接口路由
export default new Router({

  mode:'history',
  routes: [
    {

      path:'/*',
      component:NotFound
    }

  ]
}
    );
    


路由钩子& 异步请求


路由钩子

beforeRouteEnter:在进入路由前执行

beforeRouteLeave:在离开路由前执行


to:路由将要跳转的路径信息

from:路径跳转前的路径信息

next:路由的控制参数

next() 跳入下一个页面

next(’/path’) 改变路由的跳转方向,使其跳到另一个路由

next(false) 返回原来页面

next((vm)=> { } ) 仅在beforeRouteEnter中使用,vm是组件实例


script>

export default {
    
  //进入路由之前执行
  beforeRouteEnter:(to,from,next)=>
{
    
    console.log("STARE");
    
    next();

  }
    ,
  //进入路由之后执行
  beforeRouteLeave:(to,from,next)=>
{
    
    console.log("END");
    
    next();

  }

}
    
/script>
    

异步请求

  • 安装Axios和vue-axios
cnpm install axios -s
cnpm install --save vue-axios
  • 安装Axios
  • main.js中导入Axios组件
//导入Axios
import axios from 'axios'
import VueAxios from 'vue-axios'

//安装axios和VueAxios
Vue.use(VueAxios, axios)


Vue工程化项目目录结构

node_modules 通过npm install命令安装的软件包存放的目录(非全局安装)


dist 项目打包发布目录


public 最后打包时,该目录中的文件会直接复制到dist目录中


public/index.html 首页入口文件

public/favicon.ico 图标文件

src


src/assets 静态资源文件目录


src/components 组件文件目录


src/router 路由插件目录


src/router/index.js 路由插件配置文件

src/store 状态管理插件目录


src/store/index.js 状态管理插件配置文件

src/plugins 插件目录,一般存放axios.js插件文件


src/views 组件文件目录(仅仅具有模板和样式,没有js程序)


src/App.vue 应用组件


src/main.js 程序逻辑入口文件


package.json 包管理配置文件,记录项目需要的各种软件包信息


package-lock.json 包版本锁定配置文件


vue.config.js vue项目配置文件


声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: IDEA搭建vue-cli | vue-router | 排错思路、Webpack、Axios、周期、路由、异步、重定向
本文地址: https://pptw.com/jishu/290238.html
Vue学习笔记(九) Vue CLI Vue学习笔记(十) Vue Router

游客 回复需填写必要信息