最近将Vue进阶文档,vuex和vue-router都看了一遍,重新写了些对初阶知识点的认识,加了些vuex和vue-router的学习心得,文章没有经过排版,先分享,介意的可先逃
框架出现的需求
Web应用日趋复杂化以致前端开发难以单兵作战,此时需要一种统一的规范将所有人紧紧拴在一起,因此框架应运而生
通过框架,团队成员在能在事先规定的接口各行其事,最后能较好将各个部分整合在一起
MVC框架的基本了解
MVC是框架的一种经典范式,将整个Web文件划分3层,每一层相对独立并通过统一接口联系在一起
Model:数据层,专门存放程序数据源,常用JSON格式数据
View:视图层,由HTML+CSS构成的界面
Controller:控制层,处理业务逻辑,是M和V的桥梁,通常负责处理数据与视图的传输
Vue
数据绑定
- {{message}}:文本信息/单个JS表达式
- v-text='dataName':文本信息
- v-html='dataName':html
- v-bind:Attribute='dataName':元素属性值
- v-model='dataName':数据双向绑定
Class与Style绑定
code
处于人道主义,不建议在VM上绑定样式,如有兴趣请看绑定内联样式
流程渲染语句
v-if和v-for专门用来渲染view
- v-if='dataName',为布尔值
- v-show='dataName'
- v-for='todo in todos'
v-if & v-show
二者区别相当于,
经常切换的用v-show
不常切换的用v-if,v-if还有v-else
v-for中的todos可以是数组也可以是对象
v-for
事件绑定
v-on:eventName='method'
demo
组件系统
组件本质是具有预定义项的Vue实例
Vue的组件系统知识点包括:
组件注册,组件间的数据通信
code
构建一个Vue应用
- var app = new Vue(opts)
- opts的data属性被Vue实例所代理,可直接通过app.xxx访问
- 部分opts的属性和方法可通过app.$xxx访问以便和data属性区分
code
过滤器
过滤器只允许在mustache绑定和v-bind中使用,常用于文本转换
计算属性
处理数据的复杂逻辑
data:{
message:'hello world'
},
computed:{
splitStr:function{
return this.message.split(' ')
}
}
splitStr依赖于message,并且有缓存
method可实现同样效果,但不对结果进行缓存
code
计算属性的getter和setter
computed:{
greet:{
get:function(){
return this.message
},
set:function(newVal){
this.message = newVal
}
}
}
观察属性
监视数据变化
code
事件监听
组件
全局注册
局部注册
组件注册时必须包含根节点
注册
组件间的数据通信
props down events up
props down
events up
非父组件通信
动态组件
code
内容分发——slot插槽
code
code2
异步组件
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 require 语法告诉 webpack
// 自动将编译后的代码分割成不同的块,
// 这些块将通过 Ajax 请求自动下载。
require(['./my-async-component'], resolve)
})
const Foo = resolve => {
// require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
// (代码分块)
require.ensure(['./Foo.vue'], () => {
resolve(require('./Foo.vue'))
})
}
const Foo = resolve => require(['./Foo.vue'], resolve)
组件的接口
Props:将外部环境数据传给组件
Events:组件触发事件传递给外部环境
Slots:允许外部环境将内容插入组件中
组件的命名
注册组件和字符串模板,使用kebab-case ,camelCase ,或 TitleCase;
HTML中必须使用kebab-case;
如果组件不含slot,可以在使用组件时直接<my-component/>
render函数
使用javascript方式去创建模板,更加贴近编译器,实际上所有的模板实际都是编译成render函数
render
自定义指令
有的情况下,你仍然需要对纯 DOM 元素进行底层操作,这时候就会用到自定义指令
demo
Vue插件
var Vue = require('vue')
var VueRouter = require('vue-router')
// 不要忘了调用此方法
Vue.use(VueRouter)
####### Vuex
状态管理模式。它采用集中式存储管理应用的所有组件的状态
父子组件的作用域相隔离,数据通信通过props down & event up,但是有以下问题:
多层嵌套组件传参繁琐
采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝
因此,可把组件的共享状态抽取出来,以一个全局单例模式管理
这个全局对象具有以下2个特点:
Vuex 的状态存储是响应式的,状态变化,组件更新
不能直接改变 store 中的状态,只能通过提交方式显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,类似git的commit的追踪
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `
<div>{{ count }}</div>
`,
// actions
methods: {
increment () {
this.count++
}
}
})
通过提交 mutation 的方式,而非直接改变 store.state.count,更明确地追踪到状态的变化
因此可以实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。
code-1
code-2
为什么要使用computed获取state的数据?
因为状态存储是响应式,即时常变化的,对于这类动态数据应该使用computed而不是data
特点
Vuex使用单一状态树,一个对象就包含了全部的应用层级状态,即唯一数据源
之前的组件依赖于全局状态单例,如果在模块化构建系统中,需要为每个组件都导入store,Vue通过store选项,将状态从根组件『注入』到每一个子组件中
如果存在store中state的一些派生状态,即state中的计算属性---getters
权衡全局状态和局部状态!!!
mutations
mutation 必须同步执行,即
store.commit('increment')
//等待函数执行
mutations:{
increment:state => state.count++
}
action实现异步调用mutation原理在于action可以异步调用,从而间接事件mutation的异步调用,本质mutation还是“同步”
异步操作
模块
state是单一状态树,如果数据量过大则不利于维护和观察,store的modules属性允许将state划分为多个模块
每个模块都有自己的state和rootState,但是类似getter、mutation和action是公有方法
modules
表单处理
<input v-model="obj.message">
当input修改Vuex store的值时,由于不是由store.mutation引起的,所以会报错;
解决方案是监听input的input/change事件,然后以载荷的形式store.commit发送消息给mutation
code-1
使用双向绑定的计算属性
code-2
vue-router
开启一个router,在客户端
1.View层创建特定标签的链接
2.JS
定义路由模板,定义路由,将路由配置VueRouter实例,将VueRouter实例配置Vue实例
code-1
如果存在多个用户共用一个模板的情况,只需要变更用户名,则可以使用动态路由
code
由于组件在动态路由中是复用的,所以不会触发created属性,如果想要监听变化,只需要在watch属性下,监听$route参数
code
嵌套路由
有这么个需求,首先识别用户从而渲染用户初始界面Home,根据点击的链接识别不同板块内容而渲染about和profile
code
命名路由
直接写路径太烦,可以通过传递对象的方式去命名路由
code
命名视图
有时需要在同一个路由同级展示多个视图,可以考虑使用命名视图
routes;{
path:'/',
components:{}//要变成components
}
history模式
不加mode:'history',将使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
导航钩子
钩子意味着捕获,导航钩子就是捕获导航变化
可以在全局、某个路由以及某个组件中定义
teardown
响应式机制
如何追踪数据变化
使用Object.defineProperty的getter和setter
每一个组件实例,都有一个watcher实例对象
watcher实例对象作用是将data属性记录为依赖
当data属性的setter调用时,会通知watcher
watcher发出re-render,触发组件的render函数
将render到虚拟DOM Tree
重置data的getter
最后走生命周期
网友评论