HTML

Hyper Text Markup Language 超文本语言,并非编程语言,而是标记语言,使用标记标签描述网页

Web标准

  • 结构 HTML 页面元素和内容
  • 表现 CSS 网页元素外观和位置等页面样式
  • 行为 JavaScript 网页模型定义与页面交互
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>教程</title>
</head>
<body>
    <h1>我的第一个标题</h1>
    <p>我的第一个段落</p>
    <a href="http://www.runoob.com">这是我的第一个链接</a>
    <br />
    <img src="/images/logo.png" width="258" height="28" />
    <br />
    <b>加粗文本</b>
    <br />
    <i>斜体文本</i>
    <br />
    <p>这是<sub>下标</sub></p>
    <p>这是<sup>上标</sup></p>
    <p>My favorite color is <del>blue</del> <ins>red</ins>!</p>
    <br />
    <br />
    <br />
    <br />
    <br />
    <br />

</body>
</html>


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>

<body>

<b>这个文本是加粗的</b>

<br />

<strong>这个文本是加粗的</strong>

<br />

<big>这个文本字体放大</big>

<br />

<em>这个文本是斜体的</em>

<br />

<i>这个文本是斜体的</i>

<br />

<small>这个文本是缩小的</small>

<br />

这个文本包含
<sub>下标</sub>

<br />

这个文本包含
<sup>上标</sup>

</body>
</html>

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>菜鸟教程(runoob.com)</title> 
</head>
<body>

<pre>
此例演示如何使用 pre 标签
对空行和    空格
进行控制
</pre>

</body>
</html>
  • <!DOCTYPE html> 声明为 HTML5 文档
  • <html> 元素是 HTML 页面的根元素
  • <head> 元素包含了文档的元(meta)数据,如 <meta charset="utf-8"> 定义网页编码格式为 utf-8
  • <title> 元素描述了文档的标题
  • <body> 元素包含了可见的页面内容
  • <h1> 元素定义一个大标题
  • <p> 元素定义一个段落

CSS

Cascading Style Sheets 层叠样式表,定义如何显示HTML元素

p
{
    color:red;
    text-align:center;
}
选择器 属性 值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>菜鸟教程(runoob.com)</title> 
<style>
p.center
{
    text-align:center;
}
</style>
</head>

<body>
<h1 class="center">这个标题不受影响</h1>
<p class="center">这个段落居中对齐。</p> 
</body>
</html>

样式表

外部样式表

<head>
<link rel="stylesheet" type="text/css" href="mystyle.css">
</head>

内部样式表

<head>
<style>
hr {color:sienna;}
p {margin-left:20px;}
body {background-image:url("images/back40.gif");}
</style>
</head>

内联样式

<p style="color:sienna;margin-left:20px">这是一个段落。</p>

多重样式

<head>
    <!-- 外部样式 style.css -->
    <link rel="stylesheet" type="text/css" href="style.css"/>
    <!-- 设置:h3{color:blue;} -->
    <style type="text/css">
      /* 内部样式 */
      h3{color:green;}
    </style>
</head>
<body>
    <h3>测试!</h3>
</body>

样式表允许以多种方式规定样式信息。样式可以规定在单个的 HTML 元素中,在 HTML 页的头元素中,或在一个外部的 CSS 文件中。甚至可以在同一个 HTML 文档内部引用多个外部样式表。

尺寸

  • em:相对长度,相当于当前对象内文本的字体尺寸;值并不固定,继承父级元素的字体大小。例如,当前文本字体10px,则1em=10px
  • rem(root em):与em类似,但是只相对于根元素;通过修改根元素可成比例地调整页面字体大小;适配方案通过js脚本设置像素点实现
  • Viewport Width和Viewport Height,也就是vw和vh,基于视图窗口单位,属于CSS3。1vw等于视图窗口的1%;vmin:选取vw和vh中最小的那个,即在手机竖屏时,1vmin=1vw

JavaScript

没记住的方法

this.question.indexOf('?') === -1末尾是否是问号

ECM JavaScript 6

脚本语言,控制网页行为

变量声明

let:声明变量,用法类似于var,但作用域只包含let所在的代码块,同一个作用域不可用let重复声明同一个变量,并且不存在变量提升,必须先声明再使用。

for (let i = 0; i < 10; i++) {
    // ...
}

const:常量,一旦声明就不能改变,所在块级作用域内有效,只能在声明后使用;实质上保存的是指针,如果是数组或对象,数组本身和对象还是能改的。

const a = [];
a.push('hello');     //可执行
a.lengtgh = 0;        //可执行
a = ['Dave']        //报错

//冻结对象
const foo = Obejct.freeze({});

ES6共有6中声明变量的方法,以前的版本只有var和function,现在有let, const, import, class

顶层对象window(浏览器环境)和global(Node)对象,在ES5中,他们的属性与全局变量等价。但是在ES6中let与const和class声明的全局变量不属于顶层对象属性

赋值

解构赋值

允许从数组和对象中提取值,对变量赋值,称为解构Destructuring,解构不成功的变量为undefined;如果右边是不可遍历的结构,会报错。允许默认值,ES6内部使用严格相等运算===来判断一个位置是否有值,当一个数组成员严格等于undefined,默认值才会生效。

let [a, b, c] = [1, 2, 3];

let [foo, [[bar], baz]] = [1, [[2], 3]];

let [, , third] = ['f', 'b', 'a'];
// third = 'a'

let [herd, ...tail] = [1,2,3,4];
//tail = [2,3,4] head = 1

let [x, y, ...z] = ['a'];
// x = 'a'; y: undefined; z = []

let [x, y, z] = new Set(['a', 'b', 'c']);

let [x, y = 'b'] = ['a'];     //x='a', y='b'
let [x, y = 'b'] = ['a', undefined];     //y = 'b'

let [x = 1] = [null];
//默认值不生效,因为null不严格等于undefined

对象的解构赋值

变量必须与属性同名,才能取到正确的的值;如果等号右边是数值和布尔值,则会先转为对象

let {foo, bar} = {foo:'aaa', bar:'bbb'};

let {log, sin, cos} = Math;

const {log} = console;
log('hello');

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

var {x = 3} = {x: undefined};
x // 3 默认值生效条件严格等于undefined

var {x = 3} = {x: null};
x // null

let {length : len} = 'hello';
// len = 5

函数参数解构赋值

用途

let x = 1;
let y = 2;
[x,y] = [y,x];

// 返回一个数组

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
} = {}) {
  // ... do stuff
};

const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world

// 获取键名
for (let [key] of map) {
  // ...
}

// 获取键值
for (let [,value] of map) {
  // ...
}

异步相关

async

作为一个关键字放在函数的前面,表示该函数是一个异步函数,意味着该函数的执行不会阻塞后面代码的执行 异步函数的调用跟普通函数一样

async function timeout(){
    return "helloworld";
}
console.log(timeout());
console.log("我在异步函数后面,会先执行谁呢");
// Promise { 'helloworld' }
// 我在异步函数后面,会先执行谁呢

函数的返回结果是一个Promise对象,要获取Promise的返回值应该用then方法

async function timeout(){
    return "helloworld";
}
timeout().then((result)=>{
    console.log(result);
});
console.log("我在异步函数后面,会先执行谁呢");

// 我在异步函数后面,会先执行谁呢
// helloworld

此时先输出的就是后面的一串文字,说明异步函数的执行没有阻塞后面的代码执行,async的内部实现原理就是如果该函数中有一个返回值,当调用该函数时,默认会在内部调用Promise.solve() 方法把它转化成一个Promise 对象作为返回,若函数内部抛出错误,则调用Promise.reject()返回一个Promise对象

async function timeout1(flag){
    if(flag){
        return "hello world";
    }else{
        throw new Error("error!!");
    }
}

console.log(timeout1(true));
console.log(timeout1(false));
// Promise {<resolved>: "hello world"}
// Promise {<rejected>: Error: error!!...}

await

await即等待,用于等待一个Promise对象。它只能在异步函数 async function中使用,否则会报错

返回值不是Promise对象而是Promise对象处理之后的结果
await表达式会暂停当前 async function的执行,等待Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function,若 Promise 处理异常(rejected)await 表达式会把 Promise 的异常原因抛出。​如果 await 操作符后的表达式的值不是一个 Promise,那么该值将被转换为一个已正常处理的 Promise

// async await方式
async function doIt() {
    console.time("doIt");
    const time1 = 300;
    const time2 = await step1(time1);
    const time3 = await step2(time2);
    const result = await step3(time3);
    console.log(`result is ${result}`);
    console.timeEnd("doIt");
}
doIt();

wait不需要.then方法,可以对promise进行并行处理

Node.js

npm包管理

cnpm阿里优化

nvm管理不同nodejs版本

Express

创建web服务器的框架,基于内置的http模块一步步封装,提高开发效率

Bootstrap5

引入

CSS

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

Bundle JS

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

Separate

<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>

Vue

特性

  1. 数据驱动视图
  2. 双向数据绑定

数据驱动视图

在使用了Vue的页面中,数据的变化会被监听,从而达到自动重新渲染页面结构的效果,需要注意数据驱动视图是单向的数据绑定

双向数据绑定

在网页中,form表单负责采集数据,Ajax负责提交数据

填写表单时,可以在不操作DOM (Document Object Model) 的前提下,自动把用户填写的内容同步到数据源中

MVVM

将每个HTML页面拆分为三部分:Model,View,ViewModel。是Vue实现数据驱动视图和双向数据绑定的核心原理

Model:当前页面渲染时所以来的数据源

View:当前页面所渲染的DOM结构

ViewModel:Vue的实例,也是MVVM的核心

Vue2

Hello Vue2.0!

引入Vue

<!--制作原型或学习,可以使用最新版本-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<!--对于生产环境,我们推荐链接到一个明确的版本号和构建文件,以避免新版本造成的不可预期的破坏-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>

<!--使用原生 ES Modules,这里也有一个兼容 ES Module 的构建文件-->
<script type="module">
  import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.esm.browser.js'
</script>

基础使用

  1. 声明式渲染
  2. 条件与循环
  3. 处理用户输入
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
</head>
<body>
    <div id="app">
        {{message}}
    </div>

    <div id="app-2">
        <!--将v-bind元素节点的title和Vue实例的message绑定-->
        <span v-bind:title="message">
            鼠标悬停几秒钟查看此处动态绑定提示信息
        </span>
    </div>

    <div id="app-3">
        <p v-if="seen">现在你看到我了</p>
    </div>

    <div id="app-4">
        <ol>
            <li v-for="todo in todos">
                {{todo.text}}
            </li>
        </ol>
    </div>

    <div id="app-5">
        <p>{{message}}</p>
        <button v-on:click="reverseMessage">反转消息</button>
    </div>

    <div id="app-6">
        <p>{{message}}</p>
        <input v-model="message">
    </div>

</body>

<script>
    var app = new Vue({
        el: '#app',
        data: {
            message: 'Hello Vue!'
        }
    })

    var app2 = new Vue({
        el: '#app-2',
        data: {
            message: '页面加载于' + new Date().toLocaleDateString()
        }
    })

    var app3 = new Vue({
        el: '#app-3',
        data: {
            seen: true
        }
    })

    var app4 = new Vue({
        el: '#app-4',
        data: {
            todos: [
                { text: '学习JavaScript'},
                { text: '学习Vue'},
                { text: '整个好活'}
            ]
        }
    })

    var app5 = new Vue({
        el: '#app-5',
        data: {
            message: 'Hello Vue.js!'
        },
        methods: {
            reverseMessage: function () {
            this.message = this.message.split('').reverse().join('')
            }
        }
    })

    var app6 = new Vue({
        el: '#app-6',
        data: {
            message: 'Hello Vue'
        }
    })
</script>

</html>

由此可见v-xxx是一种Vue的指令,有着Vue提供的特殊属性,并且会在渲染的DOM上应用特殊的响应行为。v-model实现表单输入和应用状态之间的双向绑定

  1. 插值表达式
  2. v-bind可以缩写为':'
  3. v-on可以缩写为'@'
  4. v-if
  5. v-for
  6. v-mode

Filters过滤器

常用于文本格式化,可以和v-bind绑定。过滤器应该被添加在js表达式尾部,用管道符'|'进行调用

过滤器必须带返回

<p>{{ message | function }}</p>

filters: {
    function(var){
        return var
    }
}

//全局过滤器,第一个参数是过滤器名称,第二个是它的处理函数
//第一个参数,规定是管道符前面待处理的值,自定参数从第二个开始
Vue.filter('capitalize', (str) => {

})

计算属性和方法

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})

// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

第一个reverse是计算属性的getter,并不是方法,它依赖于message。第二个reverse则是以函数方法来达到同样的效果。计算属性是基于它们响应式依赖进行缓存,只在相关响应式依赖发生变化时,才会重新求值,例如message没有改,你访问reverse多次,会立即返回之前的结果,不会再次执行函数。而每当触发重新渲染时,调用方法则会再次执行函数。

事件

Vue提供内置变量$event,是原生DOM的事件对象e

V-on的事件修饰符有:

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

表单

可以用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。v-model 会忽略所有表单元素的 valuecheckedselected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model 不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input 事件。

<!--文本-->
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

<!--
多行文本
在文本区域插值 (<textarea>{{text}}</textarea>) 并不会生效,应用 v-model 来代替。
-->
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

<!--
单个复选框,绑定到bool值
-->
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

<!--
多个复选框,绑定到同一数组
-->
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
new Vue({
  el: '...',
  data: {
    checkedNames: []
  }
})

<!--
单选
-->
<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>
new Vue({
  el: '#example-4',
  data: {
    picked: ''
  }
})

选择框

<!--单选-->
<div id="example-5">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>

new Vue({
  el: '...',
  data: {
    selected: ''
  }
})

<!--动态选项-->
<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
  el: '...',
  data: {
    selected: 'A',
    options: [
      { text: 'One', value: 'A' },
      { text: 'Two', value: 'B' },
      { text: 'Three', value: 'C' }
    ]
  }
})

修饰符

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">

<!-- 自动将用户的输入值转为数值类型 -->
<input v-model.number="age" type="number">

<!-- 自动过滤用户输入的首尾空白字符 -->
<input v-model.trim="msg">

组件

组件是一个可以复用的Vue实例,data必须是函数

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
<div id="components-demo">
  <button-counter></button-counter>
</div>

使用组件的步骤

在App.vue的script中导入组件import components-demo from '@/components/components-demo //@默认指向src文件目录

在app.vue中注册组件

export default {
    components: {
        components-demo
    }
}

注册全局组件

main.js入口文件中,通过Vue.component()注册

props

自定义属性,提高组件复用性

export default {
    
    // props: ['init'],
    props: {
        init: {
            default: 0,
            type: Number,
            required: true
        }
    },

    data() {
        return {
            count: this.init
        }
    },
}

自定义事件

不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。

this.$emit('myEvent')

组件之间数据共享:

  1. 创建eventBus.js模块,向外共享一个Vue实例对象
  2. 数据发送方,调用bus.$emit('事件名称', 要发送的数据)方法触发自定义事件
  3. 数据接收方,调用bus.$on('事件名称', 事件处理函数)方法注册一个自定义事件

ref引用

监听器

方法中的侦听器,无法在进入页面时就自动触发,无法侦听对象属性

对象格式的侦听器,可以通过immediate选项,让监听自动触发,可以使用deep侦听属性变化

watch: {
    info: {
        handler(newVal){
            console.log(newVal)
        },
        deep: true
    }
}

watch: {
    'info.username'(newVal) {
        console.log(newVal)
    }
}

生命周期

一个组件从创建->运行->销毁的整个阶段。生命周期函数会伴随组件的声明周期,自动按顺序执行。

Vue2.x声明周期示意图

组件创建阶段

创建实例对象,初始化事件和声明周期函数

  1. beforeCreate:组件的porps/data/methods尚未被创建,不可用

初始化props、data、methods

  1. created:组件porps/data/method创建,处于可用态,但是组件模板尚未构成
  2. beforeMount(渲染之前)
  3. mounted

组件运行阶段

  1. beforeUpdate
  2. updated

组件销毁阶段

  1. beforeDestroy
  2. destroyed

axios

专注于网络请求的库

引入

unpkg CDN

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

jsDelivr CDN

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

基本语法

axios({
    method: '请求类型',
    url: '请求的URL地址',
}).then((result) => {
    //.then用来指定请求成功之后的回调函数
    //形参result是请求成功后的结果
})

传参

axios({
    method: '请求类型',
    url: '请求的URL地址',
    params: {},
    //GET 用params
    data: {}
}).then((result) => {
    
})

用例

为了在CommonJS中使用 require() 导入时获得TypeScript类型推断(智能感知/自动完成),请使用以下方法:

const axios = require('axios').default;

// axios.<method> 能够提供自动完成和参数类型推断功能
const axios = require('axios');

// 向给定ID的用户发起请求
axios.get('/user?ID=12345')
  .then(function (response) {
    // 处理成功情况
    console.log(response);
  })
  .catch(function (error) {
    // 处理错误情况
    console.log(error);
  })
  .then(function () {
    // 总是会执行
  });

// 上述请求也可以按以下方式完成(可选)
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // 总是会执行
  });  

// 支持async/await用法
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

练习

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>

<body>
    <button id="btnGET">GET</button>
    <button id="btnPOST">POST</button>
</body>
<script>
    document.querySelector('#btnGET').addEventListener('click', async function () {
        const { data: res } = await axios.get('http://www.liulongbin.top:3006/api/getbooks', {
            params: { id: 1 }
        })
        console.log(res);
    })

    document.querySelector('#btnPOST').addEventListener('click', async function () {
        // axios.post('url', { /* POST 请求体数据 */})
        const { data: res } = await axios.post('http://www.liulongbin.top:3006/api/post', {
            name: 'zs', gender: '女'
        })
        console.log(res);
    })
</script>

</html>

Vue3

Vue CLI

Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject。

全局安装

npm install -g @vue/cli

基础使用

创建项目

vue create hello-world

项目结构

src:

  1. assets:存放项目中用到的静态资源文件,例如CSS 样式表、图片资源
  2. components:封装的、可复用的组件
  3. main.js:项目入口文件,整个项目运行先执行main
  4. App.vue:项目的根组件

项目运行流程

在工程化项目中,通过main.js将App.vue渲染到index.html的指定区域

webpack

前端项目工程化的具体解决方案,有着代码压缩混淆、处理浏览器端JS兼容性,性能优化等功能,主要是去理解原理,用Vue.cil可以一键生成。

项目初始化

  1. 新建空白目录,运行npm init -y,初始化包管理配置文件package.json
  2. 新建src源代码目录
  3. src目录下新建index.htmlindex.js文件
  4. 初始化首页基本结构
  5. 安装webpack: npm install webpack webpack-cli -D
  6. 在项目根目录中,创建webpack.config.js文件并且初始化module.exports = {mode: 'development'}指定构建模式
  7. package.jsonscripts节点下新增dev脚本:"scripts": {"dev": "webpack"}使其可以通过npm run dev执行并且打包构建项目

自定义打包入口出口

webpack.config.js中定义:

const path = require('path')

module.exports = {
    mode: 'development',     //可选值还有production
    entry: path.join(__dirname, './src/index.js'),
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'main.js'
    }
}

自动打包插件

  1. 在项目中安装 npm install webpack-dev-server -D
  2. 修改package.jsscripts下的"dev": "webpack serve"
  3. 执行npm run dev后,webpack-server默认会在http://localhost:8080/创建服务器并运行项目。如果打开页面显示Can not Get错误,可以在webpack.config.js文件中增加配置devServer: {static: "./"}解决。原因是webpack-server默认serve的文件夹是public,改成./后可以将./下的文件serve到8080端口。

html 插件

  1. 项目目录下:npm install html-webpack-plugin -D
  2. 修改webpack.config.js
const path = require('path')

const HtmlPlugin = require('html-webpack-plugin')

const htmlPlugin = new HtmlPlugin({
    template: './src/index.html',       //指定原文件存放路径
    filename: './index.html'            //指定生成文件存放路径
})

module.exports = {
    mode: 'development',     //可选值还有production

    entry: path.join(__dirname, './src/index.js'),

    output: {
        path: path.join(__dirname, './dist'),
        filename: 'main.js'
    },

    devServer: {
        static: "./",
        open: true,
        port: 80,
        // host: '127.0.0.1',
    },

    plugins: [htmlPlugin]
}

Loader

负责打包js格式以外的文件

  1. npm i style-loader css-loader -D
  2. 修改webpack.config.js,增加module: {rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader']}]}
  3. 多个loader调用顺序:从后往前
  4. 其它类型的loader同理,无非是配置属性不同,可以去看文档

发布

  1. package.jsscripts下增加"build": "webpack --mode production"
Last modification:April 28th, 2022 at 10:37 pm
如果觉得我的文章对你有用,请随意赞赏
END
本文作者:
文章标题:前端学习
本文地址:http://feiqiuz.com/index.php/archives/19/
版权说明:若无注明,本文皆MixZou的小窝原创,转载请保留文章出处。