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>
 
posted @ 2021-08-11 13:54  Panda的前端笔记  阅读(94)  评论(0)    收藏  举报