MVVM 是 Model-View-ViewModel 的缩写
Model:代表数据模型
View:代表视图
ViewModel :就是连接视图和模型,实现数据的双向绑定
MVC是Model-View-Controller的缩写
Model:代表数据模型
View:代表视图
Controller:Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。
1.(创建前) beforeCreate:实例还没有被完全创建出来之前执行,此时data中的数据和methods中的方法均未被初始化
2.(创建后)created:实例创建完成后立即调用,这时实例已完成以下的配置:数据观测 (data observer),属性和方法的运算。
3.(载入前)beforeMount:在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
4.(载入后) mounted:页面、数据渲染完成,真实dom挂载完成,在此过程中进行ajax交互。
5.(更新前) beforeUpdate:重新渲染之前触发,页面中显示的数据并没有更新,但是内存中的数据已经改变,也就是说此时页面尚未和最新的数据保持同步
6.(更新后)updated:数据已经更改完成,dom 也重新 render 完成,页面中的数据已经和内存中保持一致
7.(销毁前) beforeDestroy:在实例销毁之前调用。实例仍然完全可用
8.(销毁后) destroyed:在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
beforeCreate , created , beforeMount , mounted
在vue的路由配置中有mode选项 最直观的区别就是在url中 hash 带了一个 # 而history是没有#的
mode:"hash";
mode:"history";
1.hash模式:有#号,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。在hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
2.history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。在history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,后端如果缺少对 /items/id 的路由处理,将返回 404 错误。
解决办法:只需在后端(Apache 或 Nginx)进行简单的路由配置,同时搭配前端路由的 404 页面支持。
主要分三种 全局钩子函数、针对单个路由钩子函数、组件钩子函数
(1)全局钩子函数 主要包括 beforeEach 和 aftrEach
beforeEach函数( 进入之前触发 )有三个参数:
router.beforeEach((to, from, next) => {
console.log('beforeEach')
//next() //如果要跳转的话,一定要写上next()
//next(false) //中断当前的导航
//next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。
next() //正常跳转,不写的话,不会跳转
})
aftrEach( 进入之后触发 ):
aftrEach钩子没有 next 方法,不能改变导航
(2)单个路由钩子函数 beforeEnter
写在路由配置中,只有访问到这个路径,才能触发钩子函数
const router = new VueRouter({
routes: [
{
path: '/info',
component: Info,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
(3)组件钩子函数
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当钩子执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
(1)父传子:子组件通过 props 属性,绑定父组件数据,实现双方通信
Vue.component('menu-item',{
props:['objs'],
template:'{
{objs.name}}'
})
var vm = new Vue({
el:"#app",
data:{
objs:{
name:"张三",
sex:'男'
}
}
})
(2)子传父:将父组件的事件在子组件中通过 $emit 触发
{
{text}}
Vue.component('menu-item',{
data(){
return{
text:"子组件传给父组件的内容"
}
},
template:
`
`
})
var vm = new Vue({
el:"#app",
data:{
//子组件传给父组件的内容
text:''
},
methods:{
handle(val){
this.text = val
}
}
})
(3)非父子组件、兄弟组件之间的数据传递 :
实现方式:
编译条件:
性能消耗:
$route : 是路由信息对象,里面主要包含路由的一些基本信息,包括name、meta、path、hash、query、params、fullPath、matched、redirectedFrom
$ router : 为VueRouter实例,想要导航到不同URL,则使用$router.push方法
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。 简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数。
因为js本身的特性带来的,如果 data 是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue实例的数据。如果将 data 作为一个函数返回一个对象,那么每一个实例的 data 属性都是独立的,不会相互影响了
(1)计算属性有缓存,计算属性会把函数执行一次,把结果存起来,依赖的值改变,会重新赋值。
(2)methods是每次模板编译都会执行。只要有响应式属性改变,视图刷新,函数就执行。
(1)数据驱动:ViewModel,保证数据和视图的一致性。
(2)组件系统:应用类UI可以看作全部是由组件树构成的。
优点 :
- 良好的交互体验
- 良好的前后端工作分离模式
- 减轻服务器压力
缺点 :
- SEO难度较高
- 前进、后退管理
- 初次加载耗时多
利用vue-router-auto 路由自动生成插件来实现
- 重复性高的代码建立公共组件
- 定义全局的样式变量,方便做全局修改
- 页面数量多的情况下可安装router-auto自动生成路由
- 保证项目结构清晰,保证文件夹和文件命名规范
采用i18n来解决国际化问题
1.挂载到vue的prototype上。把全局方法写到一个文件里面,然后for循环挂载到vue的prototype上,缺点是调用这个方法的时候没有提示。
2.利用全局混入mixin,因为mixin里面的methods会和创建你的每个单文件组件合并,这样做的优点是调用这个方法的时候有提示。
设置assetsPublicPath将 assetsPublicPath: ‘/’ 改为 assetsPublicPath: ‘./’
用途:防止全局同名CSS污染
原理:在标签加上v-data-something属性,再在选择器时加上对应[v-data-something],即CSS带属性选择器,以此完成类似作用域的选择方式
可以在子组件中加上ref,然后通过this.$refs.ref.method调用
第一种方法:是直接在子组件中通过this.$parent.event来调用父组件的方法
第二种方法:在子组件里用$emit向父组件触发一个事件,父组件监听这个事件
第三种方法:父组件把方法传入子组件中,在子组件里直接调用这个方法
event.currentTarget 指向事件所绑定的元素
event.target 始终指向事件发生时的元素
强制重新渲染 : this.$forceUpdate()
表单提交。可防止用户在请求未及时响应时,多次提交~
(1)事件修饰符
stop(阻止点击事件冒泡)、
prevent(阻止默认事件)、
self(只会触发自己范围内的事件,不包含子元素)、
once(只执行一次)、
capture(与事件冒泡的方向相反、事件捕获由外到内)
...
...
(2)按键修饰符
例子:
自定义按键修饰符
Vue.config.keyCodes.f1 = 112
(1)、router-link
A custom component!
3.使用组件
(1) 采用ES6的import … from …语法或CommonJSd的require()方法引入插件
(2) 使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })
在router目录下的index.js文件中,对path属性加上/:id。
使用router对象的params.id。
解析:.vue文件的一个加载器。
用途:js可以写es6、style样式可以scss或less、template可以加jade等
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for。
(1)computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
(2)当我们需要进行数值计算,并且依赖与其他数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值时都要重新计算。
(1)watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;
(2)当我们需要在数据变化时执行异步或开销较大的操作时,应使用watch。使用watch选项允许我们执行异步操作,限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。watch一般用于监控路由、input输入框的值特殊处理等等,它比较适合的场景是一个数据影响多个数。
提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标.可以是 CSS 选择器,也可以是一个 HTMLElement 实例
当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。
vue.js是不兼容ie8及其以下浏览器,因为用到了ES5中的
Object.defineProperty
(1)、babel-polyfill
安装:npm install --save babel-polyfill;
配置:module.exports = { entry: [“babel-polyfill”, “./src/main.js”] };
main.js中配置:import ‘babel-polyfill’ //放在最顶部,确保全面加载。
(2)、es6-promise
说明:若在项目中使用了ES6 promise对象,它在Chrome、Safari浏览器下可以正常运行,但在360兼容模式、IE内核中不支持;
安装:npm install es6-promise;
配置:在main.js中加入require(‘es6-promise’).polyfill(),用于在node或浏览器中支持ES6 与CommonJS。## 标题
首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。
然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。
域名、协议、端口三者只要有一个不同则为跨域,否则为同源。
1.后台更改header
header(‘Access-Control-Allow-Origin:*’);//允许所有来源访问
header(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式
2.使用jsonp
3.添加cors服务
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。可以理解成全局的公共状态
1、vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2、改变 store 中的状态的唯一途径就是显式地提交 (commit)mutation。这样使得我们可以方便地跟踪每一个状态的变化。且必须是同步函数
3、Action用于提交Mutation,并非直接改变State,他可以进行任何 异步操作,比如axios请求。
4、getter 相当于store中的计算属性。