
基本代码 和 MVVM 之间的对应关系
- Model:模型层,这里表示JavaScript对象
- View:视图层,表示DOM(HTML操作的元素)
- View Model: 连接视图和数据的中间件,Vue.js就是MVVM中的View Model层的实现
在MVVM模式中,是不允许数据和视图直接通信的,只能通过View Model来通信,而View Model就是定义了要给Observer观察者
View Model能观察到数据的变化,并对视图对应的内容实时更新
View Model能监听到视图的变化,并能够通知数据发生改变
SO,Vue.js就是一个MVVM的实现者,其核心就是实现了DOM监听 与 数据绑定
vue指令
指令名称 | 用法 |
---|---|
v-text | 用于渲染普通文本 |
v-html | 更新innerHTML |
v-show | 根据表达式的真假切换display |
v-if | 根据表达式的值有条件的渲染 |
v-else | 限制:前一兄弟元素必须有 v-if 或 v-else-if |
v-else-if | 限制:前一兄弟元素必须有 v-if 或 v-else-if |
v-for | 基于源数据多次渲染元素或模板块 |
v-on | 绑定事件监听器,缩写@ |
v-bind | 动态地绑定一个或多个 attribute,缩写: |
v-model | 在表单控件或者组件上创建双向绑定 |
v-slot | 提供具名插槽或需要接收 prop 的插槽 |
v-pre | 跳过这个元素和它的子元素的编译过程 |
v-cloak | 这个指令保持在元素上直到关联实例结束编译 |
v-once | 只渲染元素和组件一次 |
自定义指令
1.全局注册自定义指令:它作用在全局,写法是在vue实例之前,用Vue点出来一个directive()方法,directive不用加s,在这个方法里传入两个参数,第一个是指令名,指令名要求是字符串,第二个参数是一个对象,在对象里属性写钩子函数,这很像我们ajax里面的success回调函数,在钩子函数里传入参数(如el,binding,vnode,oldVnode),根据参数来做我们想做的事情.
语法:
Vue.directive('focus',{
inserted:function(el){
el.focus()//添加焦点事件,也可以给dom元素添加其它,比如input标签中用到el.value='请输入内容'
}
})
注意:全局注册是没有directive是没有s,局部注册是有s
2.局部注册自定义指令:作用在局部,默认只会在当前页面的vue实例生效,写法跟全局不同,它是写在vue实例里面,里面是用directives,这是要加s变为复数,指令名也不用字符串格式,指令名和directives都是以对象的形式来写,里面的钩子函数写法就跟全局一样了.
语法:
directives:{
content:{
inserted:el=>{
el.value='请输入内容';
}
}
}
3.当指令写好之后,直接在html元素里使用v-指令名即可
<div id="app">
<input v-focus>
</div>
钩子函数 :
-
bind
只调用一次, 当指令第一次绑定在元素上时.
用来做一次性初始化操作. -
inserted
当绑定元素已插入到父节点时调用.
也就是说 必定存在父节点.
但是 它 及它的父节点 未必存在文档中. -
update
在包含该组件的VNode更新后调用该函数.
可能在其子级更新前调用.
指令的值可能已更改,可能未更改.最好通过判断新旧值来 过滤掉不必要的操作. -
componentUpdated
在包含该组件的VNode 以及 其子节点的VNodes已更新之后 调用. -
unbind
指定从元素上解绑时,调用一次.
钩子函数参数
- el:指令所绑定的元素,可以用来直接操作 DOM。
- binding:一个对象,包含以下 property:
2.1. name:指令名,不包括 v- 前缀。
2.2. value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
2.3. oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
2.4. expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
2.5. arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
2.6. modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。 - vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
注意 :
这些参数中, 除了 el 以外 , 其他参数都看做是只读参数.即不要修改它们.
如果 需要跨钩子 使用它们, 建议使用 dataset 来实现.
Vue的生命周期
vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。在组件中具体的方法有:
Vue.js Ajax
vue-resource
Get 请求
实例:
window.onload = function(){
var vm = new Vue({
el:'#box',
data:{
msg:'Hello World!',
},
methods:{
get:function(){
//发送get请求
this.$http.get('/try/ajax/ajax_info.txt').then(function(res){
document.write(res.body);
},function(){
console.log('请求失败处理');
});
}
}
});
}
post 请求
实例:
window.onload = function(){
var vm = new Vue({
el:'#box',
data:{
msg:'Hello World!',
},
methods:{
post:function(){
//发送 post 请求
this.$http.post('/try/ajax/demo_test_post.php',{name:"菜鸟教程",url:"http://www.runoob.com"},{emulateJSON:true}).then(function(res){
document.write(res.body);
},function(res){
console.log(res.status);
});
}
}
});
}
axios
GET 方法
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get('https://www.runoob.com/try/ajax/json_demo.json')
.then(response => (this.info = response))
.catch(function (error) { // 请求失败处理
console.log(error);
});
}
})
POST 方法
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.post('https://www.runoob.com/try/ajax/demo_axios_post.php')
.then(response => (this.info = response))
.catch(function (error) { // 请求失败处理
console.log(error);
});
}
})
vue动画
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。
过渡的类名
进入类
v-enter | 进入过渡的开始状态 |
v-enter-active | 进入过渡的激活状态 |
v-enter-to | 进入过渡的结束状态 |
离开类
v-leave | 离开过渡的开始状态 |
v-leave-active | 离开过渡的激活状态 |
v-leave-to | 离开过渡的结束状态 |
自定义过渡的类名
vue提供了6个专门用于设置过渡效果的class选择器名
<transition
before-enter-class=''
enter-class=''
after-enter-class=''
before-leave-class=''
leave-class=''
after-leave-class=''
>
</transtition>
JavaScript 钩子
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
组件
Vue中的组件技术类似于后端开发中常用的一些工具类或方法,如果一个方法或功能在多个地方要用到,我们就需要将其进行抽离出来,在Vue中,组件就是一种很好的复用一个功能的手段。比如页面上的按钮、输入框等都可以以组件的形态存在,以供多个页面去复用使用。
注册组件
- 创建组件放在后面讲,先看下注册组件。首先假设存在一个已经开发好的组件M(可能是个人开发的,也可能是别人开发的,亦可能是通过npm
install安装的第三方库的组件),在我们的项目中如何去注册。 - 组件注册主要分全局注册和局部注册。
- 全局组件通常使用 Vue.component(tagName, {options})的格式注册;
- 局部组件则在实例中的components中注册。
注意:
要确保在初始化根实例之前注册了组件,即:先注册组件,再初始化Vue实例;
建议将组件提取出来放在单独js文件中,按需引用。
组件传值
如果页面A上使用某个组件M,统一称呼的口径,全文约束调用方页面A为父组件,被调用方组件M称之为子组件。
组件使用和开发的核心就是父子组件的数据传递(通信)问题,按照数据传递方向可分为三类:
- 父组件(调用方)与子组件(被调用方)的数据传递:props
- 子组件向父组件传递数据:$emit()
- 子组件与子组件(兄弟组件)数据传递:vuex
注意:
1.子组件中的驼峰命名的 prop 名在父组件赋值的时候需要使用其等价的短横线分隔命名;
2.props如果不加类型校验则是一个数组;若加上类型校验则是一个对象。
子–>父组件 :$emit()
props里面的属性字段值是单向的,只能是父组件传递给子组件,如果在子组件对其进行修改父组件是无感知的。子组件如果想跟父组件进行反馈,通过在子组件利用emit()定义一个事件回调函数。
vue路由
路由,其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的内容,如果点击页面上的about 按钮,页面中就要显示about 的内容。Home按钮 => home 内容, about按钮 => about 内容,也可以说是一种映射. 所以在页面上有两个部分,一个是点击部分,一个是点击之后,显示内容的部分。
点击之后,怎么做到正确的对应,比如,我点击home 按钮,页面中怎么就正好能显示home的内容。这就要在js 文件中配置路由。
路由中有三个基本的概念: route, routes, router。
- route,它是一条路由,由这个英文单词也可以看出来,它是单数, Home按钮 => home内容, 这是一条route, about按钮 => about 内容, 这是另一条路由。
- routes 是一组路由,把上面的每一条路由组合起来,形成一个数组。[{home 按钮 =>home内容 }, { about按钮 => about 内容}]
- router 是一个机制,相当于一个管理者,它来管理路由。因为routes 只是定义了一组路由,它放在哪里是静止的,当真正来了请求,怎么办? 就是当用户点击home 按钮的时候,怎么办?这时router 就起作用了,它到routes 中去查找,去找到对应的 home 内容,所以页面中就显示了 home 内容。
路由的实现
在vue中实现路由还是相对简单的。因为我们页面中所有内容都是组件化的,我们只要把路径和组件对应起来就可以了,然后在页面中把组件渲染出来。
页面实现
- html模板中
在vue-router中, 我们定义两个标签<router-link>
和<router-view>
来对应点击和显示部分。<router-link>
就是定义页面中点击的部分,<router-view>
定义显示部分,就是点击后,区配的内容显示在什么地方。所以
<router-link>
还有一个非常重要的属性 to,定义点击之后,要到哪里去, 如:<router-link to="/home">
Home</router-link>
- js 中配置路由
首先要定义route, 一条路由的实现。它是一个对象,由两个部分组成: path和component. path 指路径,component 指的是组件。如:{path:’/home’, component: home}
过滤器
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。
过滤器可以用在两个地方:双花括号插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
// 在双花括号中
{{ message | capitalize }}
// 在 `v-bind` 中
<div v-bind:id="rawId | formatId"></div>
过滤器函数总接收表达式的值 (之前的操作链的结果) 作为第一个参数。
过滤器可以串联:
{{ message | filterA | filterB }}
在这个例子中,filterA 被定义为接收单个参数的过滤器函数,表达式 message 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB,将 filterA 的结果传递到 filterB 中。
过滤器是 JavaScript 函数,因此可以接收参数:
{{ message | filterA('arg1', arg2) }}
这里,filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 ‘arg1’ 作为第二个参数,表达式 arg2 的值作为第三个参数。
注:当全局过滤器和局部过滤器重名时,会采用局部过滤器。