vue3基础入门-p05-axios异步请求

  1. JSON-SERVER的使用
    1. 全局安装
    2. 提供一个json文件
    3. 启动接口服务
    4. 特点
  2. axios
    1. 安装axios
    2. 通过axios发送ajax请求
    3. todomvc-axios 版本
  3. 异步DOM更新以及$nextTick的说明
  4. 学习总结

JSON-SERVER的使用

为了前端项目获取数据,需要在本地搭建json-server,这样保证可以在本地实现增删改查的操作。

在不到30秒的时间内获得零编码的完整虚假REST API

JSON-SERVER 会自动根据一个json文件帮我们生成一套增删改查的接口

官网: https://github.com/typicode/json-server/

全局安装

npm install json-server -g

提供一个json文件

data.json:

{
  "todos": [
    { "id":1, "name": "吃饭", "flag": true },
    { "id":2, "name": "喝酒", "flag": false },
    { "id":3, "name": "唱歌", "flag": false }
  ]
}

启动接口服务

json-server data.json

特点

JSON-server给我们生成的一个rest风格的接口

查询:get    http://localhost:3000/todos    获取所有的任务
            http://localhost:3000/todos/3  获取id为3的任务
增加:post   http://localhost:3000/todos    增加
删除:delete http://localhost:3000/todos/3
修改:put    http://localhost:3000/todos/3  全量的修改,会把原来的所有内容个都覆盖掉, 需要改不需要改都应该传
    patch   http://localhost:3000/todos/3  打补丁,只会修改传递的值

axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

vue自身没有提供发送ajax请求的工具

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

  • Promise based HTTP client for the browser and node.js
    • 以Promise为基础的HTTP客户端,适用于:浏览器和node.js
    • 封装ajax,用来发送请求,异步获取数据

安装axios

npm i -S axios

通过axios发送ajax请求

  1. 引入axios
<script src="node_modules/axios/dist/axios.js"></script>
  1. 发送ajax请求
<!-- 引入axios -->
<script src="node_modules/axios/dist/axios.js"></script>
<script>
	// axios暴漏了一个全局变量,就是axios
	// 基本格式:axios().then().catch()
	axios({
		// method: 请求方式
		// url: 请求地址
		// data: 设置请求的数据(post请求和put请求等数据)
		// params: 设置请求的参数(get请求和delete)
		method: 'get',
		url: 'http://localhost:3000/todos'
	}).then(res => {
		// 处理成功的结果, res是axios给我们封装的一个对象,服务器返回的数据在res.data中
		console.log(res.data)
	}).catch(function (err) {
		// 处理失败的结果
		console.log(err)
	})
</script>

todomvc-axios 版本

  • todos 列表的渲染
  • todos 列表的删除
  • todos 列表的修改
  • todos 清空已完成任务

app.js:

(function (window) {
	const app = Vue.createApp({
		data() {
			// Data函数应该返回一个对象
			return {
				todos: [],
				// 新增任务输入框绑定值
				todoName: '',
				now: -1,
				// 过滤类型
				filterType: 'ALL'
			}
		},

		methods: {
			// axios-获取任务列表
			getTodoList() {
				axios({
					method: 'get',
					url: 'http://localhost:3000/todos?_sort=id&_order=desc'
				}).then(res => {
					this.todos = res.data
				}).catch(err => {
					console.log(err)
				})
			},
			// 删除任务,根据任务id
			delTodo(id) {
				axios({
					method: 'delete',
					url: `http://localhost:3000/todos/${id}`
				}).then(res => {
					// 删除数据成功,代表服务器已经数据已经删除成功。
					// 重新发送一个请求,获取最新的任务列表
					this.getTodoList()
				})
			},
			// 添加任务
			addTodo() {
				axios({
					method: 'post',
					url: 'http://localhost:3000/todos',
					data: {
						name: this.todoName,
						flag: false
					}
				}).then(res => {
					// 重新渲染
					this.getTodoList()
					this.todoName = ''
				})
			},
			// 显示修改框
			showEdit(id) {
				this.now = id
			},
			// 修改任务:根据id来修改对应的数据
			editTodo(id, data) {
				axios({
					method: 'patch',
					url: `http://localhost:3000/todos/${id}`,
					data: data
				}).then(res => {
					this.getTodoList()
				})
			},
			// 修改任务状态
			changeState(id, flag) {
				this.editTodo(id, {flag})
			},
			// 修改任务名称
			updateTodo(id, name) {
				this.now = -1
				this.editTodo(id, {name})
			},
			// 清空已完成任务
			clearTodo() {
				// 1. 确定哪些任务需要删除
				// 2. 循环,挨个删除
				this.todos.filter(item => item.flag).forEach(item => this.delTodo(item.id))
			},
			// 切换过滤类型
			change(filterType) {
				// 控制样式判断值
				this.filterType = filterType
			},


		},
		computed: {
			//控制是否显示Footer
			isShowFooter() {
				// 当任务数量超过0,就显示footer
				return this.todos.length > 0
			},
			// 统计未完成的任务
			unCompletedCount() {
				// 过滤出未完成的任务
				// this.todos.filter(item => !item.flag)
				return this.todos.filter(item => !item.flag).length
			},
			// 控制清空按钮的显示隐藏
			isShowClear() {
				// 如果没有已完成任务,就隐藏
				// 如果存在已完成任务,便显示
				return this.todos.some(item => item.flag)
			},
			// 控制是否全部选中
			// 需要修改,提供set函数
			isCheckedAll: {
				get() {
					// 当所有的任务都完成了,表示都选中了
					return this.todos.every(item => item.flag)
				},
				set(value) {
					// console.log(value)
					// value修改后的计算属性,,,,,,应该修改todos中所有的任务的flag
					this.todos.forEach(item => item.flag = value)
				}
			},
			// 用于显示的列表
			showList() {
				// 计算属性showList 要根据 filterType
				if (this.filterType === 'Active') { // 返回未完成的任务
					return this.todos.filter(item => !item.flag)
				} else if (this.filterType === 'Completed') { // 返回已完成的任务
					return this.todos.filter(item => item.flag)
				} else { // 默认返回所有任务
					return this.todos
				}
			}

		},

		created() {
			this.getTodoList()
		}


	})

	const vm = app.mount('.todoapp')
	window.vm = vm

})(window);

完整示例代码参考:https://gitee.com/guanfuchang/todos_v2

异步DOM更新以及$nextTick的说明

在vue中数据发生了改变,DOM中的数据也会跟着发生改变,但是这个过程是异步的

vue的数据发生改变之后,DOM不会立即更新,会等到下一次渲染工作执行的时候才会更新DOM

目的:为了提高渲染的性能

<body>
<div id="app">
    <button @click="fn">改变</button>
    <p>{{ msg }}</p>
</div>

<script src="./node_modules/vue/dist/vue.global.js"></script>

<script>

    const app = Vue.createApp({
        // data 提供了vue中使用的数据
        data() {
            return {
                msg: 'hello vue'
            }
        },
        methods: {
            fn() {
                // 修改数据
                this.msg = 'Hello World!'
                // DOM 尚未更新
                let result = document.querySelector('p').innerHTML
                console.log("数据改变后,马上获取dom内容:", result)
                // 为什么:DOM操作是非常消耗性能的,简单DOM的操作能够提升我们的性能,如果每次操作数据,都立即更新DOM,无疑性能会非常的低,所以vue中会等待数据都修改完成

                // 当vue更新完DOM后,会自动调用$nextTick函数,确保在这个函数中可以获取到DOM结构是最新的
                this.$nextTick(()=> {
                     // DOM 现在更新了
                    let result = document.querySelector('p').innerHTML
                    console.log("在nextTick中获取dom内容:",result)
                })
            }
        }
    })

    const vm = app.mount('#app')
    window.vm = vm
</script>
</body>

学习总结

vue学习总结


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
My Show My Code