# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
项目来源:慕课网 - Vue2.5开发去哪网app 文档说明:1.记录知识细节;2.归纳学习心得。
node -v
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
node -v
sudo npm install npm@latest -g
node -v
npm -v
- jQuery是基于传统MVP(或叫MVC、MVX)前端架构模式,即数据层(Model)、视图层(View)、控制层(Presenter),开发中绝大部分是在写控制层代码,通常是通过ajax请求实现与数据层的交互,以及通过dom操作实现对视图层的渲染。
- Vue是基于MVVM架构模式,即数据层、视图层、VM层,VM由Vue核心代码实现,负责监控数据的改变并映射至视图层(数据绑定),以及监听视图层的交互操作并调用相应的事件(Dom监听)。鉴于VM已交由Vue管控,以及VM的特点,所以实际Vue开发中主要是对数据层的操作。
- 简单来说,jQuery是面向dom编程,而Vue是面向数据编程。
页面跳转 —— 返回html 优点:首屏时间快,SEO效果好 缺点:页面切换慢
页面跳转 —— JS渲染 优点:页面切换快 缺点:首屏时间稍慢,SEO效果差 (Vue服务器端渲染可解决上述缺点)
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
引入 reset.css ‘/src/assets/style/reset.css’
引入 border.css ‘/src/assets/style/border.css’
import fastClick from 'fastclick'
fastClick.attach(document.body)
rem(root em,根em)是css3新增的相对长度单位,它的取值始终相对于html的font-size值,这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免em字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。下面就是一个例子:p {font-size:14px; font-size:.875rem;}
1rem = html 的font-size
例如 二倍屏,设计稿中height为86px,则css设置应为 height: 43px;
若 html{font-size: 50px;} 那么 1rem = 50px, height = 43px = .86rem
注:任意浏览器的默认字体都是16px
let vm = new Vue({
el: '#app',
data: {
arrList: ['a', 'b', 'c']
}
})
vue中直接操作:
vm.arrList[1] = 'd'
是无效的。
- vue中动态操作数组的方法只有七个:
- push 尾部添加
- pop 尾部删除
- unshift 头部添加
- shift 头部删除
- splice 增删改原数组
- sort 排序
- reverse 倒序
- 或者使用vue提供的set方法:
Vue.set(vm.arrList, 1, 'd')
或
vm.$set(vm.arrList, 1, 'd')
- 或者修改数组的引用,即:
vm.arrlist = ['a', 'd', 'c']
达到将‘b’动态改为‘d’的目的。
let vm = new Vue({
el: '#app',
data: {
arrList: {
userInfo: {
name: 'Jerry',
age: '28',
gender: 'male'
}
}
}
})
vue中直接操作:
vm.userInfo.age = '29'
是无效的。
- vue中提供了set方法来动态修改对象:
Vue.set(vm.userInfo, 'age', '29')
或
vm.$set(vm.userInfo, 'age', '29')
- 或者修改对象的引用,即:
vm.userInfo = {
name: 'Jerry',
age: '29',
gender: 'male'
}
达到将‘28’动态改为‘29’的目的。
通过属性传值
<child :prop-name="1"></child>
Vue.conponent('child', {
props: [ propName ]
template: '<div>{{propName}}</div>''
})
通过事件触发
<child @change="handleChange"></child>
Vue.conponent('child', {
template: '<div onclick="handleClick">1</div>',
methods: {
handleClick: function() {
this.$emit('change', 2)
}
}
})
methods: {
handleChange: function(value) {
alert(value) // 2
}
}
通过发布订阅模式——总线机制
<child content="Jerry"></child>
<child content="Zhang"></child>
// 创建总线
Vue.prototype.bus = new Vue()
Vue.conponent('child', {
props: {
content: String
},
data: function() {
return {
selfContent: content // 子组件不可直接操作父组件传递的参数
}
},
template: '<div onclick="handleClick">{{selfContent}}</div>',
methods: {
handleClick: function() {
this.bus.$emit('change', selfContent) // 发布至总线
}
},
mounted: {
var self = this
this.bus.$on('change', function(msg) { // 总线上订阅
self.selfContent = msg
})
}
})
让is等于子组件名
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
<tbody>
</table>
Vue.component('row', {
template: '<tr><td>this is a row</td></tr>'
})
Vue.component('row', {
data: function() {
return {
content: 'this is a row'
}
},
template: '<tr><td>{{content}}</td></tr>'
})
原因是:子组件不同与根组件只被调用一次,子组件会被多次调用,而每次调用时数据应该是独立的,不能是同一个数据(同一个数据会导致一个组件的数据改变了,其它子组件数据也会受到影响)。通过返回一个对象,实现每个子组件拥有一个独立的数据存储。
<div ref="hello" @click="handleClick">
hello world
</div>
methods: {
handleClick: function() {
console.log( this.$refs.hello.innerHtml ) // hello world
}
}
若ref添加在子组件上,获得的是组件实例的引用:
<row ref="one" @click="handleClick"></row>
Vue.component('row', {
data: function() {
return {
number: 1
}
},
template: '<div>{{number}}</div>'
})
methods: {
handleClick: function() {
console.log( this.$refs.one ) // 得到的是row组件实例
console.log( this.$ress.one.number ) // 得到的是row组件实例的数据number
}
}
<counter :count="12"></counter> // 当加“:”时,传递的是数字12,不加“:”时,传递的是字符串"12"。
原因:添加“:”即v-bind:count="12",v-bind会使得引号里的是一个表达式。
生命周期函数就是Vue实例在某个时间点会自动执行的函数
let vm = new Vue({
el: '#app',
// beforeCreate 初始化事件、生命周期相关内容后(基础初始化)
beforeCreate: function() {
console.log('beforeCreate')
},
// created 初始化依赖注入(provide/inject)、双向绑定相关内容
created: function() {
console.log('created')
},
// beforeMount 将模板和数据挂载到挂载点进行渲染之前
beforeMount: function() {
console.log('beforeMount')
},
// mounted 页面挂载之后
mounted: function() {
console.log('mounted')
},
// deforeDestroy 当调用vm.$destroy()即将销毁实例时
deforeDestroy: function() {
console.log('deforeDestroy')
},
// destroyed 当调用vm.$destroy()已经销毁实例时
destroyed: function() {
console.log('destroyed')
},
// beforeUpdate 数据改变,虚拟dom重新渲染之前
beforeUpdate: function() {
console.log('beforeUpdate')
},
// updated 数据改变,虚拟don重新渲染之后
updated: function() {
console.log('updated')
}
})
overflow: hidden; // 当poadding-bottom百分比值计算的不准确时,可隐藏超出的部分
width: 100%;
height: 0;
poadding-bottom: 30%; // padding取值为百分比时,参照的是父元素的宽度
或
width: 100%;
height: 30vw; // 浏览器兼容性不好
当我们想要在父组件scoped限定的style中,修改子组件的样式时,可使用样式穿透符‘>>>’
.father-classname >>> .son-classname {
background: #fff;
}
// 为元素设置
min-width: 0;
通过this.$refs.name获取的循环中的ref,得到的是一个数组,需要获取该数据的第0个元素才行。
if (this.timer) { clearTimeout(this.timer) } this.timer = setTimeout(() => { ... }, 16)
由于现在广泛使用的屏幕都有固定的刷新率(比如最新的一般在 60Hz),在两次硬件刷新之间浏览器进行两次重绘是没有意义的只会消耗性能。浏览器会利用这个间隔 16ms(1000ms/60)适当地对绘制进行节流, 因此 16ms 就成为页面渲染优化的一个关键时间。
核心思想:将应用程序的所有组件状态(或公共数据)集中存储在state对象中,通过特定的接口改变state中的公共数据,从而实现相应组件状态/数据的改变。
核心概念:
- State - 用于集中存储状态/数据的对象。
- Getter - 用于根据state中的值,计算出新的值。相当于vue中的计算属性computed。
- Mutations - 用于集中存放修改state值的事件方法,这些方法通过store.commit('funName', canshu)来触发。
- Actions - 用于存放提交Mutations的事件方法,这些方法通过store.dispatch('funName', canshu)来触发。
- Module - 用于将复杂store分隔成模块,每个模块具有完整的vuex属性(state、getter、mutations、actions)。