计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
cache:false-----------关闭缓存,默认为true
getter不执行的情况----------包含计算属性的节点被移除并且模板中其他地方没有再引用该属性,计算属性的getter不会执行。
v-model:
selected单选时------被选中的值放入一个字符串 ‘’
selected多选时------被选中的值放入一个数组 []
绑定class和style:--------字符串 对象 数组:
:class="{'current':currentIndex===$index}“
:class="classMap[item.type]"
:class="ddfe" -----------可以绑定一个返回对象的计算属性
computed:{
ddfe: function(){
return {
'didi-orange': this.didiAge>3 ? true : false,
'didi-large': this.didiMember>1000 ? true : false
}
}
}
jQuery实现动画效果:-----------添加或删除元素的类,搭配css中定义好的样式
.scrollDown{
animation:scrollCss01 .4s;
-webkit-animation:scrollCss01 .4s;
animation-fill-mode: forwards;
}
@-webkit-keyframes scrollCss01 /* Safari and Chrome */
{
0% {bottom:0px;}
100% {bottom:-92px;}
}
.scrollUp{
animation:scrollCss02 .4s;
-webkit-animation:scrollCss02 .4s;
animation-fill-mode: forwards;
}
@-webkit-keyframes scrollCss02 /* Safari and Chrome */
{
0% {bottom:-92px;}
100% {bottom:0px;}
}
过渡:
<transition name="slide-fade">
<p v-if="show">hello</p>
</transition>
/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
动画:
<transition name="bounce">
<p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.</p>
</transition>
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。
否则,它们将被同步调用,过渡会立即完成。
事件修饰符:
prevent--------------event.preventDefault()阻止事件的默认行为,提供.prevent事件修饰符使之在HTML中便能完成操作
stop-----------------event.stopPropagation()阻止事件冒泡
capture--------------捕获模式
self-----------------只当事件在该元素本身(而不是子元素)触发时触发回调
组件:
1)使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
// 创建构造器
var Profile = Vue.extend({----------------Vue.extend()组件构造器
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
2)注册或获取全局组件:------------Vue.component()全局注册组件
// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* ... */ }))
// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', { /* ... */ })
// 获取注册的组件 (始终返回构造器)
var MyComponent = Vue.component('my-component')
3)局部注册-----------让组件只能用在其他组件内,不是全局注册。components方法进行局部注册。
import shopcart from 'components/shopcart/shopcart';
import cartcontrol from 'components/cartcontrol/cartcontrol';
import food from 'components/food/food';
components: {------------components方法进行局部注册。
shopcart,
cartcontrol,
food
},
数据传递:
props--------父组件传数据
组件通信-----this.$parent this.$children this.$root this.$refs.child
slot---------slot挂载点的内容是由父组件决定的。
具名slot-------多个slot可以有不同的名字。具名slot将匹配内容片段中有对应slot特性的元素。
混入:
// 定义一个混入对象
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
mixins: [myMixin]-------------作为选项混入
})
var component = new Component() // => "hello from mixin!"
谨慎使用全局混入对象,因为会影响到每个单独创建的 Vue 实例 (包括第三方模板)。
大多数情况下,只应当应用于自定义选项,就像上面示例一样。
动态组件:
有的时候,在不同组件之间进行动态切换是非常有用的
上述内容可以通过 Vue 的 <component> 元素加一个特殊的 is 特性来实现:
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>
重新创建动态组件的行为通常是非常有用的,但是在这个案例中,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。
为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
异步组件:
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。
为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。
Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// 向 `resolve` 回调传递组件定义
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})
这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
Vue.component(
'async-webpack-example',
// 这个 `import` 函数会返回一个 `Promise` 对象。
() => import('./my-async-component')
)
当使用局部注册的时候,你也可以直接提供一个返回 Promise 的函数:
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
处理加载状态:
这里的异步组件工厂函数也可以返回一个如下格式的对象:
const AsyncComponent = () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: import('./MyComponent.vue'),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
资源命名约定:
html特性的名字和标签的名字不区分大小写,使用kebab-case不使用camelCase形式。
vuejs支持资源的名字使用camelCase或者PascalCase形式,并且在模板中自动转换为kebab-case形式。
webpack可以自动将.vue文件编译成正常的javascript代码,只需要在webpack中配置vue-loader即可。
表单校验:
vue-validator 2.1.3插件对表单进行校验。
npm install vue-validator
var Vue = require('vue')
var VueValidator = require('vue-validator')
Vue.use(VueValidator)----------注册插件
vue-router:
Transitions:
<transition>
<router-view></router-view>
</transition>
Per-Route Transition:
const Foo = {
template: `
<transition name="slide">
<div class="foo">...</div>
</transition>
`
}
const Bar = {
template: `
<transition name="fade">
<div class="bar">...</div>
</transition>
`
}
启动-----------start(App, el)
路由映射-------On(path, config)
重定向---------Map(routerMap)
路由切换-------go(path)
路由匹配:
动态路由匹配Dynamic Route Matching:
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
// dynamic segments start with a colon
{ path: '/user/:id', component: User }
]
})
Now URLs like /user/foo and /user/bar will both map to the same route.
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:
const User = {
template: '...',
watch: {
'$route' (to, from) {------------------watch (监测变化) $route 对象
// 对路由变化作出响应...
}
}
}
或者使用 2.2 中引入的 beforeRouteUpdate 守卫:
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
动态加载路由组件:
router.map({
'/async': {
component: function(resolve){
resolve(MyComponent)
require(['./MyComponent.vue'], function(MyComponent){})-------AMD风格的require
require(['./MyComponent.vue'], resolve)
}
}
})
全局守卫:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
当一个导航触发时,全局前置守卫按照创建顺序调用。
守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
全局后置钩子:
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
router.afterEach((to, from) => {
// ...
})
路由独享的守卫:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
组件内的守卫:
最后,你可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter--------------beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next来访问组件实例。
在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteUpdate (2.2 新增)---------this 已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteLeave---------------------this 已经可用了,所以不支持传递回调,因为没有必要了。
vue-cli:----------------项目脚手架工具,支持通过模板来生成项目结构。
全局安装:
npm install -g vue-cli
使用vue-cli生成一个基于webpack构建的项目:
vue init webpack my-project
进入项目目录:
cd my-project
安装项目的依赖:
npm install
启动项目:
npm run dev
测试开发与调试:
测试工具:
ESLint:
1)Environments----脚本将要运行的环境
2)Globals--------脚本运行期间需要额外加入的全局变量
3)Rules----------配置规则是否生效来定义项目需要使用的规则
eslint-loader
Scrat + Vuejs:-----------------多人协助开发框架
vue2.0:
v-for:-----------value in obj, (value, key) in obj, (value, key, index) in obj
服务端渲染:
新增方法renderToString(component, done)--------在服务端把Vue组件component渲染成DOM字符串。
可以在done的回调函数中拿到渲染好的DOM字符串。
新增方法renderToStream(component)--------返回一个渲染流,是一个可读的stream,可以直接pipe到HTTP Response中。
app非常复杂时也不会阻塞服务器的event loop,能确保服务端的响应度。
1)首屏渲染速度更快
2)SEO
3)减少HTTP请求
源码util-------
env
dom
components
lang
debug
options
响应式原理:
模型Model----------data方法返回的{}
视图View-----------最终在浏览器中显示的DOM
Model-----------Observer Dep Watcher Directive 一系列对象的关联-------视图
Observer-------对data监听,并且提供订阅某个数据项变化的能力
template-------编译成一段document fragment, 解析其中的Directive---------得到每一个Directive依赖的数据项和update()方法
watcher--------结合上述两部分。
Directive中的数据依赖通过watcher订阅在对应数据的Observer的Dep上
数据变化时---------触发Observer的Dep上的notify方法,通知对应的watcher的update--------进而触发Directive的update方法----更新DOM视图
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
nextTick()------------在这个方法的回调函数中,我们可以放心的操作更新后的DOM对象。
计算属性----------并不是简单的getter,会持续追踪它的响应依赖。
计算一个属性时-------vuejs更新它的依赖列表并缓存结果。
当其中一个依赖发生变化-------缓存的结果无效。
依赖不发生变化---------------访问计算属性直接返回缓存的结果。而不是调用getter.
cache:false-----------计算属性关闭缓存。希望每次访问计算属性的时候都调用getter,并且不修改它的响应依赖。
只有在javascript中每次访问是更新的。数据仍然是依赖驱动的。如果模板中绑定了该计算属性,只有响应依赖变化才会更新DOM。