54-55、权限控制思路引导(略)
56、权限控制结构搭建(略)
57、权限控制功能实现
58、axios的基本介绍和安装
59、axios的GET和POST请求实例
60、axios的GET和POST请求实例
61、使用axios的this指向问题
62-63、webpack介绍,模块介绍
64-65、webpack的基本使用
65.1、export default
66、webpack的深入使用
67、webpack配置文件
68、css-loader配置
69、webpack插件介绍
70、webpack-dev-server介绍
71、vue-loader介绍和单页组件介绍
54-55、权限控制思路引导(略)
56、权限控制结构搭建(略)
57、权限控制功能实现
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <!--1. 引入vue-router对象 全局的VueRouter对象--> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <script type="text/javascript"> // 2. 让Vue使用该VueRouter创建 Vue.use(VueRouter); var Home = { template:`<p>我是首页</p>` }; var Questionbank = { template:`<p>我是智能题库</p>` }; var Login = { template:` <div> <input type="text" name="username"> <input type="password" name="password"> <input type="button" value="登录" @click=loginHandler> </div> `, methods: { loginHandler(){ //登录后,用户名和密码存储到localStorage,然后跳转到“智能题库” localStorage.setItem('user',{name:this.name, pwd:this.password}); //编程式导航 this.$router.push({path:'/questionbank'}); } } }; // 3. 创建一个路由对象 var router = new VueRouter({ routes:[ { path:'/home', component:Home, }, { path:'/questionbank', component:Questionbank, //给未来的路由做权限控制 meta:{ //为true表示访问该组件需要登录 auth:true } }, { path:'/login', component:Login, }, ] }); //全局的导航守卫, router.beforeEach(function (to, from, next) { // console.log(to); //目标路由,有meta字段 // console.log(from); //原路由,有meta字段 if(to.meta.auth){ //已经登录,就放行 if(localStorage.getItem('user')){ next(); }else { //用户点击了智能题库的导航 该用户未登录,需要让用户登录 next({path:'/login'}); } }else { //如果不调用next那么页面会卡住 next(); } }); /* 需求:用户访问“智能题库”时,要监测用户是否有权限访问智能题库的内容,监测用户是否登录, 如果没有就跳转到登录页面,登录完成后,在localStorage中存用户名和密码,并跳转到 智能题库页面,用户点击“退出”时,在localStorage中删除用户,提示“退出成功”,跳转到登录页面 */ //4. 创建Vue对象 var App={ template:`<div> <router-link to="/home">首页</router-link> <router-link to="/questionbank">智能题库</router-link> <router-link to="/login">登录</router-link> <a href="javascript:void(0)" @click="quitHandler">退出</a> <div id="view"> <keep-alive> <router-view></router-view> </keep-alive> </div> </div>`, methods:{ quitHandler(){ localStorage.removeItem('user'); alert('退出成功'); this.$router.push({path:'/login'}); } } }; new Vue({ el:'#app', template:`<App />`, components:{ App }, router, }) </script> </body>
58、axios的基本介绍和安装
Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。
-从浏览器中创建XMLHttpRequests
-从node.js创建http请求
-支持PromiseAPI
-拦截请求和响应
-转换请求数据和响应数据
-取消请求
-自动转换JSON数据
-客户端支持防御XSRE
axios的get请求:
//为给定ID的user创建请求 axios.get('/user?id=123') .then((response)=> { console.log(response); }) .catch((error)=> { console.log(error); });
axios的post请求:
axios.post('/user',{ firstName: 'fred', lastName: 'flintstone' }) .then((response)=> { console.log(response); }) .catch((error)=> { console.log(error); });
安装:
npm init --yes
npm install axios --save
vue-cli中封装axios方法:
59、axios的GET和POST请求实例
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <script type="text/javascript" src="./node_modules/axios/dist/axios.js"></script> <script type="text/javascript"> var App = { template: `<div> <button type="button" @click="sendAjax">发get请求</button> <button type="button" @click="sendAjaxByPost">发post请求</button> <div v-html="msg"></div> </div>`, data() { return { msg: '' } }, methods: { sendAjax() { axios.get('http://127.0.0.1:8000/') .then(response=> { console.log(response.data); data.msg = response.data; }) .catch(error=> { console.log(error); }); }, sendAjaxByPost() { //后端要urleccode var params = new URLSearchParams(); params.append('name', 'alex'); axios.post('http://127.0.0.1:8000/aa', params) .then(response=> { console.log(response); }) .catch(error=> { console.log(error); }); } } }; new Vue({ el: '#app', template: `<App />`, components: { App }, }) </script> </body>
60、axios的GET和POST请求实例
<body> <div id="app"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script> <script type="text/javascript" src="./node_modules/axios/dist/axios.js"></script> <script type="text/javascript"> /* Vue和axios都是全局的对象 未来axios会成为局部作用域 全局作用域使用:axios.xxx 局部作用域使用:this.$axios */ //挂载;相当于Vue.prototype.$axios = axios;把axios变成局部作用域的,以后可以通过this.$axios访问 Vue.prototype.$axios = axios; // Vue.use(axios); //这个报错,但是很多插件都是这样用的, //配置默认URL axios.defaults.baseURL='http://127.0.0.1:8000'; var App = { template: `<div> <button type="button" @click="sendAjax">发get请求</button> <button type="button" @click="sendAjaxByPost">发post请求</button> <div v-html="msg"></div> </div>`, data() { return { msg: '' } }, methods: { sendAjax() { //访问的时候直接拼接到默认URL上 this.$axios.get('/') .then(response=> { console.log(response.data); data.msg = response.data; }) .catch(error=> { console.log(error); }); }, sendAjaxByPost() { //后端要urleccode var params = new URLSearchParams(); params.append('name', 'alex'); this.$axios.post('/aa', params) .then(response=> { console.log(response); }) .catch(error=> { console.log(error); }); } } }; new Vue({ el: '#app', template: `<App />`, components: { App }, }); </script> </body>
61、使用axios的this指向问题
在框架中function(){...}尽量使用箭头函数()=>{...}的形式
sendAjax() { this.$axios.get('/') .then(response=> { console.log(this.datas); //可以使用。箭头函数,this指向Vue对象 }) .catch(error=> { console.log(this.datas); }); },
sendAjax() { this.$axios.get('/') .then(function (response) { console.log(this.datas); //不能使用。function函数,this指向window对象 要这样用就要在函数外面将_this = this,_this.datas }) .catch(function (error) { console.log(this.datas); }); },
62-63、webpack介绍,模块介绍
webpack:
工作时基本用不到webpack的配置
webpack是对前端资源进行—资源(HTML、css、js、png、font等)打包的工具
写完项目进行代码压缩的工具
1、对前端的资源进行编译打包,例如sass、less等打包为css
拿打包js来说,js有一个入口文件,比如main.js 这个文件依赖了很多其他js文件,
webpack可以从main.js去找其他所有依赖打包为一个js,之后只需要引入这个打包后的js就行了,命令:webpack ./main.js ./xxx.js
2.支持es6模块化
webpack里面有很多loader,解决部分css、js等浏览器兼容性问题
对前端中所有的模块进行打包,输出一个或几个js文件,后续引入这个js文件,上线
模块介绍:
同步,必须顺序执行。如果想执行2.js的代码,必须先执行1.js,2.js的执行依赖于1.js。如果script过多,可能造成白屏
<script>1.js</script>
<script>2.js</script>
<script>3.js</script>
<script>4.js</script>
es6中异步导入模块:必须用webpack打包之后才支持这样使用
例如:app.js中 let name = 'alex' ; export default name;
在main.js中 import app from './app.js' ; console.log(app)
可以看出main.js依赖于app.js
这样直接引入main.js,会报错,必须用webpack打包: `webpack ./main.js ./bundle.js`
引入<script src="./bundle.js"></script>就可以用了
64-65、webpack的基本使用
1.演示webpack对项目进行打包
下载webpack:npm i webpack@3.12.0 -g //@后为版本,可以不加
下载完成后:webpack -v 显示版本表示下载成功
注意:以下代码在3.12.0版本运行成功。高版本或低版本不能保证
目录结构:
index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--main.js是入口,依赖了app.js的一个变量,所以要先加载app.js, 否则main.js获取不到这个变量。用script方式是同步的,一行一行执行--> <!--<script type="text/javascript" src="app.js"></script>--> <!--<script type="text/javascript" src="main.js"></script>--> <!--如果main.js中要使用import模块化语句就必须用webpack把main.js打包为bundle.js--> <script type="text/javascript" src="bundle.js"></script> </body> </html>
main.js
/* import obj from './app.js' console.log(obj); //{name: "alex"} import {age,fav,add} from './app.js' console.log(age); //23 console.log(fav); //上班摸鱼 add(); //add方法 */ // 以上也可以直接用对象抛出 // main.js中用到了app.js中的对象 import * as o from './app.js' console.log(o); /* {default: {…}, __esModule: true, add: ƒ} add: ƒ add() age: (...) default: name: "alex" __proto__: Object fav: (...) __esModule: true get age: ƒ () get fav: ƒ () __proto__: Object * */
app.js:
let obj={ name:'alex' }; // 一个js就是一个模块,如果想把一个js中的变量或函数抛出去,让另一个js引用, // 需要将变量用export{xx}抛出,在另一个模块用import xx from 'x.js'导入 // 这时候在入口文件中用<script src='main.js'></script>导入就有问题了,会报错:Uncaught SyntaxError // 需要借助webpack进行打包:webpack ./main.js ./bundle.js // 然后引入<script src='bundle.js'></script>这样就没问题了。 // 总之要想使用export import这种模块化的语句,必须用webpack对js进行打包操作 export default obj; let age = 23; export {age} //作为一个key抛出 export var fav = '上班摸鱼'; export function add() { console.log("add方法") }
65-1、export default
Vue 的模块机制
Vue 是通过 webpack 实现的模块化,因此可以使用 import 来引入模块,例如:
此外,你还可以在 bulid/webpack.base.conf.js 文件中修改相关配置:
意思是,你的模块可以省略 ".js",".vue",“.json” 后缀,weebpack 会在之后自动添加上;可以用 "@" 符号代替 "src" 字符串等。
export 用来导出模块,Vue 的单文件组件通常需要导出一个对象,这个对象是 Vue 实例的选项对象,以便于在其它地方可以使用 import 引入。而 new Vue() 相当于一个构造函数,在入口文件 main.js 构造根组件的同时,如果根组件还包含其它子组件,那么 Vue 会通过引入的选项对象构造其对应的 Vue 实例,最终形成一棵组件树。
export 和export default 的区别在于:export 可以导出多个命名模块,例如:
//demo1.js export const str = 'hello world' export function f(a){ return a+1 }
对应的引入方式:
//demo2.js import { str, f } from 'demo1'
export default 只能导出一个默认模块,这个模块可以匿名,例如:
//demo1.js
export default {
a: 'hello',
b: 'world'
}
对应的引入方式:
//demo2.js
import obj from 'demo1'
引入的时候可以给这个模块取任意名字,例如 "obj",且不需要用大括号括起来。
66、webpack的深入使用
目录结构:
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> </div> <!--webpack把main.js打包为bundle.js--> <script type="text/javascript" src="bundle.js"></script> </body> </html>
app.js
var App={ template:`<div>我是一个组件</div>` }; export {App}
main.js
import Vue from './vue.js' import * as o from './app.js' var app = new Vue({ el:'#app', template:'<App />', components:{ App:o.App } });
效果:
<body>
<div>我是一个组件</div>
<!--webpack把main.js打包为bundle.js-->
<script type="text/javascript" src="bundle.js"></script>
</body>
每次修改了代码都需要在终端里执行命令:webpack ./main.js ./bundle.js
这样就很繁琐,如何解决呢?
在项目目录下执行命令:
npm init --yes
npm i webpack@3.12.0 -D
新建webpack.config.js文件
webpack.config.js
module.exports={ //entry入口 //output出口 entry:{ main:'./main.js' }, output: { filename: "./bundle.js" } };
这样:在项目目录下执行`webpack`命令,就按配置文件执行,相当于`webpack ./main.js ./bundle.js`
也可以执行`npm run dev` ,相当于`webpack ./main.js ./bundle.js`
以上,是生产环境的配置:写好之后用`npm run dev`编译后使用。
开发环境使用就不方便,因为改点东西就编译很麻烦。可以让webpack监听代码的改变,即时编译
写上"watch: true" 执行`webpack`命令后,服务器会进入监听状态(卡住),代码有任何变化都会体现在浏览器上
67、webpack配置文件
webpack可以使用几套配置文件,生产环境一套配置文件,开发环境一套配置文件
68、css-loader配置
使用webpack可以像模块那样去使用.js文件,那么.css文件也可以像模块那样去使用。前提是配置css-loader
效果:
项目下新建main.css文件
在main.js中导入css(为什么在js中导入css?因为main.js是webpack进行模块化的入口文件,模块化为bundle.js过程中,import './main.js' 相当于在 index.html的<head>标签中引入了该css)
执行`webpack ./main.js ./bundle.js`实现页面变红的效果,需要按以下方法配置css-loader
1.先在项目目录下执行命令下载loader:
npm install css-loader -D;npm install style-loader -D
2.webpack配置文件中配置css-loader:
module.exports={ //entry入口 //output出口 entry:{ main:'./main.js' }, output: { filename: "./bundle.js" }, watch: true, //模块中的loader加载器,有多种loader,例如 //css json png jpg mp3 mp4 es6的js代码等 module: { loaders: [ { test: /.css$/, //css后缀的文件 loader: 'style-loader!css-loader' //使用的loader } ] } };
效果:
69、webpack插件介绍
为了使整个目录结构层次分明,
可以将./bundle.js 放在./dist/bundle.js目录里。在编译的时候可以在webpack配置文件中进行设置,还可以参照给定的index.html在编译时
生成./dist/index.html, 目录结构是这样的:
这个插件的作用是,项目上线时,执行`webpack`命令后,自动生成 ./dist/bundle.js和 ./dist/index.html
1.下载插件:npm install html-webpack-plugin -D
2.配置文件webpack.config.js:
//nodejs中内容模块 var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports={ //entry入口 //output出口 entry:{ main:'./main.js' }, output: { path:path.resolve('./dist'), //相对路径转绝对路径 filename: "./bundle.js" }, watch: true, //模块中的loader加载器,有多种loader,例如 //css json png jpg mp3 mp4 es6的js代码等 module: { loaders: [ { test: /.css$/, //css后缀的文件 loader: 'style-loader!css-loader' //使用的loader } ] }, //插件 plugins: [ new HtmlWebpackPlugin({ //参照这个index.html在./dist目录下生成新的index.html template: './index.html', }) ] };
还有个http-server插件可以模拟服务器访问:
1.安装插件:`npm install -g http-server`
2.使用方法-进入dist目录执行命令:`hs -o -p 9999`
70、webpack-dev-server介绍
如果希望执行完`npm run dev`就看到浏览器页面,需要安装webpack-dev-server插件
安装这个插件的作用:
1.要测试代码,执行完命令`npm run dev`就打开浏览器
2.修改完代码,不需要手动刷新页面,代码一保存,效果就自动反应到浏览器
1.下载安装插件:npm install webpack-dev-server@2.9.0 -D //高版本可能不好使
2.修改package.json配置:
{
"name": "webpack_lesson",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"dev": "webpack-dev-server --open chrome --hot --inline --config ./webpack.dev.config.js",
"build": "webpack --config ./webpack.prod.config.js",
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^3.2.0",
"html-webpack-plugin": "^3.2.0",
"install": "^0.13.0",
"style-loader": "^1.0.0",
"webpack": "^3.12.0"
}
}
3.执行:`npm run dev`
71、vue-loader介绍和单页组件介绍
PS:vue模板只能有一个根对象,你得用一个div来或是别的标签来包裹全部的元素,把子组件全部包裹在父组件内,不然报错
之前定义组件的方式不美观,用.vue文件进行规范化, 使用vue-loader将.vue解析为.js
vue-loader作用是将.js文件用.vue的写法代替
1.安装插件:npm install vue-loader@14.1.1 vue-template-compiler@2.5.17 vue@2.5.17 -D //版本要配套。vue跟vue-compiler版本不配套也要报错
2.配置loader在webpack.config.js中:
//nodejs中内容模块 var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports={ //entry入口 //output出口 entry:{ main:'./main.js' }, output: { path:path.resolve('./dist'), //相对路径转绝对路径 filename: "./bundle.js" }, watch: true, //模块中的loader加载器,有多种loader,例如 //css json png jpg mp3 mp4 es6的js代码等 module: { loaders: [ { test: /.css$/, //css后缀的文件 loader: 'style-loader!css-loader' //使用的loader }, { test:/.vue$/, loader:'vue-loader' } ] }, //插件 plugins: [ new HtmlWebpackPlugin({ //参照这个index.html在./dist目录下生成新的index.html template: './index.html', }) ] };
main.js
import Vue from './vue.js' import App from './App.vue' var app = new Vue({ el:'#app', template:'<App />', components:{ App } }); //导入css import './main.css'
App.vue
<!-- 之前的方式App.js: export default { template:`<div>我是一个组件</div>` }; --> <!-- 换成App.vue后 组件结构 业务逻辑 组件样式 --> <template> <div> <h1 @click="clickHandler">{{msg}}</h1> <Header /> </div> </template> <script> import Header from './Header.vue' export default{ data(){ return { msg:'单页面组件' } }, methods:{ clickHandler(){ alert(this.msg); } }, components:{ Header } } </script> <!-- 不加scoped:表示全局样式,当前模板和其子模板生效 加scoped:表示局部样式,只在当前模板生效 --> <style scoped> h1{ color: white; } </style>
Header.vue
<template> <div> <h1>{{desc}}</h1> </div> </template> <script> export default{ data(){ return { desc:'我是Header组件' } } } </script> <style scoped> h1{ color: green; } </style>
main.css
body{ background-color: red; } h1{ color: blue; }