一.安装相关
全局安装脚手架:npm install -g vue-cli
创建一个基于 webpack 模板的新项目: vue init webpack my-project
下载依赖:npm install …
二.组件结构
<template> //vue2中必须有根元素包裹所有代码,类似与react的render函数中
HTML 表达式{{ }},
v-link,
v-for, vue1中支持返回$index,vue2不支持,同时vue2支持循环重复元素
v-mode,
v-if, v-else(同angular 增删dom) v-else必须跟在v-if/v-show后面 否则无法识别
v-show
v-on: 监听DOM事件 缩写@
<a v-on:click="doSomething">
filterBy filterKey: 配合指令实现,根据filterKey作为筛选条件
vue2中删除了内置过滤器,保留自定义过滤器(传参有区别):
Vue.filter('toDou',function(n){
//alert(input);
return n<10?'0'+n:''+n;
});
v-bind: 缩写:
<a href="javascripit:void(0)" v-bind:class="activeNumber === n + 1 ? 'active' : ''">{{ n + 1 }}</a>
过滤器(形式同angular) {{ message | reverse | uppercase }}
</template>
<script> import export 逻辑处理
new Vue({ //创建vue实例
el: '#app', //el指向view,将vue实例挂载到
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue.js' },
{ text: 'Build Something Awesome' }
]
},
Components:{
‘child-component’:{
Template:”#childComponent”,
Props:{ //定义组件的props属性
Datalist: Array, //props验证
Name: String
}
}
},
Methods: {
},
Events: {
}
})
</script>
<style>样式</style>
三.组件通信
1.父à子:类似与react 通过属性props传值
子组件中定义props:
Components:{
‘child-component’:{
Template:”#childComponent”,
Props:[“name”,”age”]
}
}
对子组件的引用,通过v-bind实现属性绑定:
<child-component v-bind: name=”name” v-bind: age=”age”></child-component>
Props默认是单项绑定,可以使用v-bind: name.sync=”name”来显式指定双向绑定
子à父、子à子:小项目中用事件派发$dispatch()和事件监听$on()就可以解决,但是复杂的大项目呢?(事件派发用法类似于angular 但是vue2中已移除)
Vuex见五:
四.组件访问
父组件访问子组件:
$children: this.$children是一个数组,包含所有子组件的实例
$ref: 子组件使用v-ref指令,为自己声明一个索引ID,方便父组件通过this.refs。索引名 访问到子组件实例,而不用按顺序访问
子组件访问父组件:
$Parent: 访问父组件链上的任意实例,但是在子组件中修改父组件的状态是非常糟糕的方法,
五.Slot
Vue组件的API来源于三部分----props,slot和事件
Props允许外部环境传递数据给组件
事件允许组件触发外部环境的action
Slot允许外部环境插入内容到组件的视图结构内
六.生命周期(vue2)
beforeCreate 组件实例刚刚被创建,属性都没有
created 实例已经创建完成,属性已经绑定
beforeMount 模板编译之前
mounted 模板编译之后,代替之前ready *
beforeUpdate 组件更新之前
updated 组件更新完毕 *
beforeDestroy 组件销毁前
destroyed 组件销毁后
七.Vue2动画: transition 组件
class定义:
.fade-enter{} //初始状态
.fade-enter-active{} //变化成什么样 -> 当元素出来(显示)
.fade-leave{} .fade-leave-active{} //变成成什么样 -> 当元素离开(消失)
钩子函数:
+ beforeEnter(el){
console.log('动画enter之前');
},
enter(el){
console.log('动画enter进入');
},
afterEnter(el){
console.log('动画进入之后');
el.style.background='blue';
},
beforeLeave(el){
console.log('动画leave之前');
},
leave(el){
console.log('动画leave');
},
afterLeave(el){
console.log('动画leave之后');
el.style.background='red';
}
+ <transition name="fade"
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave">
<p v-show="show"></p>
</transition>
如何animate.css配合用?
<transition enter-active-class="animated zoomInLeft" leave-active-class="animated zoomOutRight">
// <p v-show="show"></p>
// <p v-show="show" class='animated></p>
</transition>
多个元素运动:
<transition-group enter-active-class="" leave-active-class="">
<p :key=""></p>
<p :key=""></p>
</transition-group>
八.路由
九. 路由嵌套:
/user/username
const routes=[
{path:'/home', component:Home},
{
path:'/user',
component:User,
children:[ //核心
{path:'username', component:UserDetail}
]
},
{path:'*', redirect:'/home'} //404
];
+ 路由实例方法:
router.push({path:'home'}); //直接添加一个路由,表现切换路由,本质往历史记录里面添加一个
router.replace({path:'news'}) //替换路由,不会往历史记录里面添加
------------------------------------------
十.状态管理
Vuex核心概念:
- The state tree:单一状态树,一个对象就包含全部的应用层级状态。每个应用仅包含一个 store 实例。单状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
- Getters: 用来从 store 获取 Vue 组件数据。
- Mutators: 事件处理器用来驱动状态的变化。
- Actions: 可以给组件使用的函数,以此用来驱动事件处理器 mutations
Vuex工作机制:
用户操作触发action à派发Mutation事件à Mutation触发状态改变àstate触发视图渲染 (单项数据流 类似redux)
创建vuex store:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
// 需要维护的状态
const state = {
notes: [],
activeNote: {},
show: ''
};
const mutations = {
// 初始化 state
INIT_STORE(state, data) {
state.notes = data.notes,
state.show = data.show;
state.activeNote = data.activeNote;
},
// 新增笔记
NEW_NOTE(state) {
var newNote = {
id: +new Date(),
title: '',
content: '',
favorite: false
};
state.notes.push(newNote);
state.activeNote = newNote;
},
// 修改笔记
EDIT_NOTE(state, note) {
state.activeNote = note;
// 修改原始数据
for (var i = 0; i < state.notes.length; i++) {
if(state.notes[i].id === note.id){
state.notes[i] = note;
break;
}
};
},
// 删除笔记
DELETE_NOTE(state) {
state.notes.$remove(state.activeNote);
state.activeNote = state.notes[0] || {};
},
// 切换笔记的收藏与取消收藏
TOGGLE_FAVORITE(state) {
state.activeNote.favorite = !state.activeNote.favorite;
},
// 切换显示数据列表类型:全部 or 收藏
SET_SHOW_ALL(state, show){
state.show = show;
// 切换数据展示,需要同步更新 activeNote
if(show === 'favorite'){
state.activeNote = state.notes.filter(note => note.favorite)[0] || {};
}else{
state.activeNote = state.notes[0] || {};
}
},
// 设置当前激活的笔记
SET_ACTIVE_NOTE(state, note) {
state.activeNote = note;
}
};
export default new Vuex.Store({
state,
mutations
});
创建vuex action
即自定义各种action类型:
function makeAction(type) {
return ({ dispatch }, ...args) => dispatch(type, ...args);
};
const initNote = {
id: +new Date(),
title: '我的笔记',
content: '第一篇笔记内容',
favorite: false
};
// 模拟初始化数据
const initData = {
show: 'all',
notes: [initNote],
activeNote: initNote
};
export const initStore = ({ dispatch }) => {
dispatch('INIT_STORE', initData);
};
// 更新当前activeNote对象
export const updateActiveNote = makeAction('SET_ACTIVE_NOTE');
// 添加一个note对象
export const newNote = makeAction('NEW_NOTE');
// 删除一个note对象
export const deleteNote = makeAction('DELETE_NOTE');
export const toggleFavorite = makeAction('TOGGLE_FAVORITE');
export const editNote = makeAction('EDIT_NOTE');
// 更新列表展示
export const updateShow = makeAction('SET_SHOW_ALL');
创建 Vuex Getters
// 获取 noteList,这里将会根据 state.show 的状态做数据过滤
export const filteredNotes = (state) => {
if(state.show === 'all'){
return state.notes || {};
}else if(state.show === 'favorite'){
return state.notes.filter(note => note.favorite) || {};
}
};
// 获取列表展示状态 : all or favorite
export const show = (state) => {
return state.show;
};
// 获取当前激活 note
export const activeNote = (state) => {
return state.activeNote;
};
以上就是我们 Vuex 的所有逻辑了,在定下了我们需要完成的功能之后,接下来就是只需要在组件中去调用 action 来实现对应的功能了。
十一. 路由 vue-router
import VueRouter from 'vue-router';
import VueResource from 'vue-resource';
// 路由模块和HTTP模块
Vue.use(VueResource);
Vue.use(VueRouter);
const router = new VueRouter();
router.map({
'/index': {
component: App
},
‘/index/home’{
Component:Home
}
});
router.redirect({
'*': '/index'
});
router.start(App, '#app');
十二. 生命周期
beforeCreate(创建前),
created(创建后),
beforeMount(载入前),
mounted(载入后),
beforeUpdate(更新前),
updated(更新后),
beforeDestroy(销毁前),
destroyed(销毁后)
十三. 项目打包
1、修改config里面的index.js里面的productionSourceMap为false,默认情况是true(true代表打包环境是开发环境,可以进行调试;false表示生产环境,正式上线的)
2.在cmd里面运行npm run build,(运行的是build里面的build.js文件)
生成的包放在dist下面
而后在node上调试需要express