大前端进阶之路

前言

虽然以前html、js、css三剑客自认为写的挺6,但是好久没接触大前端代码了,同时前端发展的太快了,现在我的前端技术肯定是落后太多了,那么先从环境搭建继续吧,在工作之余学习大前端的语法、工具、框架!希望自己将学到东西一点一点收录到此!

Nodejs

什么是Nodejs?

以前我们编写 js 代码需要从浏览器执行,放在html中!

Nodejs ,就是可以在服务器端运行JS代码! 基于 Coogle 的 V8 引擎,可以脱离浏览器执行 js 代码!性

能较好!

安装Nodejs

官网下载地址:https://nodejs.org/zh-cn

安装前最好装一个python2,保证nodejs的正常使用

安装完毕后,可以看到 node 和 npm 环境!

nodejs与npm环境

Hello Node!

  1. 创建index.js

    console.log('hello node!')
  2. 打开终端,运行js程序

    node 程序名.js

    运行结果

node服务器端开发(简单例子)

  • 编写服务端代码
//导入http模块
const http = require('http')
//创建服务,并监听8080端口,下面是es6的 lambda表达式:()=>,以前写法为:function()
http.createServer((request, response) => {
response.writeHead(200, { 'content-Type': 'text/html' })
response.end('<h2>hello,node server</h2>')
}).listen(8080)
//控制台输出
console.log('server running : http://localhost:8080')
  • 打开终端,运行js程序

运行服务

访问结果

ES6语法

什么是ES6?

  • ES6 = ES2015 = ECMAScript6

  • 一个规范而已! JavaScript 2015年出来的新标准!

  • 大部分现在的前端程序员,都会使用es6进行开发!

let 声明变量

let声明的变量其实就是比var声明更加严格

  • 无法重复声明

    var x = 1
    var x = 1

    let y = 1
    let y = 1

    无法重复声明

  • 有作用域限制

    {
    var x = 1
    let y = 2
    }
    console.log(x)
    console.log(y)

    有作用域限制

  • 不会提升作用域

    console.log(x)
    var x = 1

    console.log(y)
    let y = 2

    不会提升作用域

const 声明常量

ES6以前都是约定俗成var修饰的大写变量为常量,const与java中 final类似:声明常量处一定要赋值,并且之后就不允许在改变!

const PI = 3.141592653589793238462643
PI = 0 // Assignment to constant variable.

const INIT_VALUE // Missing initializer in const declaration

解构赋值

ES6更加优雅的赋值方式

//传统赋值
let a = 1, b = 2, c = 3
console.log('传统赋值:', a, b, c)
//解构赋值
let [x, y, z] = [1, 2, 3]
console.log('解构赋值:',x, y, z)

//定义用户对象
let user = { name: 'hth', age: 18 }

//传统对象赋值
let name1 = user.name
let age1 = user.age
console.log('传统对象赋值:', name1, age1)

//解构对象赋值,变量必须与对象属性同名
let { name, age } = user
console.log('解构对象赋值:', name, age)

解构赋值

对象声明简写

//传统对象声明
let name1 = 'hth1'
let age1 = 18
let user1 = { name: name1, age: age1 }
console.log(user1)

//es6简写 对象属性名会被定义成与变量名相同
let name = 'hth'
let age = 18
let user = { name, age }
console.log(user)

对象声明简写

模板字符串拼接

let name = 'hth'
let age = 18
// 传统的字符串拼接
let message = '我的名字叫:' + name + ',今年' + age + '岁'; // 拼接字符串
console.log(message)
//es6模板字符串拼接
let es6message = `我的名字叫:${name},今年${age}岁`
console.log(es6message)

模板字符串拼接

方法定义简写

const person = {
sayHi: function () {
console.log('传统方法定义~')
}
}

person.sayHi()

const es6Person = {
sayHi() {
console.log('es6方法定义~')
}
}
es6Person.sayHi()

对象拓展运算符(深度拷贝)

let user = { name: 'hth', age: 18 }
//复制引用
let userCopyReference = user
//修改名称
userCopyReference.name = '666'
console.log('原对象', user.name)
console.log('复制引用后的新对象', userCopyReference.name)

//对象深度拷贝
let user1 = { name: 'hth', age: 18 }
let userCopyProperty = { ...user1 }
//修改名称
userCopyProperty.name = '666'
console.log('原对象', user1.name)
console.log('深度拷贝后的新对象', userCopyProperty.name)

深度拷贝

匿名箭头函数(Lambda表达式)

const f1 = function () {
console.log('传统匿名函数')
}
f1()

const f2 = () => {
console.log('es6箭头函数')
}
const f3 = (str) => console.log(str)
f2()
f3('如果只有一行代码,可省略{}')

匿名箭头函数

函数的默认参数

const print = (name = 'hth', age = 18) => console.log(`我的名字叫:${name},今年${age}岁`)
print('xxx', 20)
print('xxx')
print()
print('xxx', null)
print('xxx', undefined)

函数的默认参数

NPM 包管理

  • 我们安装nodejs时,自动帮我们安装了npm环境!

npm版本

什么是npm?

NPM的全称是Node Package Manager,是一个NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准。

就好比maven,所有东西只要到导入依赖即可,npm 也是如此,npm install,好比Linux 的 yum install!

初始化npm包目录

  • 在自己的项目目录下执行:
npm init     # 初始化的过程会让你填写你项目的信息,如name、version、description、author等
# 或者
npm init -y # 直接生成默认值
  • 生成了一个package.json,如同pom.xml

package.json

修改npm镜像

# 查看npm的配置信息 
npm config list
# 执行以下配置,可以让所有的依赖通过淘宝的仓库下载,速度会比较快!
npm config set registry https://registry.npm.taobao.org/

安装/更新依赖包

  • 安装

    npm install 依赖包[@x.x.x] #不带版本号默认最新版本
  • 指定只在开发中使用的依赖

    npm install --save-dev(等价于 -D) 依赖包[@x.x.x]
  • 全局环境安装

    npm install -g 依赖包[@x.x.x]
  • 更新

    npm update 依赖包[@x.x.x] #不带版本号默认最新版本
  • 卸载

    npm uninstall 依赖包
  • 示例

安装依赖包

注意事项

  • 安装依赖后,会生成node_modules目录,此文件夹一般文件非常多并且非常大,在开发中提交时记得排除,写在.gitignore中!

node_modules

  • 每次更新到源码后,因为有package.json文件记录了依赖的信息,所以我们直接npm install即可!

npm脚本

在真实开发中,打包、发布、部署等一系列的操作编辑成script,进行一键处理!

  1. 打开package.json

    scripts

  2. 在scripts中,添加脚本

    {
    "dev": "pwd && echo '正在打包...' && echo '正在部署...' && echo '部署完毕!'"
    }
  3. 运行脚本

    npm run dev

    运行脚本

Babel ES6转码器

因为很多se6高级语法,浏览器是不支持的, Nodejs也不一定能运行!

所以我们需要进行转码操作!

Babel 是一个广泛的转码器!可以将 ES6代码转换为 ES5的代码! 语法会自动转换!

安装Babel

# 安装
npm install -g babel-cli
# 查看版本
babel --version

查看版本

使用Babel

  • 我们在src目录下编写js源代码,输出目录在dist

  • 编写.babelrc配置文件

    {
    "presets":[
    "es2015"
    ],
    "plugins": []
    }
  • 安装babel依赖

    npm install -D babel-preset-es2015
  • 将一个文件转码到另一个文件

    babel src/es6.js --out-file dist/es6.js
    # 或者
    babel src/es6.js -o dist/es6.js

    转码

  • 将一个目录下所有文件转码到另一个目录

    babel src --out-dir dist
    # 或者
    babel src -d dist

    目录转码

小技巧

可以将转码操作写在npm scripts中!

模块化

随着js代码越来越大!js产生了两种模块化规范:

  • CommonJS规范
  • ES6模块化规范

CommonJS规范

  • 编写一个模块math.js

    const sum = (a, b) => a + b

    const sub = (a, b) => a - b

    const mul = (a, b) => a * b

    const di = (a, b) => a / b

    // 导出这些方法供他人使用!
    // 如果名称相同,可以简写
    module.exports = { sum, sub, mul, di }
  • 使用模块

    const math = require('./math')

    console.log(math.sum(2, 3))
    console.log(math.sub(2, 3))
    console.log(math.mul(2, 3))
    console.log(math.di(2, 3))

    使用模块

ES6模块化规范

  • 编写一个模块es6_module.js

    // 第一种写法
    export function getList() {
    console.log('用户列表')
    }
    export function save() {
    console.log('保存用户')
    }
    // 第二种写法
    export default {
    delete() { console.log("删除一个用户") },
    get() { console.log("查询一个用户") }
    }
  • 使用模块

    //第一种写法的导入
    import { getList, save } from './es6_module'
    getList()
    save()
    //第二种写法的导入
    import user from './es6_module'
    user.delete()
    user.get()
  • 注意,node目前不支持import语法,所以我们必须使用Babel进行语法转义

  • 转义后执行

    转义后执行

Webpack

什么是Webpack?

Webpack 是一个前端的资源打包工具!

js css less png ———-> .js

安装与使用

  • 安装

    npm install -g webpack webpack-cli
    # 查看版本
    webpack -v
    webpack-cli -v

    安装

  • 新建webpack.config.js

    //用于当前目录解析
    const path = require('path')

    module.exports = {
    //打包的主文件
    entry: './src/test_module.js',
    output: {
    //输出路径
    path: path.resolve(__dirname, './dist'),
    //输出文件名
    filename: 'bundle.js'
    }
    }
  • 打包

    webpack --mode=development

    image-20200329153923598

  • 运行bundle.js

    运行bundle.js

总结

Webpack打包出来只有一个文件,并且可以直接使用,无需经过es6转码,并且代码极其难读,可以防止别人窥探源码

bundle.js

webpack.config.js详细配置

  • 从互联网上摘抄的详细配置,留着未来按需参考!
const path = require('path');
module.exports = {
//entry表示入口,webpack执行构建的第一步将从entry开始,可以抽象成输入
entry: './app/entry',//只有一个入口,入口只有一个文件
entry: ['./app/entry1','./app/entry2'],//只有一个入口,入口有两个文件夹
entry: { //有两个入口
a: './app/entry-a',
b: ['./app/entry-b1','./app/entry-b2']
},
output: {
//输出文件存放的目录,必须是string类型的绝对路径
path: path.resolve(__diename,'dist'),
//输出文件的名称
filename: 'bundle.js',// 完整的名称
filename: '[name].js',//在配置了多个entry时,通过名称模板为不同的entry生成不同的文件名称
filename: '[chunkhash].js',//根据文件内容的hash值生成文件的名称,用于浏览器长时间缓存文件
//发布到线上的所有资源URL前缀,为string类型
publicPath: '/assets/', //放到指定目录下
publicPath: '', //放到根目录下
publicPath: 'https://cdn.example.com/', //放到CDN上
//导出库的名称,为string类型
//不填它时,默认的输出格式是匿名的立即执行函数
library: 'MyLibrary',
//导出库的类型,为枚举类型,默认是 var
//可以是umd、umd2、commonjs2、commonjs、amd、this、var、assign、window、global、jsonp
libraryTarget: 'umd',
//是否包含有用的文件路径信息生成的代码里,为boolean类型
pathinfoL:true,
//附加chunk的文件名称
chunkFilename: '[id].js',
chunkFilename: '[chunkhash].js',
//jsonp异步加载资源时的回调函数名称,需要和服务端搭配只用
jsonpFunction: 'myWebpackJsonp',
//生成的 Source Map 文件的名称
sourceMapFilename: '[file].map',
//浏览器开发行和工具里显示的源码模块名称
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]',
//异步加载跨域的资源时使用的方式
crossOriginLoading: 'use-credentials',
crossOriginLoading: 'anonymous',
crossOriginLoading: false,
},
module: {
rules: [ // 配置loader
{
test: /\.jsx?$/, //正则匹配命中要使用loader的文件
include: [ // 只会命中这里面的文件
path,resolve(__dirname,'app')
],
exclude: [ //忽略这里面的文件
path.resolve(__dirname,'app/demo-files')
],
use: [ //使用哪些loader,有先后次序,从后向前执行
'style-loader', //直接使用loader的名称
{
loader: 'css-loader',
options: { //向html-loader传递一些参数
}
}
]
},
],
noParse: [ //不用解析和处理的模块
/special-library\.js$/ //用正则匹配
],
},
// 配置插件
plugins: [
],
resolve: {
modules: [ //寻找模块的根目录,为array类型,默认以 node_modules为根目录
'node_modules',
path.resolve(__dirname,'app')
],
extensions: ['.js','.json','.jsx','.css'], //模块的后缀名
alias: { //模块别名配置,用于映射模块
//将‘module’映射成‘new-module’,同样,‘module/path/file’也会被映射成‘new-module/path/file’
'module': 'new-module',
//使用结尾符号$后,将‘only-module’映射成‘new-module’,
//但是不像上面的,‘module/path/file’不会 被映射成‘new-module/path/file’
'only-mosules$':'new-module',
},
alias: [ //alias还支持使用数组类更详细地进行配置
{
name: 'module', //老模块
alias: 'new-module', //新模块
// 是否只映射模块,如果是true,则只有‘module’会被映射;如果是false,则'module/inner/path'也会被映射
onlyModule: true
}
],
symlinks: true, //是否跟随文件的软连接去搜索模块的路径
descriptionFiles: ['packsge.json'], // 模块的描述文件
mainFilelds: ['main'], //模块的描述文件里描述入口的文件的字段名
enforceExtension: false, //是否强制导入语句写明文件后缀
},
//输出文件的性能检查配置
performance: {
hints: 'warning', //有性能问题时的输出警告
hints: 'error', //有性能问题时输出错误
hints: false, // 关闭性能检查
maxAssetSize: 200000, //最大文件的大小(单位为bytes)
maxEntrypointSize: 400000, //最大入口文件的大小(单位为bytess)
assetFilter: function(assetFilename) {
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js') ;
}
},
devtool: 'source-map', //配置source-map
context: __dirname, //webpack使用的根目录,string类型必须是绝对路径
// 配置输出代码的运行环境
target: 'web', //浏览器,默认
target: 'webworker', //WebWorker
target: 'node', //Node.js使用`require`语句加载 Chunk代码
target: 'async-node', //Node.js异步加载 Chunk代码
target: 'node-webkit', // nw.js
target: 'electron-main', // electron,主线程
target: 'electron-renderer', // electron,渲染线程
externals: {
jquery: 'jQuery'
},
status: { //控制台输出日志
assets: true,
colors: true,
errors: true,
errorDetails: true,
hash: true,
},
devServer: { // DevServer相关的配置
proxy: { // 代理到后端服务接口
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname,'public'), //配置 DevServer HTTP服务器的文件根目录
compress: true, //是否开启Gzip压缩
historyApiFallback: true, //是否开发 HTML5 History API 网页
hot: true, //是否开启模块热替换功能
https: false, // 是否开启 HTTPS 模式
},
profile: true, //是否捕捉webpack构建的性能信息,用于分析是什么原因导致构建性能不佳
cache:fasle, // 是否启用缓存啦提升构建速度
watch: true, //是否开始
watchOptions: { // 监听模式选项
// 不监听的文件或文件夹,支持正则匹配。默认为空
ignored: /node_modules/,
// 监听到变化后,等300ms再执行,截流,防止文件更新太快导致重新编译频率太快,默认为300ms
aggregateTimeout: 300,
// 不停地询问系统指定的文件有没有发生变化,默认每秒询问1000次
poll: 1000
},
}

JavaScripst 框架

Vue

摘自Vue官网:https://cn.vuejs.org/

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,

Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库

或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复

杂的单页应用提供驱动。

编写第一个vue程序

  1. 下载vue.js

    npm install vue
  2. 新建html、编写视图层 (使用vue的插值表达式 )

    <div id="app">
    {{message}}
    </div>
  3. 编写Vue对象

    <script src="../lib/vue.js"></script>
    <script>
    let vue = new Vue({
    el: '#app',
    data:{
    message:'Hello Vue!'
    }
    })
    </script>
  4. 打开html

    打开html

    访问结果

基本指令

写一个完整的前端需要的6要素对应vue的基本指令:

  • 视图 v-bind (HTML + CSS)

  • 事件 v-on (JS)

  • 判断 v-if

  • 循环 v-for

  • 双向绑定 v-model 表单中的常用标签都可以进行绑定!

  • 通信 (vue是专注于视图层的框架,通信是没有的,推荐我们使用axios

v-bind

  • 顾名思义:绑定,标签属性和一个数据绑定,数据改变时,view同时发生改变!

    1. 我们将input标签title绑定message属性
    <div id="app">
    <input type="text" v-bind:value="message">
    </div>
    1. 正常显示message的值

      message

    2. 使用浏览器开发者工具修改message的值,发现视图view与数据同步更新了!这就是v-bind的作用!

      修改model后

  • 因为在vue中使用非常频繁,所以可简写为::

    <div id="app">
    <input type="text" :value="message">
    </div>

v-if

  • 这还用解释吗,条件成立则渲染,否则忽略不渲染!

  • 除了v-if还伴随着v-else-ifv-else

    1. 将h2标签判断数据type是否等于A、B、C

      <div id="app">
      <h2 v-if="'A'==type">A</h2>
      <h2 v-else-if="'B'==type">B</h2>
      <h2 v-else-if="'C'==type">C</h2>
      <h2 v-else>Other</h2>
      </div>
    2. data定义type数据

      data: {
      type: 'A'
      }
    3. 默认当然显示A啦,并且我们同样动态修改type的值,显示的对象就会改变!

      BCD

  • 并且我们在Elements中可得知,并不是使用style=”display: none”的隐藏操作,而是直接不渲染不符合条件的元素

    Elements

v-for

  • 这当然是遍历一个集合咯

    1. 将li标签用v-for绑定一个数据list,并且用插值表达式进行展示

      <div id="app">
      <ul>
      <li v-for="val in list">
      {{val}}
      </li>
      </ul>
      </div>
    2. 定义list数据

      data: {
      list: ['张三', '李四', '王五']
      }
    3. 打开html,一切如此简单~

      v-for

v-on

  • 这个指令可以让我们的标签绑定一个具体的事件

    1. 定义一个按钮,并且用v-on绑定click点击事件

      <div id="app">
      <button v-on:click="showMessage">点我</button>
      </div>
    2. 定义一个方法,注意要定义在vue的methods属性下,我们在方法中用this拿到message进行消息弹窗

      let vue = new Vue({
      el: '#app',
      data: {
      message: 'Hello Vue!',
      list: ['张三', '李四', '王五']
      },
      methods: {
      showMessage() {
      alert(this.message)
      }
      }
      })
    3. 测试

      v-on

  • v-on也可以简化为:@

    <div id="app">
    <button @click="showMessage">点我</button>
    </div>

v-model

  • v-model指令可以指定一个属性进行双向绑定,不仅改变model时view会同步改变,而且改变view时model也会同步改变,这个指令使用场景一般在表单中,下面来体验一下

    1. 我们定义一个v-model的input用来修改视图,再定义一个v-bind的input用来观察数据的改变

      <div id="app">
      <input type="text" v-model:value="message">
      <input type="text" v-bind:value="message">
      </div>
    2. 直接打开html,并且修改v-model的值,我们发现v-bind的值也被更新了!这说明我们修改view的值同步到了model,而第二个输入框因为绑定了message的值,监听到了model的改变,所以也同步修改了它的view

      v-model

vue 的生命周期

vue 的生命周期

生命周期钩子函数

  • 钩子函数就是在做某些事件的时候去调用的函数

不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())

因为箭头函数并没有 thisthis 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致

Uncaught TypeError: Cannot read property of undefined

Uncaught TypeError: this.myMethod is not a function 之类的错误。

官方钩子执行时机图

  • 可执行以下钩子函数,查看各对象的初始化情况
,beforeCreate() {
console.group('beforeCreate 创建前状态===============》');
console.log("%c%s", "color:red" , "el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //undefined
console.log("%c%s", "color:red","message: " + this.message)
},
created() {
console.group('created 创建完毕状态===============》');
console.log("%c%s", "color:red","el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeMount() {
console.group('beforeMount 挂载前状态===============》');
console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
mounted() {
console.group('mounted 挂载结束状态===============》');
console.log("%c%s", "color:red","el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeUpdate() {
console.group('beforeUpdate 更新前状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
updated() {
console.group('updated 更新完成状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
beforeDestroy() {
console.group('beforeDestroy 销毁前状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
destroyed() {
console.group('destroyed 销毁完成状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message)
}

输出结果

mounted
  • mounted一般用来页面初始化时加载数据,比如调用网络框架ajax、axios从后端拿到数据或者直接使用mock数据
  • 我们将data中的list设置为null,在mounted()中进行list的初始化
let vue = new Vue({
el: '#app',
data: {
list: null
},
mounted() {
this.list = ['张三', '李四', '王五']
}
})
  • 同样访问的结果没有任何问题

访问结果

axios

  • axios与ajax一样是一个网络通讯框架,支持链式编程,调用非常方便简洁!

  • axios提供了所有别名方法如:get()、post()、delete()、put()、patch()…

  • 安装,并且引入js

    npm install axios
  • 调用已经写好的api

    @RestController
    @RequestMapping("articles")
    public class ArticleController {
    @Autowired
    private IArticleService articleService;

    @GetMapping("list")
    public List<ArticleBO> list(@RequestParam("id") Long id) {
    ArticlePageVO vo = new ArticlePageVO();
    IPage page = vo.generatePage();
    return articleService.page(page, vo);
    }
    }
    • 注意配置允许跨域访问

      @Configuration
      public class WebConfig implements WebMvcConfigurer {
      /**
      * 设置 cors 跨域支持
      */
      @Override
      public void addCorsMappings(CorsRegistry registry) {
      registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "HEAD", "PATCH", "POST", "PUT", "DELETE", "OPTIONS").allowCredentials(true).maxAge(3600);
      }
      }
let vue = new Vue({
el: '#app',
data: {
list: null
},
mounted() {
axios.get('http://localhost:8080/articles/list', {
params: {
id: 12
}
}).then((response) => {
this.list = response.data
})
}
})
  • 成功渲染:

    渲染api返回的数据

get

axios.get('url')
axios.get('url', { params: { id: 12 } })

post

axios.post('url',{ firstName: 'Fred', lastName: 'Flintstone' })

all

function getUserAccount() {
return axios.get('url');
}

function getUserPermissions() {
return axios.get('url');
}
axios.all([getUserAccount(), getUserPermissions()])

then

调用成功时回调此方法

axios.get('url')
.then(function (response) {
console.log(response);
})

catch

调用失败时回调此方法

axios.get('url')
.then((response) =>{
console.log(response);
})
.catch((error) =>{
console.log(error);
})

vue-cli

什么是vue-cli?

Vue-cli 是官方提供的一个脚手架!可以利用它快速生成前端化的工程模板!

功能:

  • 统一的目录!
  • 快速调试!
  • 单元测试!
  • 在线运行!
  • …….

环境安装

# 第一次安装可能会有些慢!
npm install vue-cli -g

# 检测我们安装的vue的应用
vue list

安装成功

创建前端代码

  • 在自己的目录下,创建一个基于weboack模板的vue项目!

    vue init webpack myvue
    • 在初始化的过程中,vue-cli会问我们是否生成vue-router、ESLint、单元测试、是否执行npm install等,作为初学者都选择No,自己一步一步集成即可

    初始化vue项目

  • 安装所有依赖 npm install

  • 启动项目 npm rn dev

    访问项目

vue-cli 架构分析

  • 这个是官方推荐的项目结构、并且大部分vue项目都是如此,所以值得我们了解它的运行原理

    vue-cli 目录结构

  • build 和 config webpack 配置文件,项目配置文件
  • node_modules 这个一般在开源项目中都不存在,我们拿到项目的第一步就是 安装所有依赖 (npm install)
  • src 项目的源码目录! (Vue项目 和 js 代码)
  • static 静态资源文件!
  • .babelrc Babel配置文件 (ES6语法转换为 ES5语法!)
  • .editorconfig 编辑器配置
  • .gitignore git文件忽略配置
  • .postcssrc.js css 相关的配置文件,就是导入了css的插件
  • index.html 首页,所有的页面都是通过这里跳转的,实际开发是不使用这个文件的!
  • package.json npm项目的配置文件(名称、版本、描述、作者、依赖、启动脚本 ……)
main.js
// es6语法,导入组件和依赖!
import Vue from 'vue' // vue 依赖
import App from './App' // 导入组件

Vue.config.productionTip = false // 关闭浏览器控制台关于环境的提示!

/* eslint-disable no-new */
// vue的核心对象
new Vue({
el: '#app', // 绑定index.html的节点
components: { App }, // 在模块系统中局部注册组件App
template: '<App/>' // 将该模板指定的标签(这里的标签指定的是components 中定义的组件名)替换#app元素
})
App.vue
  • 此组件代表了我们整个项目的整体面貌,一看代码就知道和我们上面看到的首页对应了
<!-- HTML 代码模板 -->
<template>
<div id="app">
<!--一张log图 -->
<img src="./assets/logo.png">
<!--该组件写的是一些a链接 -->
<HelloWorld/>
</div>
</template>

<!--JS 代码 -->
<script>
// JS 代码, 导入我们自己写的模块!
import HelloWorld from './components/HelloWorld'
// 导出对象App,在其他地方导入的话就可以直接使用了!
export default {
name: 'App',
components: {
HelloWorld // 注册组件!
}
}
</script>

<!--CSS 样式: 如果没有加 scoped 就是全局生效,如果增加了就是当前页面的template部分生效!-->
<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

Vue 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为

安装

npm install vue-router

使用

  1. 新建路由的目录与idnex.js,这是我们编写路由的地方

    路由目录

  2. 自定义编写我们的组件HTH.vue

    <template>
    <h2>HTH页面!</h2>
    </template>

    <script>
    export default {
    name: "HTH",
    data() {
    return {};
    }
    };
    </script>

    <style lang="" scoped>
    </style>
  3. 编写路由,注册我们的组件路由地址

    • 因为在webpack中配置了将src解析为@,所以我们可以直接写@/components/HTH,导入组件可以忽略.vue

      @解析

    //导入Vue用来使用路由
    import Vue from 'vue'
    //导入路由组件
    import VueRouter from 'vue-router'
    //指定Vue使用VueRouter插件
    Vue.use(VueRouter)

    import HelloWorld from '@/components/HelloWorld'
    import HTH from '@/components/HTH'

    export default new VueRouter({
    routes: [
    //规则1,主页面跳转到 HelloWorld
    {
    path: '/main',
    component: HelloWorld
    },
    //规则2,hth路径跳转到我们写的HTH组件
    {
    path: '/hth',
    component: HTH
    }
    ]
    })
  4. 在main.js 中配置路由

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

    Vue.config.productionTip = false

    //导入我们编辑的路由
    import router from './router'

    /* eslint-disable no-new */
    new Vue({
    el: '#app',
    //名称相同,不用写 :
    router,
    components: { App },
    template: '<App/>'
    })
  5. 修改App.vue,使用我们配置的路由

    • <router-link to="/main"> 指定跳转地址,其实本质就是a标签
    • <router-view></router-view>跳转的地址内容展现的地方
    <template>
    <div id="app">
    <router-link to="/main">HelloWord</router-link>
    <router-link to="/hth">HTH</router-link>
    <!-- 出口,展现路由内容的地方! -->
    <router-view></router-view>
    </div>
    </template>

    <script>
    export default {
    name: "App"
    };
    </script>

    <style>
    /* 暂时不需要style */
    </style>
  6. 测试,分别点击两个链接,成功跳转

    HelloWorldHTH

细节配置

通配页面
  • 在我们编写路由时,路由会优先匹配精准的,然后匹配通用!所以我们可以将404页面配置为:

    {
    path: '*',
    // 404页面组件
    component: NotFound
    }
路由模式
  • hash: 默认,路径会带 # 号

  • history: 不带 # 号,也就是我们常常看见的网页路由!

    • 参考Vue Router HTML5 History 模式在开发过程中的dev服务器可以正常访问,但是为生产版本提供服务的简单静态服务器将会以404响应,所以生产环境nginx需要如下配置

    • location / {
      try_files $uri $uri/ /index.html;
      }
  • abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

    export default new VueRouter({
    mode: 'history',
    routes: [
    //规则1,主页面跳转到 HelloWorld
    {
    path: '/main',
    component: HelloWorld
    },
    //规则2,hth路径跳转到我们写的HTH组件
    {
    path: '/hth',
    component: HTH
    }
    ]
    })

history

UI 框架

Element-UI

Element-UI 是饿了么出品的基于 Vue.js 的后台组件ui库!

官网:https://element.eleme.cn/#/zh-CN

安装

npm i element-ui -S
  • install简写为i,-S 写入到dependencies对象,-D写入到 devDependencies 对象

element-ui

使用

  • 同样在main.js中指定Vue使用Element-ui

    import Vue from 'vue'
    import App from './App'
    //1.导入element-ui css
    import 'element-ui/lib/theme-chalk/index.css'
    //2.导入element-ui
    import ElementUi from 'element-ui'
    //3.使用element-ui
    Vue.use(ElementUi)

    Vue.config.productionTip = false

    //导入我们编辑的路由
    import router from './router'

    /* eslint-disable no-new */
    new Vue({
    el: '#app',
    //名称相同,不用写:
    router,
    components: { App },
    template: '<App/>'
    })
  • 接下来就是在官网随心所欲取ui组件即可,我第一步是让我们的App.vue变得好看,也就是使用容器布局

  • 接着使用了几个element内置的图标,也推荐使用第三方图标库:https://fontawesome.dashgame.com/

  • 以及我们后端小伙伴接触比较多的表单组件

    表单组件

    尝试使用几个组件

  • 最后尝试用了几个组件,ui框架的html、css甚至js都是现成的,拿过来改成自己的dataModel即可使用,非常的方便简单

Vue-element-admin

Vue-element-admin 是一款基于 element-ui的后台管理的集成解决方案 前端脚手架

官网:https://panjiachen.github.io/vue-element-admin-site/zh/

Vue-element-admin

安装

  • 安装集成方案 vue-element-admin:
# clone the project
# 原地址:git clone https://github.com/PanJiaChen/vue-element-admin.git
# 码云,下载速度快,每日更新
git clone https://gitee.com/mirrors/vue-element-admin.git

# enter the project directory
cd vue-element-admin

# install dependency
npm install

# develop
npm run dev

vue-element-admin

  • 安装基础模板 vue-admin-template:
# clone the project
# 原地址:git clone https://github.com/PanJiaChen/vue-admin-template.git
# 码云,下载速度快
git clone https://gitee.com/panjiachen/vue-admin-template.git

# enter the project directory
cd vue-admin-template

# install dependency
npm install

# develop
npm run dev

vue-admin-template

使用

  • 我们一般可以使用vue-admin-templeate进行开发!
  • vue-element-admin 这个完整版的后台脚手架,当做一个工具库!需要什么我们拿来使用即可!
  • 接下来的开发步骤就是:
    1. 编写自己的组件
    2. 注册路由
    3. 对接api

官方深入学习 Vue-element-admin

文章作者: 何同昊
文章链接: http://hetonghao.cn/2020/03/大前端进阶之路/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 何同昊 Blog
支付宝超级火箭🚀
微信超级火箭🚀