把自己的学习使用记录在本地电脑,这次整理出来分享一下。个人认为都是平时工作当中用到的比较多的。希望对你们有帮助。
基础复习
跨域配置: 域名、端口
1、跨域是浏览器之间的, 因为服务器之间是不存在跨域的,所以,配置代理之后,浏览器先发给代理服务器,然后 代理服务器去跟接口交流 就不存在跨域了。
2、 多个请求地址,就在proxy那配置 多个对象就行了。
负载均衡
其实只需要在ngix中添加一个 配置就能解决。
options的根属性
- el:目的地(string||DOM元素)
- template 模板
- data是一个函数,return一个对象, 对象中的key data中的属性...在dom中直接用,在js中 this.xxx
- components: key是组件名,value是组件对象
- methods: 一般用来配合 xxx事件
- props: 子组件接收的参数设置 ['title', 'name']
指令
- v-if: (留坑:
<!---->
插入\移除 ) 和 v-show: (添加样式:display:none
) - v-else-if/v-if: 必须和v-if是相邻的元素
- v-bind/v-on: bind是给属性赋值, v-on 绑定事件
- v-bind:单项数据流(vue -->-html): 对象、数组、三目运算、绑定内联样式
- v-model:双向数据流(vue --> html --> vue):
v-model 指令在<input>
(<input>
标签有多种类型,如 button、select 等等)及<textarea>
元素上进行双向数据绑定。但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。 区别详情
附加功能: 过滤器filter & 监视watch改动
- 过滤器 可以给 数据显示 进行 添油加醋
<!-- 在双花括号中 -->
{{ message | filterA }}
<!-- 在 'v-bind' 中 -->
<div v-bind:id="rawId | filterA"></div>
- 组件的选项中定义本地的过滤器:
filters: {filterA: function (value) {return value}}
- 创建 Vue 实例之前全局定义过滤器:
Vue.filter('filterA', function (value) {return value})
- 监视单个(data)watch 官方详解
- {{ watchfn1: 'xxx' }} //监视xxx并通过watchfn1函数处理输出
- key是属于data属性的属性名,value是监视后的行为
- 基础类型 简单监视、复杂类型 深度 监视
- computed(计算属性) 监视多个(data) 官方详解
- 全局: 组件/过滤器 让大家直接用 全局不带s
- 过滤器: function(原数据,参数1,参数2){return 结果;} 调用 {{ '原数据'| 过滤器名(参数1,参数2) }}
- watch:单个监视
- computed: 群体监视
slot
- 内置的组件
vue响应式原理
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。 这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在属性被访问和修改时通知变更。 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
- 注意:属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的,因为 Vue 会在初始化实例时对属性执行 getter/setter 转化。
异步更新队列 (重灾区)
因为Vue 在更新 DOM 时是异步执行的。如果你想基于更新后的 DOM 状态来做点什么,这就可能会有些棘手。 为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。
Vue.component('example', {
template: '<span>{{ message }}</span>',
data: function () {
return {
message: '未更新'
}
},
methods: {
updateMessage: function () {
this.message = '已更新'
console.log(this.$el.textContent) // => '未更新'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '已更新'
})
}
}
})
vue双向数据绑定原理
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
Vue实现这种数据双向绑定的效果,需要三大模块:
Observer:能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数 Watcher:作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
vue生命周期的执行过程
首先创建一个vue实例,Vue(); 在创建Vue实例的时候,执行了init(),在init过程中首先调用了beforeCreate。
-
beforeCreate:初始化了部分参数,如果有相同的参数,做了参数合并,执行beforeCreate;el和数据对象都为undefined,还未初始化;
-
created:初始化了 Inject、Provide 、props、methods、data、computed和watch,执行created ;data有了,el还没有;
-
beforeMount:检查是否存在el属性,存在的话进行渲染dom操作,执行beforeMount;$el和data都初始化了,但是dom还是虚拟节点,dom中对应的数据还没有替换;
-
mounted:实例化 Watcher,渲染dom,执行mounted;vue实例挂载完成,dom中对应的数据成功渲染;
-
beforeUpdate:在渲染dom 后,执行了mounted 钩子后,在数据更新的时候,执行 beforeUpdate;
-
updated:检查当前的watcher列表中,是否存在当前要更新数据的watcher,如果存在就执行updated;
-
beforeDestroy:检查是否已经被卸载,如果已经被卸载,就直接return出去,否则执行beforeDestroy;
-
destroyed:把所有有关自己痕迹的地方,都给删除掉;
组件传值
父传子
- 在调用组件的时候 绑定一个属性,此属性就可以在 子组件中获取到
<fu-component v-bind:users="users"></fu-component>
- 在子组件中获取并使用:
props: ["users"]
, 这样就可以使用了:<div>User {{ users }}</div>
总结:
- 父用子 先有子,声明子, 使用子。
- 父传子 绑定属性, 子声明(接收), 子直接用。
子传父$emit
- 在子组件注册
this.$emit("eventName","子向父传 值")
; 再父组件上v-on:eventName="xxx($event)"
.- 在eventName事件中就可以写逻辑代码了.
兄弟组件通信
跨多层级组件通信
- provide & inject 父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。
- eventBus模式
而如果两个组件不是父子关系呢?这种情况下可以使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过
bus.$emit
触发事件,bus.$on
监听触发的事件。
- 避免 this.$parent
Vue.js 支持组件嵌套,并且子组件可访问父组件的上下文。访问组件之外的上下文违反了 基于模块开发 的 第一原则 。因此你应该尽量避免使用 this.$parent 。
任意传值使用 vuex
已下有详细讲解
Vue路由
- 首先安装路由
npm install vue-router
- main.js 使用路由
Vue.use(VueRouter)
- 配置路由:
const router = new VueRouter({ routers: [ {path: "/", component: Home}],//配置路由地址 mode: "history" //去除# 配置(发布后刷新404的话就需要服务器配置WEB-INF) })
- 同时在使用的地方加上
<router-view></router-view>
- a标签会重新加载页面,所以 使用
<router-link></router-link>
标签- jsonplaceholder.typicode.com 在线json接口
参数传递
- "动态路径参数"(dynamic segment)
- 路由 参数的声明:
{ path: '**/user/:id**', component: User }
- 参数的获取(使用):
this.$route.params.id
- 捕获所有路由
path: '*'
: 会匹配所有路径path: '/user-*'
: 会匹配以/user-
开头的任意路径.$route.params 内会自动添加一个名为 pathMatch 参数.
- query传参
path:'/componentsB' query:{que:'我是通过query传到组件B的参数'}
页面通过this.$route.query
来获取参数
精讲路由
路由的跳转
1、第一种 router-link 声明式
<router-link to="name"> </router-link>
tag属性 可自定义 显示标签;:to="{name:'xxx',params:{key:value}}"
这种写法就是 根据路由定义的 name来动态获取跳转路由{{this.$route.params.username}}
获取路由参数
2、第二种 编程式
this.$router.go(-1); //跳转到上一次浏览的页面
//不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
this.$router.replace('/index');
this.$router.replace({name: 'routerNmae'}); //指定跳转到路由name
this.$router.push('/index'); //通过push跳转
this.$router.push({name: 'routerNmae'}); //通过push跳转,新增history记录
// 命名的路由params
router.push({ name: 'user', params: { userId: '123' }})-> /user/123
// 带查询参数query,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
二级路由 — 路由嵌套
一般都用作导航
- 1、依然在 路由.js 中import 页面路径
- 2、在需要展示二级的 path中 配置
{path:'/', name:'index', meta:{title:'主页',}, component:index, children:[{path:'/index/xxx',name:"erjiLink",component:routerName}]}
- 3、配置 redirect:'/默认显示路径' -- 重定向
导航守卫
全局守卫
全局前置守卫 使用更多(登录拦截)
router.beforeEach((to, from, next) => { // ... })
路由独享的守卫
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...**进入该页面之前todo**
}
} ]
组件内守卫
- beforeRouteEnter:在渲染该组件的对应路由被 confirm 前调用,不能 访问 this。但是,
next(vm => { // 通过 **vm** 访问组件实例 })
- beforeRouteUpdate (2.2 新增):在当前路由改变,但是该组件被复用时调用
- beforeRouteLeave:导航离开该组件的对应路由时调用
完整的导航解析流程(路由守卫)
导航被触发。
在失活的组件里调用离开守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
组件结构化
按照一定的结构组织,使得组件便于理解。
<template lang="html">
<div class="Ranger__Wrapper">
<!-- ... -->
</div>
</template>
<script type="text/javascript">
export default {
// 不要忘记了 name 属性
name: 'RangeSlider',
// 组合其它组件
extends: {},
// 组件属性、变量
props: {
bar: {}, // 按字母顺序
foo: {},
fooBar: {},
},
// 变量
data() {},
computed: {},
// 使用其它组件
components: {},
// 方法
watch: {},
methods: {},
// 生命周期函数
beforeCreate() {},
mounted() {},
};
</script>
<style scoped>
.Ranger__Wrapper { /* ... */ }
</style>
优化组件
检查所有的事件。子组件向父组件通信一般是通过事件来实现的,但是大多数的开发者更多的关注于 props 从忽视了这点。 Props向下传递,事件向上传递! 。以此为目标升级你的组件,提供良好的 API 和 独立性。
当遇到 props 和 events 难以实现的功能时,通过 this.$refs
来实现。
当需要操作 DOM 无法通过指令来做的时候可使用 this..$ref
而不是 JQuery , document.getElement,document.queryElement 。
提供组件 API 文档
在模块目录中添加 README.md 文件: 在 README 文件中说明模块的功能以及使用场景。对于 vue组件来说,比较有用的描述是组件的自定义属性即 API 的描述介绍。
状态管理器 教程
- state: 存储数据
- getter: 获取store 属性方法
- mutation: 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,类似于事件。
- action: Action 提交的是 mutation,而不是直接变更状态。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。 确实是如此—如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。
这个状态自管理应用包含以下几个部分:
state,驱动应用的数据源;
view,以声明方式将 state 映射到视图;
actions,响应在 view 上的用户输入导致的状态变化。
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,
那么相应的组件也会相应地得到高效更新。
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation. 这样使得我们可以方便地跟踪每一个状态的变化.
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:
store简单状态管理起步使用
- this.$store.state.products // 获取 store中的数据
- getters:Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:
store.js 中定义
getters: {
// ...1通过属性定义
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
},
// ...2通过方法定义
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
我们可以很容易地在任何组件中使用它
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount; //通过属性访问
store.getters.getTodoById(2) //通过方法访问 -> { id: 2, text: '...', done: false }
}
}
mapGetters 辅助函数
仅仅是将 store 中的 getter 映射到局部计算属性:
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter'
]).
}
Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,类似于事件。
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
//要唤醒 mutation handler
store.commit('increment')
登录成功之后重定向到redirect
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
//登录成功方法里
this.$router.push({ path: this.redirect || '/' })