vue问题总结2
ref注册子组件 父组件通过$refs.子组件方法调用
子组件通过$emit
父向子传值
父 :dataname = val
子 props: ['dataname']后直接用
子向父
子 this.$emit("functionname",dataval) $emit触发自定义事件
父 @functionname="getval" 使用自定义事件获取值
getval(data){data为传值}中赋值
非父子
借助eventbus
创建eventBus.js
import Vue from 'vue' export default new Vue()
import bus from '../untils/eventBus' bus.$emit('funname', data) bus.$on('funname',(data) => { data为传值 bus中this指向是bus,外面var that = this获取vue对象 })
路由跳转
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">//name,path都行, 建议用name
<router-link :to="{name:'home', params: {id:1}}">
// params传参数 (类似post)
// 路由配置 path: "/home/:id" 或者 path: "/home:id"
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
// html 取参 $route.params.id
// script 取参 this.$route.params.id
<router-link :to="{name:'home', query: {id:1}}">
// query传参数 (类似get,url后面会显示参数)
// 路由可不配置
// html 取参 $route.query.id
// script 取参 this.$route.query.id
1. 不带参数
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
params只能用name来引入路由
而query 要用path引入
2. query传参
this.$router.push({path:'/home',query: {id:'1'}})
// script 取参 this.$route.query.id
3. params传参
this.$router.push({name:'home',params: {id:'1'}}) // 只能用 name
// script 取参 this.$route.params.id
4. query和params区别
query类似 get, 跳转之后页面 url后面会拼接参数,类似?id=1, 非重要性的可以这样传, 密码之类还是用params刷新页面id还在
params类似 post, 跳转之后页面 url后面不会拼接参数 , 但是刷新页面id 会消失,需要在路由设置相应参数,刷新就不消失
this.$router.replace() (用法同push)
this. router.go(n) 向前或者向后跳转n个页面,n可为正整数或负整数
$route对象表示当前的路由信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等。
$router对象是全局路由的实例,是router构造方法的实例。
Vue-router 导航守卫有哪些
全局前置/钩子:beforeEach、beforeResolve、afterEach路由独享的守卫:beforeEnter组件内的守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
全局路由钩子 判断所有页面跳转的路由
router.beforeEach((to, from, next) => { //会在任意路由跳转前执行,next一定要记着执行,不然路由不能跳转了 console.log('beforeEach') console.log(to,from) // next() })
router.afterEach((to, from) => { //会在任意路由跳转后执行 console.log('afterEach') })
组件路由钩子,写在组件中
beforeRouteEnter:function(to,from,next){ console.log("进入当前组件"); next() }, beforeRouteUpdate:function(to,from,next){ console.log("更新组件(切换tab 修改#后面的值)"); next() }, beforeRouteLeave:function(to,from,next){ console.log("离开这个组件"); next() }
某个路由的钩子,写在路由配置中
const router = new VueRouter({ //router/index.js routes: [{ path: '/login', component: Login, beforeEnter: (to, from, next) => { // ... }, beforeLeave: (to, from, next) => { // ... } }] })
vuex获取状态
this.$store.state.data
vuex修改状态
//mutation调用
mutations:{ changeVal:function(state,val){ state.data = val } } this.$store.commit("changeVal",newval)//mutation调用 //action修改 action中不能直接更改状态,它是通过提交mutation来实现操作 mutations:{ changeVal:function(state,val){ state.data = val } }, actions:{ changeVal2:function({commit},val){ commit("changeVal",val) } } this.$store.dispatch("changeVal2",newval)//action调用

mutation同步 action异步
使用mutation修改state和直接修改 https://my.oschina.net/u/4301494/blog/3455913
直接修改或者通过commit都可以修改并且响应式触发更新
严格模式下直接修改报错,必须commit
vuex能够记录每一次state的变化记录,保存状态快照,实现时间漫游/回滚之类的操作。便于调试
接口回去数据,getters中根据权限键值处理数据
路由模式
hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。
Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”
一. 概述
window.history属性指向 History 对象,它表示当前窗口的浏览历史。
History 对象保存了当前窗口访问过的所有页面网址。下面代码表示当前窗口一共访问过3个网址。
window.history.length=3
由于安全原因,浏览器不允许脚本读取这些地址,但是允许在地址之间导航。
浏览器工具栏的“前进”和“后退”按钮,其实就是对 History 对象进行操作。
history.back()//后退到前一个网址 浏览器的后退 //等同于 history.go(-1)
history.forward()//移动到下一个网址 浏览器前进
History.pushState()方法用于在历史中添加一条记录。




vue diff算法
虚拟dom 就是对象储存dom节点信息
在采取diff算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较。
patch函数接收两个参数oldVnode和Vnode分别代表新的节点和之前的旧节点
-
判断两节点是否值得比较,值得比较则执行patchVnode
-
不值得比较则用Vnode替换oldVnode
patchVnode
当我们确定两个节点值得比较之后我们会对两个节点指定patchVnode方法。
这个函数做了以下事情:
-
找到对应的真实dom,称为el
-
判断Vnode和oldVnode是否指向同一个对象,如果是,那么直接return
-
如果他们都有文本节点并且不相等,那么将el的文本节点设置为Vnode的文本节点。
-
如果oldVnode有子节点而Vnode没有,则删除el的子节点
-
如果oldVnode没有子节点而Vnode有,则将Vnode的子节点真实化之后添加到el
-
如果两者都有子节点,则执行updateChildren函数比较子节点,这一步很重要
其他几个点都很好理解,我们详细来讲一下updateChildren
这个函数做了什么
-
将Vnode的子节点Vch和oldVnode的子节点oldCh提取出来
-
oldCh和vCh各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦StartIdx>EndIdx表明oldCh和vCh至少有一个已经遍历完了,就会结束比较。
使用Vue.observable()进行状态管理
1.创建store.js文件(位置任意,一般放在要通信的组件的最外层,也可放全局)
import Vue from 'vue' export const state = Vue.observable({ bookingData: [],//预约信息 }) export const mutations = { setBookingData: e => (state.bookingData = e) }
2.import { state, mutations } from'store';
方式一:
methods:{ // 点击事件进行状态共享 saveReplace(data) { // 设置定义的参数 }, }
方式二:
methods:{ // 点击事件进行状态共享 saveReplace:mutations.setbookingData, // 设置定义的参数 }, }
方式三:
methods:{ saveReplace(){ mutations.setbookingData([1,2]); } }
vfor优先级比vif更高,把vif写在外层
<li v-for="user in users" v-if="user.isActive" :key="user.id" > {{ user.name }} </li>
应写成
computed: { activeUsers: function () { return this.users.filter(function (user) { return user.isActive }) } } <ul> <li v-for="user in activeUsers" :key="user.id" > {{ user.name }} </li> </ul>

浙公网安备 33010602011771号