父 => 子 传值
父组件中定义属性 <com-a :aaa="parm"> ,子组件通过 props:['aaa'] 获取
子 => 父 传值
父组件中自定义事件 <com-a @aaa="parm"> ,子组件通过 methods:{this.$emit('aaa',要传的值)}向父元素传值
v-test / v-html
v-test:所有内容转换为字符串输出
v-html:如果有标签就按标签转换
组件中为什么 data(){return{}} 而不是 data:{}
防止修改 data 内容时由于引用传值导致误改了其他 template 组件
v-if / v-show
v-if 标签有 / 没有
v-show 通过 display:none 控制
其他
<template lang="jade"> 使用 jade 模板
<style lang="less"> 使用 less 语法
watch
属性监听
data(){
abc:'',
}
watch:{
abc:function(val,oldval){
// 当 abc 发生变化时触发函数,可通过两个参数获取到变化前后的值
}
}
计算属性有两种方法(视频第三章 5-7 节后半部分)
computed- 自定义方法,实时调用
插槽
-
<slot>:将要插入的内容放到子组件标签中,在子组件中使用<slot></slot>。 - 可命名 :
<p slot="head"></p>,对应子组件中<slot name="head"></slot>
缓存标签内的信息
<keep-alive></keep-alive>
组件的动态切换
<p :is="currentView"></p>
data(){
return{
currentView:'com-a'
}
}
通过对 currentView 动态切换实现组件切换,这里 com-a 是写好的组件
过渡效果
- 通过
<transition name="aa">内置组件,组件可以命名,可以通过两种方式实现,需要给过渡的作用标签加上v-show或者v-if- CSS 过渡
- JS 过渡
- CSS 过渡 官网有个图非常直观,对比官网例子

整个过程可分为:
1.刚开始淡入
2.完全显示
3.完全消失
.fade-enter 刚要进入的瞬间 => 1
.fade-leave-to 完全离开的瞬间 => 3
.fade-enter-active { // 进入的过程
transition: all .5s ease;
}
.fade-leave-active { // 离开的过程
transition: all .5s ease;
}
.fade-enter { // 刚进入的瞬间
transform:translateX(200px);
opacity: 0
}
.fade-leave-to { // 离开终点的瞬间
transform: translateX(200px);
opacity: 0
}
- 当使用
is 属性 + transition实现组件切换的过渡效果时,<transition>有个默认的属性mode="in-out",这样的效果是:新组件先进入,而旧组件后消失,这样会有个效果上的不和谐。改成mode="out-in"就好 - 多个标签或者组件进行过渡切换时,如果标签名相同,比如两个
<p>标签切换显示隐藏,并且标签上没有key属性时,切换效果会无效。这是由于vue最大化重用标签或组件,实际上是针对一个<p>标签进行操作,所以需要在两个<p>标签加上不同的key属性作为区分,避免重用 - 当
<transition>与<keep-alive>共用时,需要<transition>在外
自定义指令
- 局部自定义指令 - 写在某个组件中
- 全局自定义指令 - 写在根节点实例化时
new Vue时(main.js中)<p v-color="'red'">自定义指令</p> // 注意传的是字符串red,所以写的是 'red'(带引号) ... directives:{ color:function(el,binding){ el.style.color = binding.value } } -
el:指令所绑定的元素,可以用来直接操作DOM -
binding:一个对象,包含name,value等多个属性 - 指令定义函数提供了几个钩子函数(见官网):
-
bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
-
插件
- 安装方法
-
npm install vue-router --save(--save是安装插件后,让package.json中同步更新) - 在全局中引用
vue-router-
main.js中最上面import VueRouter from 'vue-router' -
main.js中加入Vue.use(VueRouter)
-
-
Vue - cli
-
npm install vue-cli -g全局安装 -
vue init webpack新建项目名 初始化项目 -
npm install安装项目依赖 -
npm run dev在localhost启动测试服务器 -
npm run build(部署)
Vue - router
写在
<router-link>中的是 声明式导航,另一种是写在
JS中的 编程式导航this.$route.path// 全部的路径值-
this.$route.params// 带:的部分
console.log(this.$route.params) // Object {color: "xxxx", name: "xxx"}{ path: '/apple/:color/ok/:name', name: 'apple', component: Apple } -
子路由的匹配方式
- 如果配置中设置了
name属性(也就是 命名路由),则也可以在<router-link :to="{name:"xxx"}" tag="li">中通过name属性调用。其中tag属性可以将默认的<a>改为<li>。 - 命名路由 / 命名视图
// 命名路由 <router-link :to="{name:'apple2'}"> 命名路由 </router-link> { path: '/apple', name: 'apple2', component: Apple, children:[ { path:'applechild', component:applechild }] }// 命名视图 <router-view name="viewA"></router-view> <router-view name="viewB"></router-view> // index.js 中 path: '/apple', name: 'apple2', components: { viewA: Apple, viewB: Banana }, - 如果配置中设置了
可以在标签中通过类似
<p>{{$route.params.color}}</p>语法调用
此外,一旦添加了诸如:color这种参数,<router-link>中to属性值必须格式完全匹配index.js中的路径地址(如上例中,url地址必须为
/apple/param1/ok/param2),否则不会跳转到响应的组件,注意看to需不需要加:-
正常跳转的时候会有
hash的#,通过在index.js中设置mode: 'history',即可export default new Router({ mode:'history', routes:[{ ... }] }) -
编程式导航
- 在
index.js中通过router.push({path:'xxx'})实现 - 也可以配合
Vue-router的钩子函数,比如router.beforeEach()可以实现跳转之前先执行一个判断之类的
- 在
-
重定向
- 当访问根目录时,自动跳转到
apple路由
{ path: '/', redirect:'apple', // 重定向 name: 'Hello', component: Hello }, - 当访问根目录时,自动跳转到
router-link-active
Vuex

$ cnpm install vuex --save- 在
main.js(入口文件)中引入
// main.js
import Vuex from 'vuex' // 1. 引入
Vue use (Vuex) // 2. 注册
let store = new Vuex.store({
// 3. 配置
mutations:{
fn1(){
...
},
fn2(){
...
},
}
})
new Vue({
el: '#app',
router,
store, // 4. 全局使用
template: '<App/>',
components: { App }
})
// 子组件中
this.$store.state // 5. 在子组件中调用 store 中的状态
this.$store.commit('fn1',传值) // 6. 可以通过 commit 调用 store 中 mutations 内的各种方法,进而改变 store 中的参数
this.$store.commit('fn2',传值)
- 关于
mutations和actions
mutations用来直接管理state的,因此mutations是 同步 的(mutations内的方法是一行一行执行)
actions用来调用mutations中的方法,是 异步 的(actions中的某个方法在执行的过程中可以去请求个数据啥的,不耽误后面代码执行)// <template> 中通过 dispatch 调用 actions 中的方法 plus(){ this.$store.dispatch('increase',100) }, // actions 中 通过 commit 调用 mutations 中的方法 mutations:{ increment (state,price){ state.totalPrice += price }, decrement (state,price){ state.totalPrice -= price }, }, actions:{ increase (context,price){ context.commit('increment',price) } }
-
getters:store中的一个属性。可以通过getters获取到state中的某个状态,进行进一步的操作,比如:state中有个数组,使用getters获取到这个数组,然后对数组进行过滤或者计算啥的let store = new Vuex.Store({ state: { totalPrice:0 }, getters:{ way(state){ return state.totalPrice; } }, // <template> 中调用 this.$store.getters.xxx -
modules:Talk is cheap// 定义 const modulesA = { state:{...}, mutations:{...}, actions:{...}, getters:{...}, } const modulesB = { state:{...}, mutations:{...}, actions:{...}, getters:{...}, } // 配置 let store = new Vuex.Store({ modules:{ a:modulesA, b:modulesB } }) // 调用 store.state.a // moduleA's state store.state.b // moduleB's state - 官方推荐使用
Vuex项目的结构├── index.html ├── main.js ├── api │ └── ... # 抽取出API请求 ├── components │ ├── App.vue │ └── ... └── store ├── index.js # 我们组装模块并导出 store 的地方 ├── actions.js # 根级别的 action ├── mutations.js # 根级别的 mutation └── modules ├── cart.js # 购物车模块 └── products.js # 产品模块
关于双向绑定
- 先进行初始化的数据绑定,将实际的
DOM节点劫持到
documentFragment中 - 响应式数据绑定,主要是实现
input输入内容时,data跟着变化,需要做的就是通过ES5的defineProperty进行数据的观察和修改 - 实现
data改变同步页面中的数据更新,观察者模式,可以是多个观察者对数据进行监听,当数据改变后,会触发一个更新的函数,进而实现页面的更新