1、 模板语法
{{}} 内容为data中定义的变量
2、 数据绑定
1、v-bind:value:单向数据绑定,v-bind可以省略,v-model双向数据绑定,v-on:click简写@click
2、MVVM:(model,view,viewModel):在vue中,model值的是data中的数据,view是template,vm是vue实例,model=>view通过数据绑定实现,view=>model通过事件绑定实现
3、 数据代理
1、defineProperty,为对象增加属性,新增加的属性不能修改,删除,枚举等,可以通过配置参数实现
let obj={name:'xiaozhang'}
Object.defineProperty(obj,'sex',{
value:'男',
get:function(){},
set:function(){},
writable:false, //可修改
enumerable:false,//可枚举(Object.keys()和for in)
configurable:false//可配置,控制删除和重新配置属性
})
2、vue中的数据代理
vm._data=options.data
vm.a=vm._data.a
4、 事件
1、事件修饰符:prevent(阻止默认事件,比如a标签跳转),stop(阻止冒泡),self(元素自身,不包括冒泡和捕获),capture (使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理),passive事件默认行为立即执行(比如whell.passive,滚动条的滚动发生在回调函数执行完后,体验不佳,可以使用此修饰符),once(只触发一次)
2、使用$event传递事件参数
3、键盘@keyup.enter,@keydown;ctrl,alt,sheft,meta(windows)的keyup许配合其他按键一起使用(@keyup.ctrl.y)
5、 computed与watch
1、computed:{},有缓存,有get和set,get在初次绑定和数据发生变化都会执行,在调用set赋值时注意修改依赖的数据的值
2、watch:{},无缓存,immediate:true可在初始绑定就执行handler函数,默认不监测对象内部值的改变(一层),deep:true可以监测对象内部值改变(多层)
6、 动态绑定class与style
1、class绑定方法 :class=‘classA’
- 对象classA:{‘class1’:true,‘class2’:false},类名确定,但需要动态决定是否生效
- 数组class:[‘class1’,‘class2’],个数不确定类名也不确定
- 字符串 classA:‘class1’,个数确定,类名动态
2、style绑定方法 :style=‘styleA’
- 数组 styleA:[{color:red,fontSize:‘12px’},{width:‘120px’}]
- 对象 styleA:{color:red,fontSize:‘12px’}
7、 列表相关
v-for时key值最好使用数据的唯一性约束,不使用index,如果单纯展示不操作数组时使用不会有问题,但是如果涉及到数组更新可能会造成更新混乱的情况
8、 数据监测
使用defineProperty循环为变量的每一个属性增加get和set属性,然后使用observer观察者模式收集所有的
let data={name:'',sex:''}
const obs = new Observer(data)
function Observer(obj){
Object.keys(obj).forEach(k=>{
new Observer(obj[key])
Object.defineProperty(this,k,{
get:function(){
return obj.k},
set:function(val){
obj.key = val
}
})
})
}
9、 过滤器与指令
1、过滤器:处理展示数据
filters:{
suma(a,b){
return a+b
}
}
2、常用内置指令
- v-model
- v-if,v-show
- v-once 节点只渲染一次,用于展示初始数据
- v-pre 跳过渲染,可用于不包含指令和vue语法的节点
- v-text 替换节点内容为text
- v-html替换节点内容为html
- v-cloak 用于vue未加载完成时的样式处理,加载完后该类消失
3、自定义指令
directives:{
//简写,1、在指令与元素初次绑定成功时重新执行;2、使用指令的模板变化时重新执行
big(element,binding){
console.log('big',this) //注意此处的this是window
element.innerText = binding.value * 10
},
//完整写法
'add-span':{
bind(element,binding){},//绑定成功时执行回调
inserted(){},//节点插入模板
update(){}//更新
}
}
10、 生命周期
beforeCreate,created,beforeMount,mounted,beforeDestory,destroyed,beforeUpdate,updated
11、组件传参
1、prop
2、$refs获取子组件
3、$emit(子组件传参给父组件)
4、全局总线
Vue.prototype.$eventBus = new Vue();
//不是全局时,需要传参的组件中分别引入
//接收组件
mounted(){
this.$eventBus.$on('event1',data=>{
})
}
//发送组件
this.$eventBus.$emit('event',{a:1})
5、使用发布订阅插件
6、slot
12、插件
let pluginA = {
install:function(vue){
//可以定义filter,directive等
// 1. 添加全局过滤器
Vue.filter(....)
// 2. 添加全局指令
Vue.directive(....)
// 3. 配置全局混入(合)
Vue.mixin(....)
// 4. 添加实例方法
Vue.prototype.$myMethod = function () {...}
Vue.prototype.$myProperty = xxxx
}
}
export default pluginA
//在main.js中引入
import pluginA from './plugin.js'
vue.use(pluginA )
13、vuex
适用于全局变量的存储
const store1 = {
namespaced:true,//使用时需加上命名空间,避免重名,在使用相关map时可作为传入参数
state:{
a:1,
b:0
},
getters:{
doubleA(state){
return state.a*2 //类似于计算属性
}
},
mutations: {//只能进行同步操作
incrementA (state) {
// 变更状态
state.a++
},
incrementB (state) {
// 变更状态
state.b++
},
},
actions:{//允许异步操作
increment (context) {
context.commit('incrementA');
context.commit('incrementB')
}
}
}
import { mapGetters,mapMutations,mapActions } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中,就可以直接使用this.A2
...mapGetters({
A2:'doubleA'}
)
},
methods:{
...mapMutations({
add: 'incrementA' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
},
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
13、vue-router
1、路由配置
- 使用router-link 和router-view标签
- 使用函数跳转(replace,push,back:使用replace时后退无法返回原路径)
2、路由传参
- query
- params
将路由配置文件中的props设置为true,可以将params中的参数转换为props,props支持三种写法
export default[{
path:'/home'
redirect:'/login',
component:()=>import('pages/home'),//可实现按需加载组件
meta:{//可以在此处定义控制该路由所需变量
keepAlive:false,
auth:true
},
//1、支持对象
//props:{id:111,name:'aaa'}
//2、支持布尔值,将params中的参数转换为props
props:true
//3、支持函数
//props($route){
//return {is:$route.query.id}
}
}]
3、路由守卫
- 在路由文件中定义全局路由守卫
//router.js
import VueRouter from vue-router'
VueRouter.beforeEach((to,from,next)=>{
//可在此处进行权限校验
})
VueRouter.afterEach((to,from)=>{
})
- 在路由文件中定义某个特定路由的配置
export default[{
path:'/home'
redirect:'/login',
component:()=>import('pages/home'),//可实现按需加载组件
meta:{//可以在此处定义控制该路由所需变量
keepAlive:false,
auth:true
},
beforeEnter:(to,from,next)=>{
//可在此处进行权限校验
},
afterEnter:(to,from)=>{
//可在此处进行权限校验
}
}]
- 组件内进行配置
//home.vue
beforeRouterEnter:(to,from,next)=>{
},
beforeRouterLeave:(to,from,next)=>{
}
4、路由的两种模式
hash模式和history模式:hash模式路径中有#,兼容性强,分享链接时存在被屏蔽或无法识别的风险;history兼容性较差,刷新时会报404,主要是由于请求的路径并不是一个真实的路径,所以无法找到具体的文件,需要重新rewrite到index.heml后再通过路由处理请求资源