Vue.js基础之知识总结
前言
一、Vue.js 概述
1.1 渐进式JavaScript框架
1.1.1 只关注视图层
1.1.2 发展路程 原生JS -> Jquery之类的类库 -> 前端模板引擎 -> Angular.js / Vue.js
1.2 优点
1.2.1 易用
熟悉HTML、CSS、JavaScript知识后,可快速上手Vue
1.2.2 灵活
在一个库和一套完整框架之间自如伸缩
1.2.3 高效
20KB运行大小,超快虚拟DOM;能够帮助我们减少不必要的DOM操作;提高渲染效率
二、内置指令
2.1 组件复用的问题(添加key避免复用)
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
那么在下面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input> 不会被替换掉——仅仅是替换了它的 placeholder
这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key attribute 即可:
<body>
<div id="app">
<div v-if="loginType == true">
<label for="username">username</label>
<input type="text" placeholder="username" id="username">
</div>
<div v-else>
<label for="Email">email</label>
<input type="text" placeholder="email" id="email">
</div>
<button @click="handleChangeState">change</button>
</div>
<script>
const app =new Vue({
el: '#app',
data: {
loginType: true,
},
methods: {
handleChangeState() {
this.loginType = !this.loginType;
}
},
})
</script>
</body>
2.2 v-model
2.2.1 概述
1、双向绑定,负责监听用户的输入事件以更新vm的数据
2、v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
3、v-model实现
<input type="text" :value="target" @input="changeTarget">
data: {target: ''}
changeTarget(event) {
this.target = event.target.value;
}
三、自定义指令
3.1 钩子函数 定义指令的功能的函数
钩子函数的类型 | 备注 |
---|
bind | 只调用一次,指令第一次绑定到元素时调用,和样式相关的操作使用 |
inserted | 被绑定元素插入父节点时调用,和JS行为有关的操作 |
updated | 当VNode更新的时候,会执行 updated, 可能会触发多次 |
钩子函数的参数 | 备注 |
---|
el | 指令所绑定的元素,也就是元素节点 |
binding | 一个对象 |
binding包含的键 | 备注 |
---|
name | 常用。指令名,不带v- |
value | 常用。指定绑定的值,就是指令等号后的标识符 |
oldValue | 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用 |
expression | 字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。 |
arg | 传给指令的参数,可选。例如:v-my-directive:foo 中,参数为 “foo”。 |
modifiers | 一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar:true }。 |
3.2 全局指令
3.2.1 基本语法
使用Vue的静态方法directives()
Vue.directive('指令名', {
钩子函数名: function(el,binding) {
...
}
})
3.2.2 无参和有参指令
<div id="app">
<input type="text" v-focus>
<input type="text" v-color='msg'>
</div>
Vue.directive('focus', {
inserted: function(el){
el.focus();
},
bind: function(el, binding){
el.style.backgroundColor = binding.value.color;
}
});
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'blue'
}
}
});
3.3 局部指令
3.3.1 添加在vm实例的directives属性里
var vm = new Vue({
el: '#app',
data: {
...
},
methods: {
...
},
directives: {
指令名1: {
钩子函数名: function(el,binding) {
...
}
},
指令名2: {
钩子函数名: function(el,binding) {
...
}
},
});
3.3 不区分钩子函数的指令
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
六、过滤器
6.1 概述 对数据进行处理,格式化数据
6.2 过滤器分类 如果全局过滤器和局部过滤器同名会通过就近原则调用局部过滤器
七、过渡 & 动画
2.1 过渡类名
2.1.1 v-enter
定义进入过渡的开始状态。
2.1.2 v-enter-active
:定义进入过渡生效时的状态。
2.1.3 v-enter-to
:定义进入过渡的结束状态。
2.1.4 v-leave
:定义离开过渡的开始状态。
2.1.5 v-leave-active
定义离开过渡生效时的状态。
2.1.6 v-leave-to
定义离开过渡的结束状态。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210616161510611.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NhdG9zZXJl,size_16,color_FFFFFF,t_70)
2.2 过渡
2.2.1 能实现单组件过渡的情况
2.2.2 给目标的组件包裹transition组件并添加name属性来修改类名前缀
<transition name="slide-fade">
targetComponent
</transition>
2.2.3 给目标组件添加能实现过渡的条件
<targetComponent v-if/v-show...></targetComponent>
2.2.4 添加过渡类和初始样式类
initClass {}
.fade-enter-active, {
transition: ...
}
.fade-leave-active {
transition: ...
}
.fade-enter, .fade-leave-to {
// 初始样式
}
2.3 动画
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
2.4 自定义过渡类
2.4.1 优先级高于普通的类名
2.4.2 类名
enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)
2.4.3 在transition组件中定义自定义类
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
八、组件
1.1 组件概述
1.1.1 封装可重用代码扩展成HTML标签
1.1.2 实质上被当作一个标签使用
1.1.3 组件可复用
1.1.4 面向视图层部署组件
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210310172717249.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NhdG9zZXJl,size_16,color_FFFFFF,t_70)
1.2.3 组件命名规则
短横线分隔命名(kebab-case)
例如 <my-component-name>
首字母大写命名(PascalCase)
例如 <MyComponentName>
命名方式 | 备注 |
---|
短横线 | 推荐使用。在任何情况下都有效 |
驼峰法 | 仅仅能在template使用,在dom元素上使用会出错 |
1.2.4 动态组件
<component :is="currentTabComponent"></component>
九、vue-router
3.1 路由概述
3.1.1 根据不同的用户事件,显示不同的页面内容
3.1.2 前端路由负责事件监听,触发事件后,通过事件函数渲染不同内容
3.1.3 完整的导航解析流程
导航被触发。
在失活的组件里调用 beforeRouteLeave 守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
3.2 路由元信息
3.2.1 解决多个匹配到的路由的拦截代码冗余的问题
因为嵌套路由的存在, 所以this.$route.matched这个数组会保存父路由记录以及子路由记录,但是在代码的编写上总不能一一判断多个路由记录
的情况,这会导致代码量增多,冗余度高,所以使用meta属性无论使用在哪个匹配到的路由上,通过遍历matched数组就可以判断meta属性是true
还是false。从而进行拦截并执行其他操作
3.3 路由懒加载
当打包构建应用时,所有的代码都会放到一个JavaScript的包,这个包会变得非常大,影响页面加载。
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
十、Vue的异步任务解决办法
2.1 基于Promise的fetch方法
2.1.1 fetch概述
更加简单的数据获取方式,功能更强大、更灵活,可以看做是xhr的升级版
fetch方法实际上返回了promise实例,所以才能调用then方法
第一个then的data是后台返回的response对象,通过text/json方法转为promise对象
后台返回的数据存在内部变量promiseValue里面.外部无法获取,只能通过第二个then获取
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210312175627988.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NhdG9zZXJl,size_16,color_FFFFFF,t_70)
2.1.2 fetch使用
fetch方法的参数 | 备注 |
---|
url | 完整的url |
method | 请求方法 |
body | 请求体 |
headers | 请求头 |
fetch('http://localhost:3000/books?id=123', {
method: 'get'
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
fetch('http://localhost:3000/books/456', {
method: 'get'
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
fetch('http://localhost:3000/books/789', {
method: 'delete'
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
fetch('http://localhost:3000/books', {
method: 'post',
body: 'uname=lisi&pwd=123',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
fetch('http://localhost:3000/books', {
method: 'post',
body: JSON.stringify({
uname: '张三',
pwd: '456'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
fetch('http://localhost:3000/books/123', {
method: 'put',
body: JSON.stringify({
uname: '张三',
pwd: '789'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
app.get('/books', (req, res) => {
res.send('传统的URL传递参数!' + req.query.id)
})
app.get('/books/:id', (req, res) => {
res.send('Restful形式的URL传递参数!' + req.params.id)
})
app.delete('/books/:id', (req, res) => {
res.send('DELETE请求传递参数!' + req.params.id)
})
app.post('/books', (req, res) => {
res.send('POST请求传递参数!' + req.body.uname + '---' + req.body.pwd)
})
app.put('/books/:id', (req, res) => {
res.send('PUT请求传递参数!' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
})
2.1.3 fetch响应数据格式
将返回体处理成字符串类型 text()
将返回体处理成对象类型,前提是后台返回的数据是json或对象格式 json()
五、axios
2.2.1 axios概述 ⼀个基于Promise用于浏览器和node.js的HTTP客户端
六、 Vuex
6.1 state
store的data
6.2 getters
store的computed
6.3 mutations
store的methods
6.4 actions
store的asyncMethods
6.5 module
store的模块化写法
九、Vue/cli脚手架
5.1 安装vue脚手架 npm install -g @vue/cli
5.2 创建vue项目模板
vue create 项目名
vue ui
npm install -g @vue/cli-init
vue init webpack 项目名
5.3 添加自定义配置
5.3.1 在项目的跟目录创建并配置文件 vue.config.js
module.exports = {
devServer: {
port: 8888,
open: true
},
lintOnSave: false
}
8.1 项目结构
8.1.1 main.js
入口文件
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
8.1.2 package.json
1、scripts
调试命令
(1)npm run serve
开启热服务调试
(2)npm run build
使用webpack打包项目到dist文件夹
2、dependencies
运行依赖
"axios": "^0.21.1",
"core-js": "^3.9.1",
"element-ui": "^2.15.1",
"vue": "^2.6.12",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
3、devDependencies
开发依赖
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@vue/cli-plugin-babel": "^4.5.11",
"@vue/cli-plugin-eslint": "^4.5.11",
"@vue/cli-plugin-router": "^4.5.11",
"@vue/cli-plugin-vuex": "^4.5.11",
"@vue/cli-service": "^4.5.11",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"babel-plugin-component": "^1.1.1",
"babel-plugin-transform-remove-console": "^6.9.4",
"eslint": "^6.8.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-vue": "^6.2.2",
"less": "^4.1.1",
"less-loader": "^4.1.0",
"vue-cli-plugin-element": "^1.0.1",
"vue-template-compiler": "^2.6.12"
总结