Vue高级实战

Vue-cli:
什么是Vue-cli:
Vue cli是基于Vue的应用开发提供的一个标准的脚手架工具
为应用搭建基础的框架结构,提供插件、开发服务、Preset、构建打包功能
Vue cli 背后集成了现代化开发的诸多功能,通过简单的命令就可以完成 "零配置"的项目环境搭建
安装Vue-cli步骤 :
在安装vue-cli前,要确认自己的电脑是否安装了nodejs和npm
安装Node.js:
安装了node.js才有(或者说能)使用npm ,才能安装vue-cli
什么是node.js:

为什么会有node.js:

下载对应你系统的Node.js版本:
下载地址:https://nodejs.org/en/download/

我的地址:
链接:https://pan.baidu.com/s/1zFJ6JRcZKv38F6JknKY0HA
提取码:alsk
选安装目录进行安装, 我选择安装在了E盘: E:\Program Files\nodejs
测试:在命令提示符下输入命令
//node -v //会显示当前node的版本
安装NPM:
npm全称Node Package Manager,他是node包管理和分发的工具,使用NPM可以对应用的依赖进行管理
NPM 的功能和服务端项目构建工具maven的依赖管理功能差不多,我们通过npm 可以很方便
地下载js库,打包js文件
node.js已经集成了npm工具
在命令提示符输入 npm -v 可查看当前npm版本
//npm -v
查看包管理路径:
包路径就是npm从远程下载的js包所存放的路径
使用 npm config ls 查询NPM管理包路径(NPM下载的依赖包所存放的路径)
//npm config ls
我们发现NPM默认的管理包路径在:
//C:\Users\86187\AppData\Roaming\npm
设置包管理路径:
依赖包放在C盘不太合适,为了方便对依赖包管理,我们将管理包的路径设置在单独的地方:
我们选择一个路径,专门存放这些依赖包,我选择创建一个目录: H:\software\nodejs_package
在 H:\software\nodejs_package 下再创建 npm_modules 文件夹 和 npm_cache 文件夹
执行下边的命令,设置为自定义的包管理路径:
//npm config set prefix "H:\software\nodejs_package\npm_modules" 全局位置设置
//npm config set cache "H:\software\nodejs_package\npm_cache" 缓存位置设置
此时再使用 npm config ls 查询NPM管理包路径发现路径已更改

NPM环境变量配置:
查看npm的全局路径是什么
//npm config get prefix

配置PATH环境变量:
添加新的系统变量:key=NODE_HOME , value= H:\software\nodejs_package
path中添加 %NODE_HOME%\npm_modules
安装cnpm
npm默认会去国外的镜像去下载js包,在开发中通常我们使用国内镜像,这里我们使用淘宝镜像
下边我们来安装cnpm: 有时我们使用npm下载资源会很慢,所以我们可以安装一个cnmp(淘宝镜像)来加快下载速度
联网情况下, 输入命令,进行全局安装淘宝镜像:
//安装
npm install -g cnpm --registry=https://registry.npm.taobao.org
//查看cnpm的版本
cnpm -v
安装vue-cli :
目前主流版本是 2.x 和 3.x 版本,安装3.x 以上的版本是因为该版本既可以创建2.x项目与3.x 项目
注意:以管理员身份打开命令行
安装命令:
//npm install -g @vue/cli
输入 vue命令:

输入 vue -V 查看版本
//vue -V

快速构建Vue项目
我们使用vue-cli 快速构建项目,步骤如下:
桌面创建一个空的文件夹
以管理员身份运行cmd , 进入到vueTest文件夹(之所以用管理员,是因为可能普通的cmd不会解释对应命令,虽然有时可以)
执行下面的命令
//基于交互式命令方式,创建项目
//文件名 不支持驼峰(含大写字母)使用短横线方式
vue create my-project
//选择自定义安装,点击回车

在这列表中,选择我们要安装的组件,使用空格键选择,选好后回车

之所以去掉语法检查,是因为这个语法检查非常严格,编写时会出现许多提示错误,为了不那么的烦,可以去掉
按回车之后,提示选择什么模式的路由,我们输入 n (表示选择hash模式)

选择项目配置文件单独存放

是否保存模板,选择n则是不创建,y创建,若创建,起一个名称,那么上面的自定义安装那里
就会多出一个选项,就是你保存的模板选项,安装保存的执行安装

安装完成,提示输入执行下面这两个命令

首先进入项目目录
//cd my-project
启动项目
//npm run serve

访问项目:http://localhost:8080/

停止项目 只要关闭命令行窗口就可以
导入Vue项目到VSCode:
VSCode中右键选择打开文件夹
选择桌面上的项目
打开项目,可以看到如下项目结构

项目结构介绍:
<!--
|--- my-project 项目名称|--- node_modules 存放依赖包的目录|--- public 静态资源管理目录|--- src 组件源码目录(我们写的代码)|--- assets 存放静态图片资源(CSS也可以放在这里)|--- components 存放各种组件(一个页面可以看做一个组件),各个组件联系在一起组成一个
完整的项目|--- router 存放了项目路由文件|--- views 放置的为公共组件(主要还是各个主要页面)|--- App.vue app.vue可以当做是网站首页,是一个vue项目的主组件,页面入口文件|--- main.js 打包运行的入口文件,引入了vue模块和app.vue组件以及路由route|--- babel.config.js babel配置文件, 对源代码进行转码(把es6=>es5)|--- package.json 项目及工具的依赖配置文件|--- paxkage-lock.json 依赖配置文件|--- README.md 项目说明
-->
图解说明:

主页面就是public中的index.html,vue通过一系列操作,将组件放入这个页面里面
Vue脚手架自定义配置
package.json 介绍
每个项目的根目录下面,一般都有一个 package.json 文件,定义了这个项目所需要的各种模块(可以看成maven的pom.xml文件)
以及项目的配置信息(比如名称、版本、许可证等元数据)
npm install 命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境
<!--
{//1.项目基本信息"name": "project3","version": "0.1.0","private": true,//2.指定运行脚本命令"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build"},//4.生产环境所依赖模块的版本"dependencies": {"core-js": "^3.6.5","vue": "^2.6.11","vue-router": "^3.2.0"},//5.本地环境开发所依赖的版本"devDependencies": {"@vue/cli-plugin-babel": "~4.4.0","@vue/cli-plugin-router": "~4.4.0","@vue/cli-service": "~4.4.0","vue-template-compiler": "^2.6.11"}
}-->
通过package.json 配置项目 :
配置内容采用JSON格式,所有的内容都用双引号包裹
打开package.json,再最末端添加如下配置:
<!--
"vue":{"devServer":{"port":"8888", 改变的端口和自动打开可能没有效果,版本越高,就越严格,可能需要对应管理员才会有效果"open":true}
}
最好手写,即要符号他的符号规范,因为复制的,可能不符合他的位置规范
-->
配置说明:该配置设置打包时服务器相关的信息
port:访问端口
open true:打包完成自动打开浏览器
启动项目:
在VSCode中选择项目,右键在终端打开

输入命令:
//npm run serve
运行后发现端口号改为 8888,并且在打包完成后自动打开浏览器
注意:不推荐这种方式,因为package.json 主要是用来管理包的配置信息,为了方便维护
我们将Vue脚手架相关的配置单独定义到 vue.config.js 配置文件中
单独的配置文件配置项目:
在项目的根目录创建文件 vue.config.js
删除掉package.jspn中新添加的配置项
在vue.config.js 文件中进行相关配置
<!--
module.exports = {devServer:{open:trueport:8889}
}-->
如果package.json不起作用(可能需要对应权限),那么就使用这个
Vue 组件化开发:
组件化是Vue的精髓,Vue项目就是由一个一个的组件构成的, 我们主要的工作就是开发的组件,在57章博客最后的路由中我们也知道是这样,对应的说明是基础,也是脚手架为什么出现的原因
组件介绍:
我们用 vue-cli 脚手架搭建的项目,里面有很多,如 index.vue 或者 App.vue 这一类的文件
每一个*.vue 文件都是一个组件 ,是一个自定义的文件类型,比如 App.vue 就是整个项目的根组件
常见的组件:
页面级别的组件:
页面级别的组件,通常是 views 目录下的.vue组件,是组成整个项目的各个主要页面
业务上可复用的基础组件:
这一类组件通常是在业务中被各个页面复用的组件,这一类组件通常都写到 components 目录下,然后通过import在各个页面中使用
组件的组成部分:
template:组件的HTML部分
script:组件的JS脚本 (一般使用ES6语法编写)
style:组件的CSS样式
<!-- 1.template 代表html结构, template中的内容必须有且只有一个根元素编写页面静态部分 就是 view部分 -->
<template><div>测试页面...</div>
</template>
<!-- 2.编写vue.js代码 -->
<script>//可以导入其组件// import Header from '../components/header.vue' //默认写法,输出该组件信息,并定义组件信息export default {name:"Home", // 组件名称,用于以后路由跳转data() {// 当前组件中需要使用的数据return {}},methods: {}}
</script>
<!-- 编写当前组件的样式代码 -->
<style scoped>/* 页面样式 加上scoped 表示样式就只在当前组件有效,防止其他导入时,会影响导入对象的显示*/
</style>
项目运行流程 :
main.js:
项目运行 会加载入口文件 main.js
/*
html文件中,通过script src = 'xxx'标签引入js文件。而vue中,通过 import 变量名 from 文件路径 的方式导入文件,不光可以导入js文件。1.变量名: 指的是为导入的文件起一个名称,不是指导入的文件的名称,相当于变量名(也可以随便写,符号语法就行)2.文件路径: 指的是文件的相对路径变量名不做要求,如aa,bb
*/
import Vue from 'vue'    //导入vue,即可以使用vue.js(全局的)
import App from './App.vue' //导入主组件
import router from './router' //导入路由
//关闭启动提示,vue使用时,会出现的提示,如在控制台的出现
Vue.config.productionTip = false
//创建Vue实例
new Vue({router, //为整个项目添加路由render: h => h(App) //这是一个函数ES6语法,作用是生成模板: App = App.vue
}).$mount('#app') //挂载的是主页面中的id为app的区域
//一般来说,这个js是使得所有组件一起操作的主要入口,也就是说,他的确是入口文件,即他是主体
App.vue:
App.vue 是vue项目的主组件,是页面入口文件 ,所有页面都是在App.vue下进行切换的
<!--App.vue 中的模板(HTML代码)-->
<template><div id="app"> <!--不是挂载这个div,而是主页面的div,只是这个id与主页面一样--><div id="nav"><!--这里是两个路由导航链接1. to="/" 项目根路径 跳转的是首页--><router-link to="/">Home</router-link> |<!--2. to="/about" 点击About按钮,跳转到about组件--><router-link to="/about">About</router-link></div><!--router-view 的作用是 根据访问的路径,渲染路径匹配到的视图组件--><router-view/></div>
</template>
router 路由:
找到路由文件,来看一下具体的路由配置
// 引入所需文件
import Vue from 'vue'  //vue库
import VueRouter from 'vue-router'  //vue-router库
import Home from '../views/Home.vue' //首页
//使用路由功能,之所以需要这个,与文件有关,即插件的对应install,为什么这样,是规定这样的
Vue.use(VueRouter)
//创建路由规则
const routes = [{path: '/', //路径name: 'Home', //名称component: Home  //组件 Home.vue,可以加上vue对应组件,vue后缀的操作,其他后缀操作基本不可以},{path: '/about',name: 'About',component: () => import(/* webpackChunkName: "about" */
'../views/About.vue')}
]
//创建路由管理器,管理routes
const router = new VueRouter({routes
})
//export 用来导出模块 router就代表了整个路由文件,若学习了48章博客,那么这个作用就完全知道了
export default router
Home.vue组件 :
默认访问的是Home.vue 首页
视图部分
<template><div class="home">首页的logo<img alt="Vue logo" src="../assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js App"/></div>
</template>
JS部分
<script>//导入了一个组件 HelloWorld.vue @符号表示 src这个目录
import HelloWorld from '@/components/HelloWorld.vue'
export default {name: 'Home', components: { HelloWorld //vue使得可以直接传入组件,即vue后缀的就可以看成一个组件}
}</script>
HelloWorld.vue 组件页面,该页面可以与你们不同,因为省略写的
<template><div class="hello"><h1>{{ msg }}</h1><p>For a guide and recipes on how to configure / customize this project,<br>check out the<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli
documentation</a>.</p><h3>Installed CLI Plugins</h3></div>
</template>
<script>export default {name: 'HelloWorld',//props 表示组件中的属性,组件可以通过这个属性类型接收参数props: {msg: String //一般js的window中存在String这个属性,打印出来的值是:ƒ String() { [native code] },具体作用可以百度}
}</script>
上面路由导入对应views的vue,然后main.js导入路由,然后指向到App.vue
组件发展:
组件从html内容导入(写html)
到定义html内容导入(选择器)
到选择导入(路由,但是在一个文件里)
到分开导入(使用vue后缀的组件分开)
组件的使用案例:
创建Header.vue组件:
在components 目录下创建 Header.vue
<template><div class="Header">{{msg}}</div>  <!-- 被导入的地方,有导入的vue,所以最后会被识别-->
</template><script>
//js部分
export default {name:"Header", //组件的名称,不是class的名称data() { //必须是函数,没有赋值操作return {msg:"这是一个Header组件 "};},}//这里要说明一个问题,在后面我会认为他像vue一样的执行,实际上的确也是,但是他是被路由使用的而已,由于他们是一个组件里面的,那么路由一般会给对应创建一个vue实例,使得看起来vue的执行,或者说路由与唯一的main的vue进行合并,只是有组件(如名称)的区别而已
</script><!--
scoped 表示当前样式,只作用与当前组件template,因为路由可能会进行合并,从而跳到外面去
-->
<style scoped>
.Header {height: 100px;line-height: 100px;background-color: #eee;text-align: center;color: blue;
}
</style>
引入 Header组件
实际上,若理清了上述步骤,那么就知道修改Home.vue对应的文件
<template><div class="home"><img alt="Vue logo" src="../assets/logo.png"><!-- <HelloWorld msg="Welcome to Your Vue.js App"/> --><Header/></div>
</template>
<script>
// @ is an alias to /src
//import HelloWorld from '@/components/HelloWorld.vue'
import Header from '@/components/Header.vue';
export default {name: 'Home',components: {//HelloWorldHeader}
}
</script>
组件的传参:
props : 是组件中的属性,表示组件可以接受参数
<template><div class="Header">{{msg}}</div>
</template><script>
//js部分
export default {name:"Header", //组件的名称,不是class的名称// data() { //必须是函数,没有赋值操作,这是方法的对应简写//     return {//         msg:"这是一个Header组件 "//     };// },// props:{//     msg:String// } 也可以下面的这样写props:['msg']}
</script><!--
scoped 表示当前样式,只作用与当前组件template
-->
<style scoped>
.Header {height: 100px;line-height: 100px;background-color: #eee;text-align: center;color: blue;
}
</style>
<template><div class="home"><img alt="Vue logo" src="../assets/logo.png"><!-- <HelloWorld msg="Welcome to Your Vue.js App"/> --><Header msg="这是通过props属性进行赋值显示出来的"/></div>
</template><script>
// @ is an alias to /src
//import HelloWorld from '@/components/HelloWorld.vue'
import Header from "@/components/Header.vue"
export default {name: 'HomeView',components: {//HelloWorldHeader}
}
</script>
Element-UI :
Element-UI介绍:
element-ui 是饿了么前端出品的基于 Vue.js的 后台组件库,方便程序员进行页面快速布局和构建
Element-UI官方站点:
https://element.eleme.cn/#/zh-CN
Element-UI使用 :
创建 一个新的项目
当前项目下打开终端, 安装依赖包 ,执行下面的命令
//npm i element-ui -S  -S保存到项目里面,可能被弃用了

打开 main.js , 导入Element-UI 相关资源
main.js是工程的入口文件,在此文件中加载了很多第三方组件,如:Element-UI、Base64、VueRouter等
//导入组件库
import ElementUI from 'element-ui'
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css'
//配置Vue插件 将El安装到Vue上,使得vue自己可以进行使用里面的内容
Vue.use(ElementUI);
//通过工程进行操作的,一般是对应的elementUI自己弄的,要不然怎么可以操作导入呢,极少数是cli自己弄的

import Vue from 'vue'
import App from './App.vue'
import router from './router' //检查这个文件,直接获得里面所有的导出数据//导入element-UI组件,无需路径
//导入组件库
import ElementUI from 'element-ui'
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css' //特殊的操作,可以这样哦,使得在最外面,虽然js可以操作,实际上css也可以了,虽然并没有说明,这里说明一下,具体可以百度
//配置Vue插件 将El安装到Vue上,有些不用,全局的(但导入的基本上都会使用use,当然也有例外,如axios,自动全局)
//实际上是install的名称在作用,具体去百度
Vue.use(ElementUI); //插件一般需要use方法,组件一般不需要//上面的导入的基本是对应的js(组件也是js来的),只不过这里将组件分开封装了,而不是集中在一个页面
Vue.config.productionTip = false //这个意思是:https://blog.csdn.net/m0_62131346/article/details/124822282new Vue({router, //获得所有的导出数据,并再使用时,自然的会执行导出数据的作用(找到对应作用)render: h => h(App) /*是下面的简写render: function (createElement) {return createElement(App);
}*/
}).$mount('#app')
//注意2x的脚手架是上面的操作,3x的则是使用保留项(若要使用3x的,则去百度3x的用法),2x的方便一些
复制Element 按钮样式 到app.vue文件的 template下
<template><div id="app"><nav><el-row><el-button>默认按钮</el-button><el-button type="primary">主要按钮</el-button><el-button type="success">成功按钮</el-button><el-button type="info">信息按钮</el-button><el-button type="warning">警告按钮</el-button><el-button type="danger">危险按钮</el-button>
</el-row><router-link to="/">Home</router-link> |<router-link to="/about">About</router-link></nav><router-view/></div>
</template><style>#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}nav {padding: 30px;
}nav a {font-weight: bold;color: #2c3e50;
}nav a.router-link-exact-active {color: #42b983;
}</style>
启动项目 npm run serve, 查看页面

Vue-CLI工程改造 :
删除components 目录下的 HelloWord.vue组件
删除App.vue中的部分内容,只保留如下部分
<template><div id="app"></div>
</template>
<style></style>
删除router文件下的路由文件 index.js部分内容,只保留如下部分
<!--
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)const routes = []
const router = new VueRouter({routes
})
export default router-->
删除views目录下的 About.vue 与 Home.vue
安装axios:
注意npm i(install)对应名称,这个名称不要乱写,就算是aaaa,他都可能会帮你下载出来,因为是全网下载的(找类似),当然,如果不存在,他都可能会给出一些固定信息(好像有)
npm安装:使用npm下载axios包
//npm i axios //一般来说,脚手架会帮我们解决好跨域的问题(是解决前端跨域问题,但是后端并不会,因为不是一个地方的,所以在后面需要解决后端的跨域,当然,如果他前端也没有解决,那么你可以百度找解决方法,这里就不多说明了)
在main.js文件中导入axios 相关资源
//引入axios
import axios from 'axios'
//Vue对象使用axios,给vue添加属性,因为这里都是使用vue来操作的,添加属性好操作
Vue.prototype.axios = axios; //给对象添加属性的,这里是创建对象之前:https://blog.csdn.net/zero_hn/article/details/77700521///创建对象之后:https://www.likecs.com/show-205201279.html
从这里得出:实际上也是引用对应的Element-UI的js(封装好的组件),而组件使得分工
前面我说过:组件里面可以有组件,这其实是针对与模板,无论组件如何操作,实际上就是操作模板
而组件中的组件,就是模板中的模板,当其中的模板(组件),变化时,外边的模板(组件)也就包括了其组件
就如template: “< lagou-head></ lagou-head>”(一般全局来识别,因为他在任何时候都识别,而不像局部一样,只识别一次,所以< template>里面的< template>通常不会进行操作,就相当于一个标签,所以一般来说,路由操作的基本都是全局组件,或者他操作的是局部组件,但是必然也只有一个 < router-view>< /router-view >,但是一般外面都会利用嵌套组件,所以这里外面认为是全局组件),里面加了组件(且符合有且只有一个根元素)
这样的话一个组件(模块)也就可以当作html的导入,就类似于jsp中的<%@include file=“被包含的文件地址”%>操作
但是只有组件是这样的作用
但也需要遵循从上到下原则
实际上并不是局部组件不能嵌套,只是需要特殊操作,看这个地址:https://blog.csdn.net/weixin_60941411/article/details/127976738
他并非是不同的真正局部,可以认为他的那个只是将对应的内容进行合并而已,而并非是组件标签里面加上组件标签,使得是组件标签来进行替换,所以上面的是否是局部组件的说明也可以这样的理解,他也是组件内容的直接合并,或者说,都是使用全局组件,当然了,其中css等等会加上对应名称来进行划分,因为在html中,一般css都是代表全局的,而不会随着你放在那里使得不是全局,js也是如此,html是替换而已,使得不是
用户登录界面制作:
<template>
<!-- :show-close是否有关闭的x号-->
<el-dialog :show-close="false" title="用户登录" :visible.sync="dialogFormVisible"><el-form><el-form-item label="用户名称" :label-width="formLabelWidth"><el-input v-model="user.username" autocomplete="off"></el-input></el-form-item><el-form-item label="用户密码" :label-width="formLabelWidth"><el-input v-model="user.password" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="login">登 录</el-button></div>
</el-dialog>
</template><script>
//这里说明一下导出,这个导出不是只其他组件只能使用这个,而是其他组件可以使用这个对象
//就如你定义在本部的变量别人不能用,要让别人能用,则需要导出,因为这里的js只操作本组件
//其他人用不了,就如网页的从上到下类似,所以这里导入就相当于导入组件//即网页代码(vue后缀的操作),因为他是这样设置的export default {//在vue组件里,export default相当于操作了template里面内容,并使用new Vue(),且是操作当前组件//但是不是vue组件的,不会当成new Vue()的格式操作,这里要注意//所以实际上这是一个新的格式,vue组件格式data() {  //方法的简写,调用赋值,最终无论怎么操作//都是赋值给自己的结果,但这个只是调用方法,所以不能是直接的有值return {dialogFormVisible: "ture", //是否显示这个样式页面,这里有些脚手架配置boolean时,可以不用分号,有些必须要formLabelWidth: '120px',user:{username:"",password:""}};},methods:{//登录的方法login(){//定义常量保存urlconst url = "https://f4cbbb2f-1750-4937-b7cd-62fa010c48cd.mock.pstmn.io/login";//var that = this//发送请求,被暴露给其他人,那么this就会变化,最终使用对应的axios了//默认getthis.axios(url,{ //这里可以不用将参数放在url里,可以放在params里面,也就不用加上get和post了//他们只是一个数据的显示方式而已//携带的参数 params:{ //post没有,实际上可以直接在大括号里定义对应的通用方式,具体百度username:this.user.username,password:this.user.password}}).then((resp) =>{console.log(resp)alert("登录成功")this.dialogFormVisible = false//使用箭头函数,他的this会自动获取上一级的this//也就是相当于上面的that,获得方式有很多种,从window开始或者得到上层的Object//跳转到首页页面,在这里我们使用路由进行调整页面,使用$router对象中的push方法//地址栏是#由//包括了,而不是#/,因为这是vue,其实路由就是一种特殊的页面调整//使得URL改变而页面刷新,因为URL的改变进行刷新一定是由某个点进行刷新的,而路由就是阻止这个点//由#来识别,或者端口,以及这个提交方式//而使用组件,使得并没有刷新,但缺点是,很难记录上次页面的信息,如分页的操作this.$router.push('index') //相当于帮你点击index路径的路由}).catch((error) => { //除了在then里加上错误函数,也可以使用catch来操作错误函数//没有名称的方法可以这样写,相当于function(error){} - (error) => {}this.$message.error('对不起,登录失败');})}}};
</script><style scoped></style>
import Vue from 'vue'
import VueRouter from 'vue-router'//导入Login.vue组件
import Login from '@/components/Login' //vue后缀的,可以不写后缀名//导入布局组件
import Index from '@/components/Index'//导入课程组件
import Course from '@/components/Course'Vue.use(VueRouter)
//配置路由信息
const routes = [//访问/也到登录页面{path:"/",//redirect:"login"redirect:"index" //当访问的是/,那么就在后面加上login并重新访问,也符号加/到端口号定律//ok在这些操作下,可以知道,他们操作端口,就与服务器操作端口类似,使得可以访问到这里的数据,且从src开始},//登录路由{path:"/login",name:"login",component:Login},//布局路由{path:"/index",name:"index", //name不止可以设置值,使得进行不同值的操作,且有些方法,必须要有name,所以路由也最好写上namecomponent:Index,//添加子路由,使用children属性,来表示子路由//寻常的路由在进行指向组件时,用<router-view></router-view>来获得对应组件信息//当然可以指定name来获得不同的组件信息//但是当使用其他路由时,当前路由页面就会变化,因为这些组件,只在当前挂载点操作//地址改变其他对应页面路由所在的挂载点也会进行对应地址操作//那么如何使得页面不变,也可以使用组件呢,那么就可以得出一个组件里也可以有多个子组件//这样的我们称之为子组件,这样就可以使得页面不变,而进行组件操作,但很明显,只会在这个组件里操作//实际上就是前面说的组件里面可以有组件,只不过可以有的这个组件是路由控制的children:[//课程信息子路由{path:"/course", //当组件里进行跳转时,页面不会到其他组件去,而是当前的页面变化//之所以需要这样,因为手动的添加路由,会以最上层的挂载点包括,其他挂载不可进入//使得基本不可以路由里加路由,所以需要子路由//组件的组件使用时,最里面的会自动识别name:"course",component:Course}]}
]const router = new VueRouter({routes
})//相当于这样文件的对外数据是这个,而不是文件了
export default router
import Vue from 'vue'
import App from './App.vue'
import router from './router'//导入element-UI组件,无需路径
//导入组件库
import ElementUI from 'element-ui'
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css'
//配置Vue插件 将El安装到Vue上,有些不用,全局的(但导入的基本上都会使用use,当然也有例外,如axios,自动全局)
//实际上是install的名称在作用,具体去百度
Vue.use(ElementUI);//上面的导入的不是对应的js,不是js文件,而是所有的整体//引入axios
import axios from 'axios'
//Vue对象使用axios,给vue添加属性,因为这里都是使用vue来操作的,添加属性好操作
Vue.prototype.axios = axios;Vue.config.productionTip = falsenew Vue({router, //这里使得对应this的axios使用render: h => h(App)
}).$mount('#app')
<template><div id="app"><!-- 根据访问路径,渲染路径匹配到的组件--><router-view></router-view></div>
</template><style></style>
组件与页面:页面相当于java程序,而组件相当于java程序的方法,在多个操作同样的时候,我们可以封装起来,从而实现复用
组件与页面的优缺点:
组件:可以复用且基本异步,但是在少数的代码中,代码量比页面要大
页面:少数的代码中代码量比组件下,且代码不复杂,容易理解
但最终的结果,还是会趋向于组件化
之所以有端口,node.js环境的问题,使得和服务器类似的监听和存放,而访问数据,即创建的vue项目(类似于服务器的操作)
jdk是一个环境,而tomcat是一个资源访问,那么node.js也就是一个环境,而vue脚手架也就是资源访问
node.js是js运行环境(必须要有这个环境,因为很多js需要执行,如脚手架的路由操作,以及导入组件等等,而不用使用浏览器)
npm包操作,vue脚手架资源访问,npm使用操作vue脚手架(实际上就是资源的分配)进行访问(运行)
出现一个浏览器(因为node.js)
可以理解为:
node.js是java的jdk
npm是java的pom.xml
vue-cli是java的maven
Postman搭建mock server:
Mock server就是模拟一个服务器,我们使用Mock server可以模拟后台接口,对请求进行响应
在前后端分离的开发中 前端利用mockeserver模拟出对应接口,拿到返回数据来调试,无需等后端开发人员完成工作
postman模拟出一个server 步骤:
使用postman模拟出一个server

打开如下窗体,创建一个伪服务:
第一步:

第二步:

关闭后,就会出现一个地址,这个地址是postman提供给我们的,相当于他给我们创建一个Servlet
vue脚手架自带保存代码刷新浏览器功能(隐式的刷新)
前端路由出现后,为什么需要后端来操作
第一:数据库的存储,不可能不存储数据,即必须要后端
第二:前端路由都在一个页面,即当需要跳转到一个全新的页面时,就需要非常多的组件合并,并不好,所以需要后端跳转
或者前端跳转(但没有对应数据,如存放的id等),比如网站的直播功能和视频功能
所以路由一般用在类似于视频页/推荐页/搜索页之间
跨域问题解决:
出现跨域问题:
当我们在前端项目中,向后端发送请求的获取课程数据的时候,出现了跨域问题:
已被CORS策略阻止:请求的资源上没有’ Access-Control-Allow-Origin’标头(跨域请求失败)

什么是跨域:
跨域是指通过JS(注意是js)在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据时
只要协议、域名、端口有任何一个不同,都被当作是不同的域,浏览器就不允许跨域请求,因为端口之间没有道路(被封锁)
否则的话,会影响端口之间的运行,以及数据的不安全性,所以要想有跨域,我们需要开辟道路,所以基本只有浏览器的操作是出现跨域的,这是浏览器为了保证安全而进行了操作,即跨域基本只出现在浏览器之间,是浏览器为了安全,而产生的属性
之所以这样:是由于浏览器实现的同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源
因为无论的什么js请求,都是XmlHttpRequest的操作或者类似的操作
所以AJAX或者用到这些对象的是不允许跨域的
不过像< script>,< link>,< img>,< iframe>这些标签一般(并不绝对,比如< iframe>标签)是允许跨域的
也许还有其他标签可以跨域,他们都基本是设置可以跨域的
但你并不能修改这些资源,比如iframe里的内容
举个例子:
若可以跨域或者修改对应网站(修改若可以,那么基本想怎么操作就可以怎么操作了),那么就可以有如下操作
比如一个黑客,他利用iframe把真正的银行登录页面嵌到你访问的页面上或者他伪造的银行登录页面(这里是最主要的)
当你使用真实的用户名和密码登录时,如果没有同源限制
他就可以通过JavaScript读取到你的表单中输入的内容,通过js进行发送到电脑上
如自己电脑准备服务器,接收两个参数,为账户密码
通过js获得表单数据,使用ajax发送地址,传入账号密码作为参数,接收到数据库里
这样用户名和密码就轻松到手了,因为可以跨域(修改一般不可能做到)
所以浏览器中有跨域的操作,也是为了安全,也就是说,跨域使得不是所有的页面,你都可以得到的,比如银行登录页面
跨域的几种常见情况:

解决跨域问题:
跨域的允许主要由服务器端控制,即道路被封锁,如百度就可以跨域,当然浏览器跨域是我们自己进行控制跨域的(浏览器控制)
只是他们基本都支持跨域,少部分需要我们进行设置支持(设置后才可跨域,虽然服务器端允许了,但前端却也要设置支持才可,否则不会跨域),而正是因为少部分需要我们设置,所以说基本看服务器的跨域允许
因为标签的缘故和一些属性等等,可以使得他们进行跨域,这也是为了防止这些危险的标签从而使得我们操作了危险的网站
这是一个浏览器的一个防护,当然还有很多防护,就不依次说明了
之所以是这样,是因为跨域时,我们的请求其实是发送过去的,主要是响应中的数据,决定是否允许跨域,即可以说是服务端控制
服务器端通过在响应的 header 中设置 Access-Control-AllowOrigin及相关一系列参数,提供跨域访问的允许策略
设置响应头中的参数来允许跨域域请求:
Access-Control-Allow-Credentials
Access-Control-Allow-Origin 标识允许跨域的请求有哪些
在POM文件中引入依赖:
<!-- 解决跨域问题所需依赖 -->
<dependency><groupId>com.thetransactioncompany</groupId><artifactId>cors-filter</artifactId><version>2.5</version>
</dependency>
在web.xml中 配置跨域 filter:
<!--配置跨域过滤器--><filter><filter-name>corsFilter</filter-name><filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class></filter><filter-mapping><filter-name>corsFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
<!-- 会帮我们在响应头那里加上上面的参数,使得可以跨域-->
<!--注意:他只是设置了谁能跨域,如果是不跨域的请求,自然无论这里是否操作了对应的谁放行,都可以访问
因为是不跨域的,即本项目可以认为有两个参数,a和b
跨域(不是本项目)的地址只有一个参数,即b,只要a和b其中一个满足
就能访问,所以如果本项目跨域(相同的没有跨域)设置了部分放行,没有放行的因为a是成立的,所以还是可以访问
而其他不是本项目的(地址),则只能满足b,即只能放行的可以访问了,一般如果不操作配置,默认可以认为是全部不放行的-->
再次查询:
解决跨域问题之后,页面显示数据
<template><el-container><el-header>后台管理</el-header><el-container><!-- 侧边栏--><el-aside width="200px"><el-menu default-active="2" class="el-menu-vertical-demo" background-color="#D3DCE6" router ><!-- 添加上router就以下面的index的路径为准--><el-submenu index="1"><template slot="title"><i class="el-icon-location"></i><span>导航菜单</span></template><el-menu-item-group><!-- 修改index的路由地址--><el-menu-item index="/course"><i class="el-icon-location"></i>课程管理</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><!-- 主要区域--><el-main><router-view></router-view></el-main></el-container></el-container>
</template><script>
export default {};
</script><style scoped>
.el-container {height: 725px;
}
.el-header,
.el-footer {background-color: #b3c0d1;color: #333;text-align: center;line-height: 60px;
}.el-aside {background-color: #d3dce6;color: #333;text-align: center;line-height: 200px;
}.el-main {background-color: #e9eef3;color: #333;text-align: center;line-height: 30px;
}
</style>
<template><!-- 注意:Element-UI的样式和组件,以及相应的属性可以添加到可以操作的地方
如官网中不同的地方的属性可以可以给对应其他地方的组件进行作用,因为都是作用与组件--><div><el-row :gutter="20"><!-- 默认一个格子占满24个分栏,:span="6",即一个格子占满6个分栏,从左边开始--><el-col :span="6"><el-input placeholder="课程名称" prefix-icon="el-icon-search"v-model="filter.course_name" clearable></el-input></el-col><el-col :span="1"><el-button type="primary" @click="search">点击查询</el-button></el-col></el-row><el-tablev-loading="loading"element-loading-text="拼命加载中":data="courseList"stripestyle="width: 100%"><el-table-column fixed="left" prop="id" label="ID"></el-table-column><el-table-column prop="course_name" label="课程名称"></el-table-column><el-table-column prop="price" label="价格"></el-table-column><el-table-column prop="sort_num" label="排序"></el-table-column><el-table-column prop="status" label="状态"></el-table-column></el-table></div>
</template>
<script>
export default {data() {return {courseList: [{id: 1,course_name: "Java",price: 88.8,sort_num: 1,status: "下架"}],loading: true,filter:{course_name:""}};},//定义钩子函数created,在dom页面生成之前执行created() {//再页面生成之前,调用loadCourse()this.loadCourse();},methods: {//获取课程信息loadCourse() {alert("loadCourse方法执行了");//发送请求获取数据const url = "http://localhost:8080/lagou_edu_home/course";return this.axios.get(url, {params: {methodName: "findCourseList"}}).then(res => {console.log(res.data);//将获取到的数据 赋值给courseListthis.courseList = res.data;//axios返回的响应体里,有很多数据,对应返回的是data数据//取消加载动画this.loading = false;}).catch(error => {this.$message.error("获取数据失败");//从上向下的显示});},//根据课程名查询search(){//重新开启加载提示this.loading = true;//发送请求const url = "http://localhost:8080/lagou_edu_home/course";return this.axios.get(url,{ //只要是get,就一定是先将对应参数放在url,然后再放在请求体中params:{methodName:"findByCourseNameAndStatus",course_name:this.filter.course_name //这个this没错,因为是当参数的,不用以为调用者变了}}).then((res) => {console.log(res.data)this.courseList = res.data//关闭加载this.loading = false}).catch((error) => { //其中(error),可以写成error,即一个参数的话,可以不写括号this.$message.error("获取失败")})}}
};
</script><style>
</style>
ok到这里,就说明一下导入和导出
其实就是让导入的代码检查到这里,并使用对应的变量,所以导入的变量,也可以使用该变量所在js的变量
就如java里的方法可以使用自己方法变量,所以导入者也就可以使用他所在的变量,而我们导入的只是可以跨js使用而已
即使用他的东西,并用变量保存他们,这个保存的变量就是被导入的变量,可以操作两边的js,看成类似于java的方法即可
换言之,就是层级提高了的变量,简称为借用或借用操作(export default和import)

58-Vue高级实战相关推荐

  1. 今天,学会这几个Vue高级实战技巧就够了!

    前言 今天,我们来分享几个不可不知的vue高级实战技巧. 技巧 自动注册组件 我们平时可能这样引入注册组件.每次都得需要在头部引入,然后注册,最后在模板上使用. <template>< ...

  2. axios vue 动态date_Web前端Vue系列之-Vue.js 实战

    课程简介: 课程目标:通过本课程的学习,让大家掌握Vue.js的进阶知识并在项目中应用. 适用人群:具有一定vue开发基础的开发人员. 课程概述:Vue (读音 /vjuː/,类似于 view) 是一 ...

  3. 《Vue.js实战》第七章.组件

    7.1 组件作用: 提高代码复用性,使项目易于维护 7.1 组件的使用 7.1.1 组件注册-全局注册 全局注册后,任何vue的实例都可以使用该组件. Vue.component('my-compon ...

  4. Vue.js实战梁笔记02(第3-5章)

    1.计算属性 当表达式过程的时候,不如使用函数,如何使用函数呢,使用methods是一种,使用计算属性也是一种方式. 所有的计算属性都是以函数的形式卸载vue实例内的computed选项内,最终返回计 ...

  5. [Vue.js] 一篇超级长的笔记,给《Vue.js 实战》划个重点

    本文前言 本笔记建立在书籍<Vue.js实战 / 梁灏编著>的基础上,旨在帮助有 Vue.js 基础的朋友快速回忆 Vue.js 的细碎内容.初学者建议阅读<Vue.js实战> ...

  6. 《Vue.js实战》记录

    目录 初识Vue.js 指令 v-html v-pre v-bind v-on v-cloak v-once v-show v-for v-model 自定义指令 全局指令 局部指令 钩子函数 计算属 ...

  7. 08.vue.js实战笔记(计算属性、v-bind及class和style的绑定、内置指令、方法与事件)

    1.计算属性 所有的计算属性都以函数的形式写在vue实例的computed选项内,最终返回计算后的结果 <!DOCTYPE html> <html lang="en&quo ...

  8. 2018最新APP界面设计教程---手机ui高级实战案例 视频教程(价值320元)

    课程简介: 适用人群         适合有基础的学员 学到什么         火星人UI设计培训结合大量的实战案例,从ICON的设计构思开始,到APP界面设计,全方面解析UI设计工作流程和设计理论 ...

  9. Vue.js实战之系统学习第一节

    为什么叫系统学习呢?因为我以前接触过Vue.js,但是没学过它的原理,只是简单的使用了,使用的时候就觉得很好用,没有其他的什么感觉,但当我进入职场后,学习了很多的前端技术后,才发现这个技术的友好,被它 ...

最新文章

  1. Python 计算机视觉(十一)—— OpenCV 图像形态学处理
  2. c++ 预处理命令 #error 用法
  3. 阿里天猫、蚂蚁最全一百多道面试题以及阿里P8架构技能树分享(含答案解析)
  4. 单片机的程序有多大?
  5. 能测试快充真假的软件,苹果iOS 12可自行测试真假快充:山寨充电器将被洗牌
  6. 62 岁的比尔·盖茨当选外籍院士,但却与微软无关
  7. C#字典类型转URL参数字符串
  8. Hadoop3.1.3安装教程_单机/伪分布式配置_Hadoop3.1.3/Ubuntu18.04(16.04)
  9. 手持式频谱分析仪TFN FMT650频谱分析 干扰分析 干扰定位 地图覆盖
  10. 给定经纬度计算距离_根据两点经纬度计算距离!
  11. 天池大数据竞赛项目代码_竞赛以使用开放内容,开放数据或开放源代码开始新项目
  12. 降噪耳机简介及降噪技术-ANC、ENC、DSP、CVC
  13. 如果局域网当中两台电脑互相ping不通
  14. luffcc项目-04-登录防水墙认证(滑动图片验证码)、在登录认证中接入防水墙、前端获取显示并校验验证码
  15. CCF小白刷题之路---201809-1 卖菜(C/C++ 100分)
  16. 【Calcite】Apache Calcite 框架初探及概念详解
  17. python中sep的用法:逗号的去除
  18. Fiddler报文分析-断点应用、模拟网络限速-HTTPS的 拦截
  19. SmallJava V2.0 产品说明书(20210405)
  20. EZ-USB FX2单片机原理、编程及应用 读书笔记

热门文章

  1. Go 语言圣经 练习8.1
  2. 一文详解MySQL的锁机制
  3. 浅谈node中的resolve
  4. Docker ENTRYPOINT 笔记
  5. 计算机等级考试三级嵌入式部分考点整理
  6. 【转】推荐系统和搜索引擎的关系
  7. 安装MS SQL2014 EXPRESS
  8. Python使用科学计数法显示数字的解决方案
  9. 原装苹果手机_华强北二手苹果手机怎么分辨是否原装屏幕呢?
  10. DevExpress GridView 选中单元格文本内容当失去焦点又获得焦点时保持原来的文本选中内容