vue 笔记备份
Vue实现数据双向绑定的原理:Object.defineProperty()
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body> <body>
<div id="app">
<input type="text" id="txt">
<p id="show"></p>
</div>
</body>
<script type="text/javascript">
var obj = {}
Object.defineProperty(obj, 'txt', {
get: function () {
return obj
},
set: function (newValue) {
document.getElementById('txt').value = newValue
document.getElementById('show').innerHTML = newValue
}
})
document.addEventListener('keyup', function (e) {
obj.txt = e.target.value
})
</script>
</body>
</html>
Vue的生命周期
beforeCreate(创建前) 在数据观测和初始化事件还未开始
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
父子 组件的加载顺序
同步:
import Page from
'@/components/page'
// 同步方式引入
父子组件的执行顺序为,
父组件beforeCreated
父组件created
父组件beforeMounted
子组件beforeCreated
子组件created
子组件beforeMounted
孙组件beforeCreated
孙组件created
孙组件beforeMounted
孙组件mounted
子组件mounted
父组件mounted
异步:
const Page = () => import (
'@/components/page'
)
// 异步引入
父组件beforeCreated
父组件created
父组件beforeMounted
父组件mounted
子组件beforeCreated
子组件created
子组件beforeMounted
子组件mounted
孙组件beforeCreated
孙组件created
孙组件beforeMounted
孙组件mounted
父子 组件的销毁顺序
beforeDestroy钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁(也就是说子组件也会触发相应的函数)。这里的销毁并不指代'抹去',而是表示'解绑'。
销毁时beforeDestory函数的传递顺序为由父到子,destory的传递顺序为由子到父。
.第一次页面加载会触发哪几个钩子?
答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。
.vue.js的两个核心是什么?
答:数据驱动、组件系统
vue3 proxy的优缺点
性能优化 内存减少
兼容低,没错,IE11都不支持Proxy
vue3的整个数据监听系统都进行了重构,由es5的Object.defineProperty改为了es6的proxy。尤大说,这个新的数据监听系统带来了初始化速度加倍同时内存占用减半的效果。
Vue 2.x里,是通过 递归 + 遍历 data
对象来实现对数据的监控的,
Vue 3.x 使用Proxy。
这里面有两点需要强调下:
1、Object.defineProperty需要遍历所有的属性,这就造成了如果vue对象的data/computed/props中的数据规模庞大,那么遍历起来就会慢很多。
2、同样,如果vue对象的data/computed/props中的数据规模庞大,那么Object.defineProperty需要监听所有的属性的变化,那么占用内存就会很大。
Object.defineProperty VS Proxy
Object.definePropety的缺点
除了上面讲,在数据量庞大的情况下Object.defineProperty的两个缺点外,Object.defineProperty还有以下缺点。
1、无法监听es6的Set、WeakSet、Map、WeakMap的变化;
2、无法监听Class类型的数据;
3、属性的新加或者删除也无法监听;
4、数组元素的增加和删除也无法监听 (性能考虑,所以无法监听 )
Proxy应运而生
针对Object.defineProperty的缺点,Proxy都能够完美得解决,它唯一的缺点就是,对IE不友好,所以vue3在检测到如果是使用IE的情况下(没错,IE11都不支持Proxy),会自动降级为Object.defineProperty的数据监听系统。所以如果是IE用户,那么就享受不到速度加倍,内存减半的体验了。
Object.defineProperty
初始化
const data = {}
for(let i = 0; i <= 100000; i++) {
data['pro' + i] = i
} function defineReactive(data, property) {
let value = data[property]
Object.defineProperty(data, property, {
get() {
// console.log(`读取${property}的值为${value}`)
return value
},
set(newVal) {
// console.log(`更新${property}的值为${newVal}`)
}
})
} for(let property in data) {
defineReactive(data, property)
}
Proxy
初始化
const data = {}
for(let i = 0; i <= 100000; i++) {
data['pro' + i] = i
}
var proxyData = new Proxy(data, {
get(target, property, receiver) {
// console.log(`读取${property}的值为${target[property]}`)
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
// console.log(`更新${property}的值为${value}`)
return Reflect.set(target, property, value, receiver);
}
})
ES6
原生提供的 Proxy
语法很简单,用法如下:
let proxy = new Proxy(target, handler);
let obj = {
a : 1
}
let proxyObj = new Proxy(obj,{
get : function (target,prop) {
return prop in target ? target[prop] : 0
},
set : function (target,prop,value) {
target[prop] = 888;
}
}) console.log(proxyObj.a); //
console.log(proxyObj.b); // proxyObj.a = 666;
console.log(proxyObj.a) //
下面的例子 给予proxy的vue demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>简单版mvvm</title>
</head>
<body>
<div id="app">
<h1>开发语言:{{language}}</h1>
<h2>组成部分:</h2>
<ul>
<li>{{makeUp.one}}</li>
<li>{{makeUp.two}}</li>
<li>{{makeUp.three}}</li>
</ul>
<h2>描述:</h2>
<p>{{describe}}</p>
<p>计算属性:{{sum}}</p>
<input placeholder="123" v-module="language" />
</div>
<script>
function Mvvm(options = {}) {
this.$options = options
let data = this._data = this.$options.data
let vm = initVm.call(this)
initObserve.call(this, data)
initComputed.call(this)
new Compile(this.$options.el, vm)
mounted.call(this._vm)
return this._vm
} function initVm () {
this._vm = new Proxy(this, {
get: (target, key, receiver) => {
return this[key] || this._data[key] || this._computed[key]
},
set: (target, key, value) => {
return Reflect.set(this._data, key, value)
}
})
return this._vm
} function initObserve(data) {
this._data = observe(data)
} function observe(data) {
if (!data || typeof data !== 'object') return data
return new Observe(data)
} class Observe {
constructor(data) {
this.dep = new Dep()
for (let key in data) {
data[key] = observe(data[key])
}
return this.proxy(data)
}
proxy(data) {
let dep = this.dep
return new Proxy(data, {
get: (target, prop, receiver) => {
if (Dep.target) {
dep.addSub(Dep.target)
}
return Reflect.get(target, prop, receiver)
},
set: (target, prop, value) => {
const result = Reflect.set(target, prop, observe(value))
dep.notify()
return result
}
})
}
} class Compile{
constructor (el, vm) {
this.vm = vm
this.element = document.querySelector(el)
this.fragment = document.createDocumentFragment()
this.init()
}
init() {
let element = this.element
this.fragment.append(element)
this.replace(this.fragment)
document.body.appendChild(this.fragment)
}
replace(frag) {
let vm = this.vm
Array.from(frag.childNodes).forEach(node => {
let txt = node.textContent
let reg = /\{\{(.*?)\}\}/g
if (node.nodeType === 1) {
let nodeAttr = node.attributes;
Array.from(nodeAttr).forEach(attr => {
let name = attr.name
let exp = attr.value
if (name.includes('v-')){
node.value = vm[exp]
node.addEventListener('input', e => {
let newVal = e.target.value
// 相当于给this.a赋了一个新值
// 而值的改变会调用set,set中又会调用notify,notify中调用watcher的update方法实现了更新
vm[exp] = newVal
})
}
});
} else if (node.nodeType === 3 && reg.test(txt)) {
replaceTxt()
function replaceTxt() {
node.textContent = txt.replace(reg, (matched, placeholder) => {
new Watcher(vm, placeholder, replaceTxt); // 监听变化,进行匹配替换内容
return placeholder.split('.').reduce((val, key) => {
return val[key]
}, vm)
})
}
}
if (node.childNodes && node.childNodes.length) {
this.replace(node)
}
})
}
} class Dep {
constructor() {
this.subs = []
}
addSub(sub) {
this.subs.push(sub)
}
notify() {
this.subs.filter(item => typeof item !== 'string').forEach(sub => sub.update())
}
} class Watcher {
constructor (vm, exp, fn) {
this.fn = fn
this.vm = vm
this.exp = exp
Dep.exp = exp
Dep.target = this
let arr = exp.split('.')
let val = vm
arr.forEach(key => {
val = val[key]
})
Dep.target = null
}
update() {
let exp = this.exp
let arr = exp.split('.')
let val = this.vm
arr.forEach(key => {
val = val[key]
})
this.fn(val)
}
} function initComputed() {
let vm = this
let computed = this.$options.computed
vm._computed = {}
if (!computed) return
Object.keys(computed).forEach(key => {
this._computed[key] = computed[key].call(this._vm)
new Watcher(this._vm, key, val => {
this._computed[key] = computed[key].call(this._vm)
})
})
} function mounted() {
let mounted = this.$options.mounted
mounted && mounted.call(this)
} // 写法和Vue一样
let mvvm = new Mvvm({
el: '#app',
data: {
language: 'Javascript',
makeUp: {
one: 'ECMAScript',
two: '文档对象模型(DOM)',
three: '浏览器对象模型(BOM)'
},
describe: '没什么产品是写不了的',
a: 1,
b: 2
},
computed: {
sum() {
return this.a + this.b
}
},
mounted() {
console.log('i am mounted', this.a)
}
})
</script>
</body>
</html>
参考 https://segmentfault.com/a/1190000015460479
Vue的路由实现:hash模式 和 history模式
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 依赖的页面。”
Vuex和全局变量的概念区别
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
1、Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2、Vuex和全局变量的概念区别
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
1、Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2、你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。、你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
vue常用的修饰符?
答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用
vue等单页面应用及其优缺点
答:优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。
vue props 参数类型
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数字,有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
refAge: {
type: Number,
default: 0
},
refName: {
type: String,
default: ''
},
hotDataLoading: {
type: Boolean,
default: false
},
hotData: {
type: Array,
default: () => {
return []
}
},
getParams: {
type: Function,
default: () => () => {}
},
meta: {
type: Object,
default: () => ({})
}
vue router
组件内的导航钩子主要有这三种:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他们是直接在路由组件内部直接进行定义的
const File = {
template: `<div>This is file</div>`,
beforeRouteEnter(to, from, next) {
// do someting
// 在渲染该组件的对应路由被 confirm 前调用
},
beforeRouteUpdate(to, from, next) {
// do someting
// 在当前路由改变,但是依然渲染该组件是调用
},
beforeRouteLeave(to, from ,next) {
// do someting
// 导航离开该组件的对应路由时被调用
}
}
beforeRouteEnter 不能获取组件实例 this,因为当守卫执行前,组件实例被没有被创建出来,剩下两个钩子则可以正常获取组件实例 this
vue父组件如何动态注册子组件
少数情况,我们不知道要 加载那些组件,随着业务动态添加,比如 接口动态加载,根据需要加载组件
<button @click="asdfn">切换组件</button>
挂载的元素地方
<div ref="xxx"></div>
注册组件脚本
registerComponent(templateName,yourNeedEl){
var self=this;
return import(`@/components/${templateName}.vue`).then((component) => {
console.log("component",component)
const cpt = Vue.extend(component.default);
new cpt({
el: yourNeedEl
}); }); },
组件调用
asdfn(){
console.log("tabContent2");
var ele=this.$refs.xxx;
this.registerComponent("tabContent2",ele)
},
记得引入
import Vue from 'vue'
vue中methods、watch、computed之间的差别对比以及适用场景
一、computer
当页面中有某些数据依赖其他数据进行变动的时候,可以使用计算属性。
<p id="app"> {{fullName}} </p> <script>
var vm = new Vue({
el: '#app',
data: {
firstName: 'Foo',
lastName: 'Bar',
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
需要注意的是,就算在data中没有直接声明出要计算的变量,也可以直接在computed中写入。
计算属性默认只有getter,可以在需要的时候自己设定setter:
// ...
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
这个时候在控制台直接运行vm.fullName = ‘bibi wang’,相应的firstName和lastName也会改变。
适用场景:
二、watch
watch和computed很相似,watch用于观察和监听页面上的vue实例,当然在大部分情况下我们都会使用computed,但如果要在数据变化的同时进行异步操作或者是比较大的开销,那么watch为最佳选择。watch为一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。直接引用文档例子
var vm = new Vue({
el: '#app',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
如果在data中没有相应的属性的话,是不能watch的,这点和computed不一样。
适用场景
三、methods
方法,跟前面的都不一样,我们通常在这里面写入方法,只要调用就会重新执行一次,相应的有一些触发条件,在某些时候methods和computed看不出来具体的差别,但是一旦在运算量比较复杂的页面中,就会体现出不一样。
需要注意的是,computed是具有缓存的,这就意味着只要计算属性的依赖没有进行相应的数据更新,那么computed会直接从缓存中获取值,多次访问都会返回之前的计算结果。
vuex --> computed-->watch-->回调方法
vue 页面插入了非虚拟dom的处理,例如地图的气泡 点击事件的绑定
var MyComponent = Vue.extend({
data: function() {
return {
message: '快速录入信息',
taskUrl: '',
message2: '查看详情>>',
telPhone:'拨打电话',
}
},
// props:['data'],
props:['myname'],
template: '<a @click="show(message)">{{message }}</a>',
methods: {
show(message) { var self=this;
// console.log('地图气泡 哈哈哈',message,this.message2,this.myProps,this.myType);
// this.$router.push({path: '/detail', query:defaults }); //快速录入信息点
// this.myRouter.push({ path: '/PositioningAndPublishing', query: { 'testId': this.props.id } })
if(this.myType=="go_addEvent"){
var highwayId=this.myProps.highwayId;//K1289+820
var highwayDirectionId=this.myProps.highwayDirectionId;//
var positionCode=this.myProps.positionCode;//
var cache=+new Date;
self.bus.$emit('upPositionNumber', positionCode) // 触发事件sh
//this.$emit("upDataPoint",this.myProps) var path='/PositioningAndPublishing';
var query={
"testId": self.myProps.id ,
"highwayId": highwayId ,
"highwayDirectionId": highwayDirectionId ,
"positionCode": positionCode,
"cache": cache
}
console.log(path,"0myProps",query); self.myRouter.push({ path: path, replace: true, query:query }) } //查看详情
// this.myRouter.push({ path: '/evnetWork', query: { 'testId': this.props.id } })
// evnetWork?testId='+id+'"
if(this.myType=="go_Detail"){
var cache=+new Date; this.myRouter.push({ path: '/evnetWork',replace: true, query: { 'testId': this.myProps.id ,'cache': cache }})
} },
},
created(){
//this.message=this.message2; if(this.myType=="go_addEvent"){
this.message="快速录入信息"
} //查看详情
// this.myRouter.push({ path: '/evnetWork', query: { 'testId': this.props.id } })
// evnetWork?testId='+id+'"
if(this.myType=="go_Detail"){
this.message="查看详情>>"
} //console.log("cre33ated",this,this.message);
},
mounted() {
//console.log("TextIconOverlay",new BMapLib.TextIconOverlay());
}, beforeDestroy () {
this.bus.$off('upPositionNumber');
this.bus.$off('upTestId'); // 触发事件sh
}, });
调用
var component = new MyComponent().$mount();
infoBox =new BMapLib.InfoBox(map,content,opts);
infoBox.enableAutoPan();
infoBox.addEventListener('open',function(type, target, point){ //窗口打开是,隐藏自带的关闭按钮
//console.log(type,target,point); document.querySelectorAll('.boxClass')[0].clientLeft;
document.querySelectorAll('.boxClass')[0].classList.add("myps1sss"); setTimeout(()=>{
// console.log("component go_addEvent",component)
console.log("dat222a2",data2.positionCode);
component.myProps=data2;
component.myRouter=self.$router;
component.myType="go_addEvent";
component.message="快速录入信息";
document.querySelectorAll('.luxx')[0].appendChild(component.$el);
},100) })
或者直接dom 绑定
self.lookTimeer=setTimeout(()=>{ if(document.querySelector('.jshows')){
document.querySelector('.jshows').removeEventListener("click",looksss);
document.querySelector('.jshows').addEventListener("click",looksss)
} },200)
vue 笔记备份的更多相关文章
- Vue笔记目录
Vue笔记目录 一.Vue.js介绍 二.vue基础-vue-cli(vue脚手架) ...持续更新中,敬请期待
- 《Vue笔记01: 我与唐金州二三事》
最近我在收看唐金州在极客时间发布的<vue从入门到精通>,颇有收获. 唐金州,一点资讯前端技术专家,曾在蚂蚁金服就职,也是开源组件库ant design vue的作者,虽然唐老师写的ant ...
- Vue笔记--通过自定义指令实现按钮操作权限
经常做中后台系统,此类系统的权限是比较重要,拿自己做过的一些项目做个笔记. Vue实现的中后台管理系统.按钮操作权限的空置一般都是通过自定义指令Vue.directive. <el-button ...
- Vue笔记(有点乱)
Vue学习笔记(2019.7.31) 目录 Vue学习笔记(2019.7.31) vue 基本指令用法 v-cloak v-text v-html v-bind v-on 跑马灯 v-on v-mod ...
- 一个后端开发的 Vue 笔记【入门级】
一 前言 最近找了些教程,顺带着趴在官网上,看了看 Vue 的一些内容,入门的一些概念,以及基础语法,还有一些常用的操作,瞄了一眼,通篇文字+贴了部分代码 9000 多字,入门语法什么的还是很好理解的 ...
- vue笔记
安装vue脚手架工具 sudo cnpm install -g vue-cli
- js 抛物线 笔记备份
var funParabola = function(element, target, options) { /* * 网页模拟现实需要一个比例尺 * 如果按照1像素就是1米来算,显然不合适,因为页面 ...
- vue笔记 递归组件的使用
递归组件 什么是递归组件? 组件自身去调用组件自身. 代码示例 DetailList.vue(子组件-递归组件) <template> <div> <div class= ...
- vue笔记-列表渲染
用v-for把一个数组对应为一组元素 使用方法:v-for="(item,index) in items"//也可以使用of替代in { items:源数组 item:数组元素迭代 ...
随机推荐
- Logistic Ordinal Regression
sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...
- 转:iOS-CoreLocation:无论你在哪里,我都要找到你!
1.定位 使用步骤: 创建CLLocationManager示例,并且需要强引用它 设置CLLocationManager的代理,监听并获取所更新的位置 启动位置更新 1 2 3 _manager = ...
- JS对象中的原型
对象的原型:每个对象都连接一个原型对象,并且它可以从中继承属性.所有通过对象字面量创建的对象都连接到object.prototype.当你创建一个新对象时,你可以选择某个对象作为它的原型.原型连接在更 ...
- D - Doing Homework HDU - 1074 (状压dp)
题目链接:https://cn.vjudge.net/contest/68966#problem/D 具体思路:我们可以把每个情况都枚举出来,然后用递归的形式求出最终的情况. 比如说 我们要求 10 ...
- 基于NIO的同步非阻塞编程完整案例,客户端发送请求,服务端获取数据并返回给客户端数据,客户端获取返回数据
这块还是挺复杂的,挺难理解,但是多练几遍,多看看研究研究其实也就那样,就是一个Selector轮询的过程,这里想要双向通信,客户端和服务端都需要一个Selector,并一直轮询, 直接贴代码: Ser ...
- FPGA设计方法检查表
-----------------------摘自<FPGA软件测试与评价技术> 中国电子信息产业发展研究院 | 编著------------------------------- 文本格 ...
- mysql基准测试工具tpcc-mysql安装、使用、结果解读
TPCC是专门针对联机交易处理系统(OLTP系统)的规范,一般情况下我们也把这类系统称为业务处理系统,tpcc-mysql是percona基于TPC-C(下面简写成TPCC)衍生出来的产品,专用于My ...
- aarch64_g3
glibc-langpack-wal-2.25-6.fc26.aarch64.rpm 2017-06-20 17:08 210K fedora Mirroring Project glibc-lang ...
- 2018 CCPC网络赛
2018 CCPC网络赛 Buy and Resell 题目描述:有一种物品,在\(n\)个地点的价格为\(a_i\),现在一次经过这\(n\)个地点,在每个地点可以买一个这样的物品,也可以卖出一个物 ...
- Java集合Map与其子类回顾
接10月12号昨天的笔记,今天继续回顾集合中的Map集合. 一.集合工具操作类Collections 问题:collection和collections的区别? 1.collection是单列集合的顶 ...