vue2学习笔记(高阶)

本文详细探讨了Vue2的数据双向绑定机制,通过Object.defineProperty实现属性监听,以及发布者-订阅者模式。内容涵盖Vue2的生命周期、组件通信、路由懒加载、VueX状态管理、性能优化、虚拟DOM与diff算法,同时讲解了axios的使用、路由传参方式、组件缓存等关键知识点,旨在帮助开发者深入理解Vue2的核心概念和技术实践。
摘要由CSDN通过智能技术生成
  •  Vue2数据双向绑定的原理

Vue2 数据双向绑定原理是通过数据劫持 + 发布者-订阅者模式 的方式来实现,首先是通过 ES5 提供的 Object.defineProperty() 方法来劫持(监听)各属性的 getter、setter,并在当监听的属性发生变动时通知订阅者,是否需要更新,若更新就会执行对应的更新函数。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>title</title>
</head>
<body>
    <div>
      <!-- 发布者 -->
      <input type="text" class="publisher">
      <!-- 订阅者 -->
      <div class="subscriber">我是订阅者</div>
    </div>
    <script>
      // 目标对象
      let Target = {}
      <!-- 发布对象 -->
      let pub= document.querySelector('.publisher')
      <!-- 订阅对象 -->
      let sub= document.querySelector('.subscriber')

      //数据对象属性‘劫持’过程:Object.defineProperty() 方法劫持(监听)Target属性的 get、set
      Object.defineProperty(Target, 'msg', {
        get() {
          return console.log('访问了Target.msg的值,触发了get方法')
        },
        set(value) {
          //2.Target的属性msg值改变会触发这个回调,带修改的这个值value过来了
          console.log('修改了Target.msg的值,触发了set方法', value)
          //3.然后修改需要改变的数据sub对象,ok,实现发布者的值改变后,订阅者的数据同步改变
          sub.innerHTML = value
        }
      })
  // 1.监听器,监听发布者,监听pub对象的input输入事件,触发回调,回调中给对象Target的属性msg 赋值
      pub.addEventListener('input', (e) => {
        Target.msg = e.target.value
      })
    </script>
</body>
</html>

 Object.getOwnPropertyDescriptor

对象原型的toString方法,以及数组的length属性都是不可枚举的。

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。

let obj = { foo: 123 };
//打印obj对象的foo属性的描述对象
Object.getOwnPropertyDescriptor(obj, 'foo')
//输出的对象:
//  {
//    value: 123,
//    writable: true,
//    enumerable: true,  是否可以枚举
//    configurable: true
//  }

//Object的原型toString属性是不可枚举
Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable
// false
//数组的长度length属性是不可枚举
Object.getOwnPropertyDescriptor([], 'length').enumerable
// false

$route 和 $router的区别

 $router 是VueRouter的实例,在script标签中想要导航到不同的URL,使用  $router.push方法

 $route为router跳转对象,里面可以获取当前路由的name,path,query,parmas等。

路由懒加载

方法一 resolve

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

export default new Router({
  routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: resolve => require(['@/components/HelloWorld'], resolve)
        }
  ]
}) 

方法二.import按需加载(官方写法)

const comA = () => import('url')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')

方法三 webpack提供的require.ensure()

{  
    path: '/home',   name: 'home',   
    component: r =>require.ensure([], () => r(require('@/components/home')), 'demo')
 }

.vue文件组成部分

1.<template>所需要渲染的区域</template>

2.<script>存放引入的资源与业务实现的数据与操作</script>

3.<style>存放界面css的样式</style>

scoped作用与原理 

组件css作用域,避免子组件内部的css样式被父组件覆盖,起到隔离的作用。

组件通信有哪些方式

  1. 通过 props 传递
  2. 通过 $emit 触发自定义事件
  3. 使用 ref
  4. EventBus 
  5. $parent 或$root 
  6. attrs 与 listeners
  7. Provide 与 Inject
  8. Vuex

data属性是一个函数而不是一个对象原因 

每次调用产生一个新的地址空间防止数据被污染。

vue生命周期

  •  创建vue实例对象:  beforeCreate、 created
  •  挂载dom节点 : beforeMount、mounted
  •  数据更新 : beforeUpdate、updated
  • activated: 被 keep-alive 缓存的组件激活时调用

  • deactivated: 被 keep-alive 缓存的组件失活时调用

  •  组件销毁:  beforeDestroy、destroyed

父子组件生命周期构造函数执行顺序

加载渲染过程:
父 beforecreate,created,beforeMount 
子 beforecreate,created,beforeMount
子 mounted 
父 mounted 

子组件更新过程:
父 beforeUpdate
子 beforeUpdate
子 Updated
父 Updated

销毁过程:
父 beforeDestroy
子 beforeDestroy
子 destroyed
父 destroyed
如果常用的数据如果需要传递到子组件的话,最好在created 或者
beforemount,把数据请求回来,然后传递给子组件。

axios 

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,简单的理解就是ajax的封装。

post请求的时候参数通过data进行传递
其他请求的时候参数通过params进行传递

//get请求方式:
axios.get("api", {
	// 传递参数
	params: {
		key: value
	},
    // 设置请求头信息,可以传递空值
	headers: {
		key: value
	}
}).then((response) => {
	// 请求成功
	let res = response.data;
	console.log(res);
}).catch(error => {
	// 请求失败,
	console.log(error);
});


//post请求方式:
let data = {
	key: value
},
headers = {
	USERID: "",
	TOKEN: ""
};
// 若无headers信息时,可传空对象占用参数位置
axios.post("api", qs.stringify(data), {
	headers
}
}).then((response) => {
	// 请求成功
	let res = response.data;
	console.log(res);
}).catch((error) => {
	// 请求失败,
	console.log(error);
});


/**** 以下简单封装axios   request.js   ****/
// 导入axios
import axios from 'axios'
import { Message} from 'element-ui'
//1. 创建新的axios实例,
const service = axios.create({
  // 公共接口
  baseURL: process.env.BASE_API,
  // 超时时间 单位是ms
  timeout: 3 * 1000
})
// 2.请求拦截器
service.interceptors.request.use(config => {
   config.data = JSON.stringify(config.data); //数据转化,也可以使用qs转换
   config.headers = {
     'Content-Type':'application/json' //配置请求头
   }
   //如有需要:注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
   //const token = getCookie('名称');//这里取token之前,你肯定需要先拿到token,存一下
   //if(token){
      //config.params = {'token':token} //如果要求携带在参数中
      //config.headers.token= token; //如果要求携带在请求头中
    //}
  return config
}, error => {
  Promise.reject(error)
})

// 3.响应拦截器
service.interceptors.response.use(response => {
  //接收到响应数据并成功后的一些共有的处理,关闭loading等
  return response
}, error => {
   /***** 接收到异常响应的处理开始 *****/
  if (error && error.response) {
    // 1.公共错误处理
    // 2.根据响应码具体处理
    switch (error.response.status) {
      case 400:
        error.message = '错误请求'
        break;
      case 401:
        error.message = '未授权,请重新登录'
        break;
      case 403:
        error.message = '拒绝访问'
        break;
      case 404:
        error.message = '请求错误,未找到该资源'
        window.location.href = "/NotFound"
        break;
      case 405:
        error.message = '请求方法未允许'
        break;
      case 408:
        error.message = '请求超时'
        break;
      case 500:
        error.message = '服务器端出错'
        break;
      case 501:
        error.message = '网络未实现'
        break;
      case 502:
        error.message = '网络错误'
        break;
      case 503:
        error.message = '服务不可用'
        break;
      case 504:
        error.message = '网络超时'
        break;
      case 505:
        error.message = 'http版本不支持该请求'
        break;
      default:
        error.message = `连接错误${error.response.status}`
    }
  } else {
    // 超时处理
    if (JSON.stringify(error).includes('timeout')) {
      Message.error('服务器响应超时,请刷新当前页')
    }
    error.message = '连接服务器失败'
  }
  Message.error(error.message)
  return Promise.resolve(error.response)
})
var config = {
      meth
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**之火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值