vue的生命周期及axios
生命周期
生命周期钩子函数
- beforeCreate 创建之前(可以预加载)
- created 创建完成(可以请求数据)
- beforeMount 挂载之前 (可以对虚拟dom的优化)
- mounted 挂载完成(可以阻止渲染)
- beforeUpdate 修改之前 (可以阻止修改)
- updated 修改完成 (可以进行修改完成的后续操作)
- beforeDestroy 销毁之前(回收资源)
- destroyed 销毁完成()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <div id="app"> <input type="text" v-model="names"> <h1>你好 {{names}}</h1> </div> <script src="./lib/vue.js"></script> <script> Vue.config.productionTip = false const vm = new Vue({ el: '#app', data: { names: '袁同学!', }, methods: {
}, template:"<h3>hello world!</h3>", beforeCreate() { console.log('beforeCreate,创建之前'); }, created() { console.log('created,创建完成'); }, beforeMount() { console.log('beforeMount,挂载之前'); }, mounted() { console.log('mounted,挂载完成'); }, beforeUpdate() { console.log('beforeUpdate,更新之前'); }, updated() { console.log('updated,更新完成'); }, beforeDestroy() { console.log('beforeDestroy,销毁之前'); }, destroyed() { console.log('beforeDestroy,销毁完成'); }, })
|
vue内置的网络请求
vue.resource(已废弃)
axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
特性
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
简易的用户管理系统
数据(user.json)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| { "users": [ { "id": 1, "username": "tom", "avatar": "https://img2.baidu.com/it/u=2043310493,2206067123&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", "email": "nobita@qq.com", "age": "12", "isEdit": true }, { "id": 2, "username": "tom", "avatar": "https://img2.baidu.com/it/u=2043310493,2206067123&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", "email": "123@163.com", "age": 22 }, { "id": 3, "username": "tom", "avatar": "https://img2.baidu.com/it/u=2043310493,2206067123&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", "email": "123@163.com", "age": 22 }, { "id": 4, "username": "jerry", "avatar": "https://img0.baidu.com/it/u=912844464,1907087211&fm=253&app=138&size=w931&n=0&f=PNG&fmt=auto?sec=1680109200&t=ad9a44000082b932d0cf48960b84b5ee", "email": "123@163.com", "age": 21 }, { "id": 5, "username": "jerry", "avatar": "https://img0.baidu.com/it/u=912844464,1907087211&fm=253&app=138&size=w931&n=0&f=PNG&fmt=auto?sec=1680109200&t=ad9a44000082b932d0cf48960b84b5ee", "email": "123@163.com", "age": 21 } ] }
|
1 2
| 预先在终端配置服务: json-server -w .\user.json
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
| <!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> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"> <style> .saveBox { width: 600px; background-color: #ddd; margin: 20px auto; padding: 30px; border-radius: 5px; }
.showBox { width: 1000px; margin: 10px auto; }
.showBox td img { width: 30px; height: 30px; } </style> </head>
<body>
<div id="app"> <div class="saveBox"> <div class="form-group"> <label for="basic-url">usename</label> <input type="text" class="form-control" v-model="user.username"> </div> <div class="form-group"> <label for="basic-url">age</label> <input type="text" class="form-control" v-model="user.age"> </div> <div class="form-group"> <label for="basic-url">avatar</label> <input type="text" class="form-control" v-model="user.avatar"> </div> <div class="form-group"> <label for="basic-url">email</label> <input type="text" class="form-control" v-model="user.email"> </div> <button class="btn btn-default" type="submit" @click="saveUser">添加</button> </div> <div class="showBox"> <div class="panel panel-default"> <div class="panel-heading">Users</div> <table class="table"> <thead> <tr> <th>编号</th> <th>用户名</th> <th>年龄</th> <th>头像</th> <th>邮箱</th> <th>操作</th> </tr> </thead> <tbody v-for="(users,index) in users" ::key="users.id"> <tr v-if="!users.isEdit"> <td>{{index=1}}</td> <td>{{users.username}}</td> <td>{{users.age}}</td> <td><img :src="users.avatar" alt=""></td> <td>{{users.email}}</td> <td> <button class="btn btn-default" @click="users.isEdit=true">编辑</button> <button class="btn btn-default" @click="deleteById(users.id)">删除</button> </td> </tr> <tr v-else> <td>{{index=1}}</td> <td> <input type="text" class="form-control" v-model="users.username"> </td> <td> <input type="text" style="width: 80px;" class="form-control" v-model="users.age"> </td> <td> <input type="text" class="form-control" v-model="users.avatar"> </td> <td> <input type="text" class="form-control" v-model="users.email"> </td> <td> <button class="btn btn-default" @click="updateById(users.id)">添加</button> <button class="btn btn-default" @click="users.isEdit=false">取消更改</button> </td> </tr> </tbody> </table> </div> </div> </div> <script src="./lib/vue.js"></script> <script src="./lib/axios.min.js"></script> <script> Vue.config.productionTip = false axios.defaults.baseURL = "http://localhost:3000/" const vm = new Vue({ el: '#app', data: { users: [], user: { username: '', age: '', avatar: '', email: '' }, }, methods: { async getUsers() { let { data } = await axios.get("/users") data.forEach(user => { user.isEdit = false }); this.users = data }, async deleteById(id) { await axios.delete(`/users/${id}`) this.getUsers() }, async saveUser() { if (this.check(this.user)) { await axios.post("/users", this.user) } this.getUsers() }, check(user) { try { Object.keys(user).forEach((key) => { if (user[key].toString().trim() == '') { throw new Error() } }) return true } catch (err) { alert('请将填写完整') } }, async updateById(id) { let newUser = this.users.find((user) => { return user.id == id }) if (this.check(newUser)) { await axios.put(`/users/${id}`, newUser) newUser.isEdit = false } else { this.getUsers() } } }, beforeMount() { this.getUsers() }, }) </script> </body>
</html>
|
自定义指令
vue官方提供了v-text、v-html、v-model、v-if等一些常用的指令。除此之外vue还允许开发者自定义指令。
规则
- 使用v-开头
- 使用:来传入对应属性
- 使用=去传递对应的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| <div id="app"> <h1 v-color:name="msg">你好 {{names}}</h1> <h1 v-color:name="color">你好 {{names}}</h1> <input v-placeholder="msg" type="text"> <div v-myhtml="htmlCode"></div> </div> <script src="./lib/vue.js"></script> <script> Vue.config.productionTip = false Vue.directive('color', { bind(el, binding, vnode) { console.log('bind'); console.log(el, binding, vnode); el.style.color = binding.value }, componentUpdated(el, binding, vnode, oldvnode) { console.log('componentUpdated'); }, inserted() { console.log('inserted'); }, unbind() { console.log('unbind'); }, updated() { console.log('updated'); }, })
const vm = new Vue({ el: '#app', data: { names: '袁同学!', msg: 'hello', color: 'pink', htmlCode:"<h3>你好</h3>" }, directives:{
"placeholder":function(el,binding,vnode){ el.setAttribute('placeholder',binding.value) },
"myhtml":{ bind(el,binding,vnode){ el.innerHTML = binding.value }, inserted(el,binding,vnode){
}, update(){
}, componentUpdated(){
}, unbind(){
}, } } }) </script>
|
filter过滤器(vue3已废弃)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <div id="app"> <h1>你好 {{names}}</h1> {{db | fixed}}<br> {{db | fixed(3)}}<br> <h2>{{ new Date() | format}}</h2> </div> <script src="./lib/vue.js"></script> <script> Vue.config.productionTip = false
const vm = new Vue({ el: '#app', data: { names: '袁同学!', db: 3.1415926 }, filters: { fixed(data, len = 2) { return data.toFixed(len) }, format(date) { let year = date.getFullYear() let month = date.getMonth() + 1 let day = date.getDate() return `${year}-${month}-${day}` } } }) </script>
|
computed计算属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <div id="app"> <h1>你好 {{names}}</h1> <input type="text" v-model="number1">+ <input type="text" v-model="number2">= <input type="text" v-bind:value="sum"> <hr> {{sum1}} <button @click="sum1=20">sum1=20</button> </div> <script src="./lib/vue.js"></script> <script> Vue.config.productionTip = false
const vm = new Vue({ el: '#app', data: { names: '袁同学!', number1:'', number2:'', number3:0, }, computed:{ sum(){ return Number(this.number1) + Number(this.number2) }, sum1:{ get(){ console.log('get'); return this.number3 }, set(v){ console.log('set'); this.number3 = v } } } }) </script>
|
computed和methods的区别(面试题)
- computed会缓存数据,只有当数据变化了才会重新编译
- methods每次调用都会重新编译
- computed的效率高于methods
watch监听器
用于监听劫持的数据变化的
三个属性
- handler 处理函数
- deep 是否深度监听
- immediate 是否开始就监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <div id="app"> <h1>你好 {{names}}</h1> {{number}}<button @click="number=2">改变number</button> {{number2}}<button @click="number2=2">改变number2</button> {{user}}<button @click="user.username='tom'">改变user.username</button> </div> <script src="./lib/vue.js"></script> <script> Vue.config.productionTip = false
const vm = new Vue({ el: '#app', data: { names: '袁同学!', number: 1, number2: 1, user:{ username:'jerrry' } }, watch: { number(newValue, oldValue) { console.log(newValue, oldValue); newValue = oldValue + 10 }, number:{ handler(newValue, oldValue){ console.log('number监听了'); }, deep:true, immediate:true }, "user":{ handler(newValue, oldValue){ console.log('user监听了'); }, deep:true, immediate:true } } }) </script>
|
computed和watch的区别(面试题)
- computed有缓存,不支持异步操作
- watch没有缓存,支持异步操作
- computed 有get和set属性
- watch 有handler、deep、immediate