一、定义:是一个渐进式的JavaScript框架
二、特点:
- 减少了大量的DOM操作编写 ,可以更专注于逻辑操作
- 分离数据和界面的呈现,降低了代码耦合度(前端端分离)
- 支持组件化开发,更利于中大型项目的代码组织
vue2核心功能:
响应式数据与差值表达式
先实例化vue,在内部设置el(选择器,这个vm实例对谁生效),data 声明响应式数据,return()方法来写,插值表达式使用{{}},method封装方法(与data同级)
计算属性 computed
当对象定义,当属性使用。具有缓存性
使用场景: 结果不变,但需要多次运算的时候
缓存性:运算一次之后将结果存储在本地,下次远行的时候直接从本地获取数据
注意:使用的时候不能加括号,可以视为一个属性来使用
侦听器 watch(adeventlisenter)
参与响应式的过程,响应式数据发生改变时触发
使用场景: 当修改页面数据的时候再改点别的
指令
v-html、v-text innerHTML/innerText
v-on、v-bind、v-if(销毁/创建)、v-show(隐藏/显示)、v-model、v-for
遍历数组时,key就是index--索引;
遍历对象时,key就是属性名,index是索引,item是属性值
v-if切换开销更高、v-show初始化开销更高
v-bind 简写 : v-bind指令主要用于响应式的更新html属性
- 属性指令 用来做一些属性绑定 可配合响应式数据
v-on 简写 :
- 事件指令 可代替操作DOM绑定事件 可配合methods里自定义的方法使用
v-model专门适应于表单的数据绑定
- 修饰符 实现与指令之间的相关操作 可简化代码和DOM操作 添加在指令后面
比如:.trim 去除空格 v-model.trim
二、脚手架-组件化开发
vue中的图片打包后会转换为base64格式
组件的使用
1.创建组件:component文件夹中创建HelloWorld.vue文件
2.在app.vue中引入组件
组件间的通信/传值(常用)
一、prop父传子
1.App.vue中的引入组件中创建需要传递的数据
2.在子组件中接收并确定父组件传递过来的数据类型
more
规定接收的更多详细信息
对父元素做更多的设置展示数据的可能
每一个vue组件都相当于一个vue实例
二、$emit子传父
应用场景:购物车所有商品的结算,未知单个商品的价格
实现大概是:子组件中创建了事件,在父组件中控制/触发
1.在子组件中创建需要递交的数据及触发事件
2.父组件中接收触发的事件并绑定事件
按钮在子组件中,父组件只实时接收在子组件中改变的数据值
定义绑定的事件及获取传递过来的数据
{{childData}}
其他传递数据的方式
一、子传父,父传爷
二、EventBus传递
三、多级之间的传递vuex
插槽
应用场景: 使用同一个组件,希望有些不同的展示
1.默认插槽
2.具名插槽
Vue Devtools:插件安装,展示模块中的数据
三、vue-router
应用场景:Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
根目录-子目录
1.深入id的值控制页面展示/动态路由
应用场景:不同的id展示不同的页面,动态控制展示的内容
在路由中设置:
在组件中设置:
在app.vue中设置:
2.嵌套路由
应用场景:组件里面嵌套组件
......
3.编程式导航
应用场景:路由守卫、强制跳转
this.$router.push({name:'index'}) 路由导航
this.$route.query 获取路由传来的数据
4.路由导航守卫
当点击切换路由时:
beforeRouterLeave-->beforeEach-->beforeEnter-->beforeRouteEnter-->beforeResolve-->afterEach-->beforeCreate-->created-->beforeMount-->mounted-->beforeRouteEnter的next的回调
1.全局守卫(常用~)
beforeEach(to,from, next)、beforeResolve(to,from, next)、afterEach(to,from);
router.beforeEach((to, from, next) => {
//to 将要访问的路径
//from 代表从哪个路径跳转而来
//next 是一个函数,表示放行
// next() 放行 next('/login') 强制跳转
})
使用示例:
import Vue from "vue";
import VueRouter from "vue-router";
import Login from "../components/Login";
import Home from "../components/Home";
import Welcome from "../components/Welcome";
import User from "../components/User/User";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{ path: "/", redirect: "/login" },
{ path: "/login", component: Login },
{
path: "/home", component: Home,
redirect: 'welcome',
children: [
{ path: '/welcome', component: Welcome },
{ path: '/users', component: User },
]
}
]
});
//挂载路由导航守卫,控制页面访问权限
router.beforeEach((to, from, next) => {
if (to.path === '/login') return next();
//获取token
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')
next()
})
export default router;
2.单个路由独享
beforeEnter(to,from, next);
beforeEnter和 beforeEach 完全相同,如果都设置则在beforeEach之后紧随执行,参数to、from、next
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
使用示例:
当只有进入某个路由时,才需要验证,使用路由元信息 在路由配置中加入 meta
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 确保一定要调用 next()
}
})
3.组件级
beforeRouteEnter(to,from, next)、beforeRouteUpdate(to,from, next)、beforeRouteLeave(to,from, next)
是指在组件内执行的钩子函数,类似于组件内的生命周期,相当于为配置路由的组件添加的生命周期钩子函数。
<template>
...
</template>
export default{
data(){
//...
},
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
<style>
...
</style>
作者:TheTime
链接:juejin.cn/post/699872…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
四、vuex
总结:集中一些公用的数据与方法,外部可以通过commit触发指定方法
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state) 。Vuex 和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
基本内容:
state---data
getters---缓存
mutations---methods commit
actions---触发muntations中的方法 控制异步方法的 dispatch
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
loginStatus: '用户登录成功~',
count: 0
}
},
getters: {
},
mutations: {
increment (state,num) {
state.count+=num
}
},
actions: {
},
modules: {
}
})
在需要使用该数据的地方:this.$store.state.loginStatus //用户登录成功~
在组件中
methods: {
increment() {
this.$store.commit('increment',10)
console.log(this.$store.state.count)
}
}
使用方法:this.$store.getters.len
使用方法:this.$store.dispatch('delayChangeCount',10)
modules
使用场景:单独使用的数据不想被其他数据打扰
modules: {
a:{
state: {},
getters:{},
......
}
b:{
state: {},
getters:{},
......
}
}
使用方法:this.$store.a.getters.len
面试常问:
v-show与v-if的区别?
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS property display。
注意,v-show 不支持