vue学习笔记
vue学习笔记
VUE学习笔记
认识Vue
Hello,{{name.toUpperCase()}},{{address}}
1、Vue的模板语法
重点说明 :
如果在标签中使用属性绑定值,是字符串,动态绑定则是会去解析表达式。例如
//字符串
//动态绑定是解析表达式 数字1
Vue模板语法有2大类:
1.插值语法:
功能:用于解析标签体内容
写法:{{xxxx}},xxx会作为表达式去解析,且可以自动读取到data中的属性
2.指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)
举例:v-bind:href="xxxxxx" 或 简写为:
备注:Vue中有很多的指令,此处我们只是拿v-bind举个例子
2、数据绑定及双向绑定原理
Vue中有2种数据绑定的方式:
1.单向绑定(v-bind):数据只能从data流向页面。
2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
备注:
1.双向绑定一般都应用在表单类元素上(如:input、select等)
2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
4、MVVM模型
MVVM模型
1. M:模型(Model) :data中的数据
2. V:视图(View) :模板代码
3. VM:视图模型(ViewModel):Vue实例
观察发现:
1.data中所有的属性,最后都出现在了vm身上。
2.vm身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
5、数据代理
5.1 Object.defineProperty方法
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
备注: 应当直接在 Object
构造器对象上调用此方法,而不是在任意一个 Object
类型的实例上调用。
语法:Object.defineProperty(obj, prop, descriptor)
obj:要定义属性的对象
prop:要定义或修改的属性的名称或 Symbol
descriptor:要定义或修改的属性描述符,简写就是默认的value值。
描述符默认值汇总
拥有布尔值的键 configurable
、enumerable
(调用Object.keys()获取不到) 和 writable
的默认值都是 false
。
属性值和函数的键 value
、get
和 set
字段的默认值为 undefined
。
let _data = { msg: "小明" };
let vm = {};
//通过对象方法给vm对象赋值属性msg
Object.defineProperty(vm, "msg", {
set(value) {
// value值就是外部赋值的值
console.log(value);
// this指向vm对象
console.log(this);
// 调用一次进行赋值会无限递归
this.msg = value;
},
get() {
return _data.msg;
}
})
vm.msg = "123"
5.2关于Vue中的数据代理:
1.什么是数据代理?
(1).配置对象data中的数据,会被收集到vm._data中,然后通过,Object.defineProperty让vm上拥有data中所有的属性。
(2).当访问vm的msg时,返回的是_data当中同名属性的值
(3).当修改vm的msg时,修改的是_data当中同名属性的值
2.为什么要数据代理?
为了更加方便的读取和修改_data中的数据,不做数据代理,就要:vm._data.xxx访问数据
3.扩展思考?—— 为什么要先收集在_data中,然后再代理出去呢?
更高效的监视数据(直接收集到vm上会导致监视效率太低)
4.基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。
vue底层,当data的数据变化,去更新dom,双向绑定dom元素的data变化也更新dom,本质是数据变化
验证data中的数据就是vm下的_data
const data = {
name: "尚硅谷",
address: "宏福科技园",
};
const vm = new Vue({
el: "#root",
data
});
//控制台上
vm._data === data //true
数据代理的原理
// 现在获取msg只能通过vm._data获取
// 如何实现通过vm.msg进行获取,将data下的键值挂载到vm下,每改变data中msg的值,vm.msg也能同步改变?
// 模拟Vue实例下vm的_data参数对象,配置对象data中的数据,会被收集到vm._data中
let _data = { msg: "小明" };
// vm模拟Vue实例化的对象
let vm = {};
// 实现方式:为vm对象添加属性值
Object.defineProperty(vm, "msg", {
set(value) {
// value值就是外部赋值的值
console.log(value);
// this指向vm对象
console.log(this);
//实现双向绑定 修改任意的一个值 两个都会发生改变
_data.msg=value;
},
get() {
return _data.msg;
}
})
// 外部改变_data.msg的值
_data.msg = "123"
console.log(vm.msg);
6、事件处理
事件的基本使用:
1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名;
2.事件的回调需要配置在methods对象中,最终会在vm上;
3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;
4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
5.@click="demo" 和 @click="demo($event)" 效果一致,但后者可以传参;
6.1事件的修饰符
Vue中的事件修饰符:
1.prevent:阻止默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式,默认是事件冒泡方式
5.self:只有event.target是当前操作的元素时才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
1.Vue中常用的按键别名:
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用)
上 => up
下 => down
左 => left
右 => right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
3.系统修饰键(用法特殊):ctrl、alt、shift、meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐)
5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self
会阻止所有的点击 ,而 v-on:click.self.prevent
只会阻止对元素自身的点击。
不要把 .passive
和 .prevent
一起使用,因为 .prevent
将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive
会告诉浏览器你不 想阻止事件的默认行为
7、计算属性computed和数据监视watch
7.1 计算属性
计算属性:
1.定义:要用的属性不存在,要通过已有属性计算得来,默认是getter读取
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
姓名案例:
使用插值语法实现
姓:
名:
全名:{{firstName + '-' + lastName}}
methods方法实现
姓:
名:
全名:{{getFullName()}}
computed方法实现
姓:
名:
全名:{{fullName}}
全名:
methods和computed对比
{{x}}
{{y()}}
{{z}}
点我调用y方法
点我调用y方法
展示x的值:
7.2 监视方法
watch方法实现
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
全名:{{fullName}}
computed和watch之间的区别:
1.只要是computed能完成的功能,watch都可以完成
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
备注:
1.所有被Vue所调用(管理)的函数,都不要写箭头函数 ----- 例如:watch中的函数、computed中的函数
2.所有不是被Vue所调(管理)的函数,都要写成箭头函数 --- 例如:定时器的回调、ajax的回调等等
3.watch就是Vue给我提供的一个监测数据改变的手段,至于数据发生改变后,要做什么,得看具体的业务了逻辑。
例如:
需要新的值、旧的值作比较,决定接下来要干什么
不要值,只要数据改变了,就要发请求等等
8、绑定样式
绑定样式:
1. class样式
写法:class="xxx" xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2. style样式
:style="{fontSize: xxx}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象。
{{title}}
{{title}}
{{title}}
{{title}}
{{title}}
354563
354563
9、条件渲染
条件渲染:
1.v-if
写法:
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
2.v-show
写法:v-show="表达式"
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
今天天气很{{isHot ? '炎热':'凉爽'}}
切换天气
建议:心境自然就会凉
建议:妈妈告诉你要穿秋裤了
建议:心境自然就会凉
建议:妈妈告诉你要穿秋裤了
10、列表渲染
10.1 基本列表
v-for指令:
1.用于展示列表数据
2.语法:v-for="(item, index) in xxx" :key="yyy"
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
{{p.name}}--{{p.sex}}--{{p.age}}
{{value}}
{{value}}---{{index}}
{{value}}---{{index}}
使用template进行v-for遍历:template会不显示
[v-for
与 v-if
一同使用]:
当它们处于同一节点,v-for
的优先级比 v-if
更高,这意味着 v-if
将分别重复运行于每个 v-for
循环中
10.2 key的原理
面试题:react、vue中的key有什么作用?(key的内部原理)
1. 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。
3. 用index作为key可能会引发的问题:
1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
2. 如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题。
4. 开发中如何选择key?:
1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
使用index作为key是没有问题的。
如果input输入框不加key属性,input输入框会复用,出现混乱的现象
10.3 列表过滤
显示过滤排序后的结果
1、可以使用计算属性
2、使用方法v-for=‘item in set(data)’
//数组中嵌套数组不适合使用计算属性
data: {
sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
10.4 列表排序
10.5 列表更新的问题
v-for 遍历数组或对象,VUE无法监测数组或对象中的值的变化,正常情况修改数组元素的值,vue不能动态的更新。原因是:复杂数据类型保存的是对象的引用,当改变对象的键或值,对象的引用并没有发生变化。
vue对于数组的方法作出一层封装,可以改变原数组的方法,vue是可以监测到变化,有push pop shift unshift reverse splice sort
对于非变更的方法,如filter concat slice 返回新数组 将新的值赋给原数组即可
// 控制台上直接修改app.list[]元素,不会动态刷新
// 解决方案
// 1.调用splice方法,Vue进行包裹可直接动态刷新
// 2.调用$forceUpdate()方法强制进行刷新
// 3.Vue.set(app.list,indexOf,newValue)
// 4.app.$set(app.list,indexOf,newValue)
10.6 模拟数据监测
10.7 Vue.set的使用
向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi')
注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。
this.student.sex = '女' //直接使用不是响应式
//两种方式
Vue.set(this.student,'sex','男')
this.$set(this.student,'sex','男')
10.8 总结Vue数据监测
Vue监视数据的原理:
1. vue会监视data中所有层次的数据。
2. 如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value) 或
vm.$set(target,propertyName/index,value)
3. 如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1).调用原生对应的方法对数组进行更新。
(2).重新解析模板,进而更新页面。
4.在Vue修改数组中的某个元素一定要用如下方法:
1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set() 或 vm.$set() (对象,数组的索引,添加索引的内容)
特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!
11、收集表单信息
收集表单数据:
若: ,则v-model收集的是value值,用户输入的就是value值。
若: ,则v-model收集的是value值,且要给标签配置value值。 不加name属性也可
若:
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
备注:v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤
12、过滤器
过滤器:
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联(如time | timeFormater('YYYY_MM_DD') | mySlice)
2.并没有改变原本的数据, 是产生新的对应的数据
3.局部有,优先使用局部过滤器
显示格式化后的时间
现在是:{{fmtTime}}
现在是:{{getFmtTime()}}
现在是:{{time | timeFormater}}
现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}
尚硅谷
{{msg | mySlice}}
13、内置指令及自定义指令
13.1 内置指令
常用内置指令
v-text : 更新元素的 innerText 类似于插值
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
v-html : 更新元素的 innerHTML 内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
v-cloak :这个指令保持在元素上直到关联实例结束编译(没有值)
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
v-once指令:
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
v-pre指令:
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
v-if : 条件渲染(动态控制节点是否存在)
v-else : 条件渲染(动态控制节点是否存在)
v-else-if:
v-show : 条件渲染 (动态控制display)
v-for : 遍历数组/对象
v-on : 绑定事件监听, 可简写为@ 修饰符
v-bind:xxx : 强制绑定解析表达式, 可简写为 :xxx 修饰符
v-model: 双向数据绑定 修饰符 .lazy .number .trim
v-slot(#) : 插槽名
{{name}}
13.2 自定义指令
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
自定义指令总结:
一、定义语法:
(1).局部指令: new Vue({directives:{指令名:配置对象} }) 或 new Vue({ directives{指令名:回调函数}}) (2).全局指令:
Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
注意:配置对象使用函数的写法,默认是bind和update里面的内容
二、配置对象中常用的3个回调:
(1).bind:指令与元素成功绑定时调用。
(2).inserted:指令所在元素被插入页面时调用。
(3).update:指令所在模板结构被重新解析时调用。
不用 (4)componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
不用 (5)unbind:只调用一次,指令与元素解绑时调用。
三、备注:
1.指令定义时不加v-,但使用时要加v-;多个单词用v-big-number
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。指令名多个单词用双引号
{{name}}
当前的n值是:
放大10倍后的n值是:
点我n+1
15.2 注意点
几个注意点:
1.关于组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
2.关于组件标签:
第一种写法:
第二种写法:
备注:不用使用脚手架时, 会导致后续组件不能渲染。
3.一个简写方式:
const school = Vue.extend(options) 可简写为:const school = options
15.3 组件的嵌套
15.3 VueComponent构造函数
关于VueComponent:
1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend调用生成的。
2.我们只需要写 或 ,Vue解析时会帮我们创建school组件的实例对象,
即Vue帮我们执行的:new VueComponent(options)。
3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!
4.关于this指向:
(1).组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
(2).new Vue(options)配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
Vue的实例对象,以后简称vm。
15.4 一个重要的内置关系 vc和vm的原型
1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
16、单文件组件
非单文件组件
通过Vue.extend去注册组件,在new Vue中的components配置,直接在html中使用
不易复用,现在将功能模块拆分
单文件组件
vue文件 1.webpack解析 2.脚手架
|-main.js 注册app组件 挂载app 使用template 注册app 配置template( ) 不用在html中写
|-App.vue app中引入components中组件 注册 school和student
|-index.html 引入main.js 和 Vue
|-components |-student
有template script export default const student = Vue.extend({}) 可简写为 export default{}
|-school
17、分析脚手架
脚手架
不使用render函数 在main.js中写
原先写法
html:
main.js:
import App from './App.vue'
new Vue({
el:'#root',
template:` `,
components:{App},
})
App.vue:
脚手架写法 缺少模板解析器
只在main.js中写
//只引入了实时运行版的vue
//import Vue from 'vue'
//完整版的包含模板解析器 就可以运行
import Vue from 'vue/dist/vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
// render: h => h(App),
components:{App},
template:` `
}).$mount('#app')
为什么:Vue = Vue核心(2/3) + 模板解析器(1/3) 所以用render进行渲染 打包后生成最终代码不需要模板解析器的部分
Vue 选项中的 render
函数若存在,则 Vue 构造函数不会从 template
选项或通过 el
选项指定的挂载元素中提取出的 HTML 模板编译渲染函数。
//引入Vue
import Vue from 'vue'
//引入App组件,它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false
/*
关于不同版本的Vue:
1.vue.js与vue.runtime.xxx.js的区别:
(1).vue.js是完整版的Vue,包含:核心功能+模板解析器。
(2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用
render函数接收到的createElement函数去指定具体内容。
*/
//创建Vue实例对象---vm
new Vue({
el:'#app',
//render函数完成了这个功能:将App组件放入容器中 返回的是虚拟dom
render: h => h(App),
// render:q=> q('h1','你好啊')
// template:`你好啊 `,
// template:` `,
// components:{App},
})
18、常用方法
18.1 ref属性
ref在普通元素上就是真实的Dom节点
组件上就是组件的示例对象(vc)
18.2 props属性
prop接受的值实在data赋值之前
//简单声明接收
// props:['name','age','sex']
//接收的同时对数据进行类型限制
/* props:{
name:String,
age:Number,
sex:String
} */
//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
props:{
name:{
type:String, //name的类型是字符串
required:true, //name是必要的
},
age:{
type:Number,
default:99 //默认值
},
sex:{
type:String,
required:true
}
}
18.3 混入Mixin
混入的方式 :方法自身有用自身的 生命周期是都会执行,混入的钩子会提前调用
还可以自定义混入
功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
第一步定义混合:
{
data(){....},
methods:{....}
....
}
第二步使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
18.4 插件
功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
通过 install 方法给 Vue 或 Vue 实例添加方法, 定义全局指令 混入 过滤器
定义插件:
对象.install = function (Vue, options) {
// 1. 添加全局过滤器
Vue.filter(....)
// 2. 添加全局指令
Vue.directive(....)
// 3. 配置全局混入(合)
Vue.mixin(....)
// 4. 添加实例方法
Vue.prototype.$myMethod = function () {...}
Vue.prototype.$myProperty = xxxx
}
使用插件:Vue.use()
import Vue from 'vue'
import loadingComponent from '@/components/Loading/index.vue'
//使用extend创建 组件的vc构造函数
const LoadingConstructor = Vue.extend(loadingComponent)
//实例化vc 挂载在div中
const instance = new LoadingConstructor({
el: document.createElement('div')
})
//在实例中挂载属性
instance.show = false // 默认隐藏
// 组件中使用props接收
const loading = {
show(txt = '') { // 显示方法
instance.show = true
instance.text = txt || '拼命加载中'
document.body.appendChild(instance.$el)
},
hide() { // 隐藏方法
instance.show = false
}
}
export default {
//install方法 有一个Vue形参
install() {
if (!Vue.$loading) {
Vue.$loading = loading
}
//通过混入 在created中 将实例化$loading 挂载在this上
Vue.mixin({
created() {
this.$loading = Vue.$loading
}
})
}
}
18.5 nextTick
语法:this.$nextTick(回调函数)
作用:在下一次 DOM 更新结束后执行其指定的回调。
什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
//解析时机的问题 当this.isEdit数据变化,并没有立即更新dom 而是执行完focus 所以必须在dom更新后进行执行
if(todo.hasOwnProperty('isEdit')){
todo.isEdit = true
}else{
// console.log('@')
this.$set(todo,'isEdit',true)
}
this.$nextTick(function(){
this.$refs.inputTitle.focus()
})
19、事件总线
main.js
new Vue({
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus = this
}
}).$mount('#app')
绑定 触发 销毁
this.$bus.$on('name',callback=>{})
this.$bus.$emit('name',params)
this.$bus.$off()全部关闭(name)
发布订阅pubsub.js
//首先是先订阅消息hello, 定义触发的回调 第一个参数的回调的函数名,第二个是接受的数据
this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
console.log(this)
// console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
})
//发送数据方,需要发布消息,触发回调
pubsub.publish('hello',666)
//取消订阅 是取消订阅号
pubsub.unsubscribe(this.pubId)
20、动画和过度
作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。
图示:
写法:
准备好样式:
元素进入的样式:
v-enter:进入的起点
v-enter-active:进入过程中
v-enter-to:进入的终点
元素离开的样式:
v-leave:离开的起点
v-leave-active:离开过程中
v-leave-to:离开的终点
使用
包裹要过度的元素,并配置name属性:
你好啊!
备注:若有多个元素需要过度,则需要使用:
,且每个元素都要指定key
值。
你好啊!
尚硅谷!
使用animate动画库
你好啊!
尚硅谷!
21、vue脚手架配置代理
方法一
在vue.config.js中添加如下配置:
//如果本地存在则不会转发
devServer:{
proxy:"http://localhost:5000"
}
说明:
优点:配置简单,请求资源时直接发给前端(8080)即可。
缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)
方法二
编写vue.config.js配置具体代理规则:
module.exports = {
devServer: {
proxy: {
'/api1': {// 匹配所有以 '/api1'开头的请求路径
target: 'http://localhost:5000',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api1': ''}//将请求地址中的api1替换为空
},
'/api2': {// 匹配所有以 '/api2'开头的请求路径
target: 'http://localhost:5001',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api2': ''}
}
}
}
}
/*
changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
changeOrigin默认值为true
*/
说明:
优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
缺点:配置略微繁琐,请求资源时必须加前缀。
代码请求写法:
axios.get('http://localhost:8080/demo/cars')
//vue.config.js
'/demo': {
target: 'http://localhost:5001',
pathRewrite:{'^/demo':''},
// ws: true, //用于支持websocket
// changeOrigin: true //用于控制请求头中的host值 true:host值不是实际的
}
//请求本地服务器,会转换撑localhost:5001/cars
22、插槽
作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件 。
分类:默认插槽、具名插槽、作用域插槽
使用方式:
默认插槽:
父组件中:
html结构1
子组件中:
插槽默认内容...
具名插槽:
父组件中:
html结构1
html结构2
子组件中:
插槽默认内容...
插槽默认内容...
作用域插槽:
理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。 (games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)
具体编码:
在slot上绑定属性,可以在父组件中使用子组件的数据 ,接受方式:
scope=“”
slot-scope=""
可以结构赋值
v-slot:default=""
default=""
父组件中:
{{g}}
子组件中:
23、Vuex
1.概念
在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
2.何时使用?
多个组件需要共享数据时
3.搭建vuex环境
创建文件:src/store/index.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
在main.js
中创建vm时传入store
配置项
......
//引入store
import store from './store'
......
//创建vm
new Vue({
el:'#app',
render: h => h(App),
store
})
4.基本使用
初始化数据、配置actions
、配置mutations
,操作文件store.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//引用Vuex
Vue.use(Vuex)
const actions = {
//响应组件中加的动作
jia(context,value){
// console.log('actions中的jia被调用了',miniStore,value)
context.commit('JIA',value)
},
}
const mutations = {
//执行加
JIA(state,value){
// console.log('mutations中的JIA被调用了',state,value)
state.sum += value
}
}
//初始化数据
const state = {
sum:0
}
//创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
})
组件中读取vuex中的数据:$store.state.sum
组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)
或 $store.commit('mutations中的方法名',数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch
,直接编写commit
5.getters的使用
概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
在store.js
中追加getters
配置
......
const getters = {
bigSum(state){
return state.sum * 10
}
}
//创建并暴露store
export default new Vuex.Store({
......
getters
})
组件中读取数据:$store.getters.bigSum
6.四个map方法的使用
mapState方法: 用于帮助我们映射state
中的数据为计算属性
computed: {
//借助mapState生成计算属性:sum、school、subject(对象写法)
...mapState({sum:'sum',school:'school',subject:'subject'}),
//借助mapState生成计算属性:sum、school、subject(数组写法)
...mapState(['sum','school','subject']),
},
mapGetters方法: 用于帮助我们映射getters
中的数据为计算属性
computed: {
//借助mapGetters生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'}),
//借助mapGetters生成计算属性:bigSum(数组写法)
...mapGetters(['bigSum'])
},
mapActions方法: 用于帮助我们生成与actions
对话的方法,即:包含$store.dispatch(xxx)
的函数
methods:{
//靠mapActions生成:incrementOdd、incrementWait(对象形式)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
//靠mapActions生成:incrementOdd、incrementWait(数组形式)
...mapActions(['jiaOdd','jiaWait'])
}
mapMutations方法: 用于帮助我们生成与mutations
对话的方法,即:包含$store.commit(xxx)
的函数,传参写在事件后@click=xxx(data)
methods:{
//靠mapActions生成:increment、decrement(对象形式)
...mapMutations({increment:'JIA',decrement:'JIAN'}),
//靠mapMutations生成:JIA、JIAN(对象形式)
...mapMutations(['JIA','JIAN']),
}
备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。
7.模块化+命名空间
目的:让代码更好维护,让多种数据分类更加明确。
修改store.js
const countAbout = {
namespaced:true,//开启命名空间
state:{x:1},
mutations: { ... },
actions: { ... },
getters: {
bigSum(state){
return state.sum * 10
}
}
}
const personAbout = {
namespaced:true,//开启命名空间
state:{ ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
countAbout,
personAbout
}
})
开启命名空间后,组件中读取state数据:
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),
//对象写法
...mapState('countAbout',{sum:'sum'),
开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])
//对象写法
开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
...mapActions('user',['addCash'])
开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
...mapMutations('user',['addCash'])
## 24、路由
理解: 一个路由(route)就是一组映射关系(key - value),多个路由需要路由器(router)进行管理。
前端路由:key是路径,value是组件。
1.基本使用
安装vue-router,命令:npm i vue-router
应用插件:Vue.use(VueRouter)
编写router配置项:
//引入VueRouter
import VueRouter from 'vue-router'
//引入Luyou 组件
import About from '../components/About'
import Home from '../components/Home'
//创建router实例对象,去管理一组一组的路由规则
const router = new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home
}
]
})
//暴露router
export default router
实现切换(active-class可配置高亮样式)
About
指定展示位置
2.几个注意点
路由组件通常存放在pages
文件夹,一般组件通常存放在components
文件夹。
通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
每个组件都有自己的$route
属性,里面存储着自己的路由信息。
整个应用只有一个router,可以通过组件的$router
属性获取到。
3.多级路由(多级路由)
配置路由规则,使用children配置项:
routes:[
{
path:'/about',
component:About,
},
{
path:'/home',
component:Home,
children:[ //通过children配置子级路由
{
path:'news', //此处一定不要写:/news
component:News
},
{
path:'message',//此处一定不要写:/message
component:Message
}
]
}
]
跳转(要写完整路径):
News
4.路由的query参数
传递参数
跳转
跳转
接收参数:
$route.query.id
$route.query.title
5.命名路由
作用:可以简化路由的跳转。
如何使用
给路由命名:
{
path:'/demo',
component:Demo,
children:[
{
path:'test',
component:Test,
children:[
{
name:'hello' //给路由命名
path:'welcome',
component:Hello,
}
]
}
]
}
简化跳转:
跳转
跳转
跳转
6.路由的params参数
配置路由,声明接收params参数
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:News
},
{
component:Message,
children:[
{
name:'xiangqing',
path:'detail/:id/:title', //使用占位符声明接收params参数
component:Detail
}
]
}
]
}
传递参数
跳转
跳转
特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!
接收参数:
$route.params.id
$route.params.title
7.路由的props配置*
作用:让路由组件更方便的收到参数
{
name:'xiangqing',
path:'detail/:id',
component:Detail,
//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
// props:{a:900} 不用props接受会放在$attrs中
//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
// props:true
//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
props(route){
return {
id:route.query.id,
title:route.query.title
}
}
}
8.
的replace属性
作用:控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式:分别为push
和replace
,push
是追加历史记录,replace
是替换当前记录。路由跳转时候默认为push
如何开启replace
模式:News
9.编程式路由导航
作用:不借助
实现路由跳转,让路由跳转更加灵活
具体编码:
//$router的两个API
this.$router.push({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.replace({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退
10.缓存路由组件
作用:让不展示的路由组件保持挂载,不被销毁。
具体编码:
11.两个新的生命周期钩子
作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
具体名字:
activated
路由组件被激活时触发。
deactivated
路由组件失活时触发。
12.路由守卫
作用:对路由进行权限控制
分类:全局守卫、独享守卫、组件内守卫
全局守卫:
//全局前置守卫:初始化时执行、每次路由切换前执行
router.beforeEach((to,from,next)=>{
console.log('beforeEach',to,from)
if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
if(localStorage.getItem('school') === 'atguigu'){ //权限控制的具体规则
next() //放行
}else{
alert('暂无权限查看')
// next({name:'guanyu'})
}
}else{
next() //放行
}
})
//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to,from)=>{
console.log('afterEach',to,from)
if(to.meta.title){
document.title = to.meta.title //修改网页的title
}else{
document.title = 'vue_test'
}
})
独享守卫:
beforeEnter(to,from,next){
console.log('beforeEnter',to,from)
if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
if(localStorage.getItem('school') === 'atguigu'){
next()
}else{
alert('暂无权限查看')
// next({name:'guanyu'})
}
}else{
next()
}
}
组件内守卫:
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
}
13.路由器的两种工作模式
对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。
hash模式:
地址中永远带着#号,不美观 。
若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
兼容性较好。
history模式:
地址干净,美观 。
兼容性和hash模式相比略差。
应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
index.html :html的入口文件
引入css文件
引入index.js 此时的src指向实例化Vue的js文件
css:
style.css
js:
index.js
定义实例化的Vue 使用render模板去替换el挂载的DOM节点
导入root文件,指向components中的root
render:(h){return h(root)}
components:
root.js:定义render的返回值
先导入页面需要的组件 和数据(如果需要则要导入事件总线)
{
template:`
//如果css中定义了app的样式,id=app需要加上
`,
components:{
"todo-list":todolist,
"done-list":donelist
}
}
todolist.js
donelist.js
先导入事件总线中需要的数据
定义组件的功能:获取数据使用computed计算属性 定义的方法 需要去触发总线中的方法 eventBus.$emit("事件总线中的方法",传入的参数)
store
store.js
先定义需要的数据,在eventBus上注册子组件需要的方法 this.$on("事件总线中的方法",this.eventBus中的方法)
Jenkins安装
nginx配置
yum install gcc-c++ yum install -y pcre pcre-devel yum install -y zlib zlib-devel yum install -y openssl openssl-devel wget http://nginx.org/download/ngi... tar zxvf nginx-1.16.1.tar.gz 先进入解压文件夹 ./configure && make && make install whereis nginx 查看nginx安装路径 在usr/local/nginx/html下 启动 [root@localhost ~]# /usr/local/nginx/sbin/nginx 停止/重启 [root@localhost ~]# /usr/local/nginx/sbin/nginx -s stop(quit、reload) 命令帮助 [root@localhost ~]# /usr/local/nginx/sbin/nginx -h 验证配置文件 [root@localhost ~]# /usr/local/nginx/sbin/nginx -t 配置文件 [root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
安装yarn
使用 yum 安装 Yarn Yarn 官方提供的有 Yarn RPM 软件包,在添加 yum 源配置之后可使用 yum 安装:
添加 yum 源配置
curl -sL https://dl.yarnpkg.com/rpm/ya... | sudo tee /etc/yum.repos.d/yarn.repo
使用 yum 安装
sudo yum -y install yarn
查看安装的 Yarn 版本:
yarn -v
Jenkins安装
jekins+gitee+nginx sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat... sudo rpm --import https://pkg.jenkins.io/redhat... sudo yum upgrade sudo yum install epel-release java-11-openjdk-devel sudo yum install jenkins sudo systemctl daemon-reload sudo systemctl start jenkins 启动 查看状态sudo systemctl status jenkins 修改编辑权限 vim /etc/sysconfig/jenkins service jenkins restart重启
这时访问jenkins有不可以,要开放阿里云8080端口 1.登录成功 为了确保管理员安全地安装 Jenkins,密码已写入到日志中(不知道在哪里?)该文件在服务器上: /var/lib/jenkins/secrets/initialAdminPassword 请从本地复制密码并粘贴到下面。 d65c81a6952341dfac53d9efaf61e0cc 2.按照默认配置安装插件 3.创建一个管理员账户,完成配置后,就可以登录 Jenkins 了 4.安装插件 下面来安装nodejs插件
gitee令牌2e724699896926f21b301598d10d91d7
gitee实验jenkins教程
安装rz :yum install -y lrzsz
gcc 版本过低
4.安装gcc
yum install gcc -y #默认安装旧版本4.85
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils #安装新版本
切换为新版本
scl enable devtoolset-9 bash #临时切换,退出服务器恢复
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile #永久切换
jenkins
需要配置webhook gitee需要配置 参考jenkins+gitee实现前端项目自动化部署 - 简书 (jianshu.com)
安装nodejs
cd /home/downloads
wget https://nodejs.org/dist/v10.16.0/node-v10.16.0.tar.gz
下载编译好的node Linux
ln -s /usr/local/src/node-v16.5.0-linux-x64/bin/node /usr/local/bin/node
ln -s /usr/local/src/node-v16.5.0-linux-x64/bin/npm /usr/local/bin/npm
课堂知识内容回顾
1、使用template会将el挂载的节点内容替换. 注意template模板的使用
组件间的通信方式有3类:
第一类:父子组件通信
第二类:隔代组件通信
第三类:兄弟组件通信
(1) props/$emit 适用父子组件通信
父-->子传值 props
(5)EventBus($emit/$on)适用于父子、隔代、兄弟组件通信
(6)Vuex 适用于父子、隔代、兄弟组件通信
组件的插槽slot
编译作用域
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
后背内容 默认的内容
具名插槽
作用域插槽
{{slotProps.user.firstName}}
//补充:当被提供的内容只有默认插槽时 组件的标签才可以被当作插槽的模板来使用
{{ slotProps.user.firstName }}
//可以简写为
{{ slotProps.user.firstName }}
//结构赋值
{{person}}
//这里还是只能写user
{{user}}
要改变插槽的值
//第一种传入的是对象 子组件中使用user.lastName
{{slotProps.user}}
{{user}}
{{user}}
//第二种方式 在组件中直接传入
{{slotProps.user.lastName}}
{{user}}
动态组件 keep-alive
使用keep-alive时,组件将缓存
组件一
组件二
内联模板inline-template
x-template
混入mixin
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
{{msg}}
打印
----------------
过滤器 filter
过滤器可以用在两个地方:**双花括号插值和 `v-bind` 表达式** (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示。
当全局过滤器和局部过滤器重名时,会采用局部过滤器。
全局过滤器:在创建 Vue 实例之前全局定义过滤器
// 全局过滤器
Vue.filter("replaceMinus",function(value){
return value.replace(/-/g," ");
})
局部过滤器
var app = new Vue({
el:"#app",
data:{
msg:'hello-world-haha-heihei'
},
filters:{
"replaceMinus":function(value){
return value.replace(/-/g," ");
},
"upperCase":function(value){
return value.toUpperCase();
}
}
})
案例:
{{msg | replaceMinus}}
{{msg | upperCase}}
自定义指令directive
自定义指令的钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
钩子函数参数
指令钩子函数会被传入以下参数:
el:指令所绑定的元素,可以用来直接操作 DOM。 binding:一个对象,包含以下 property:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。 oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
注意:除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。
### [动态指令参数](https://cn.vuejs.org/v2/guide/custom-directive.html#动态指令参数)
创建一个自定义指令,用来通过固定布局将元素固定在页面上。我们可以像这样创建一个通过指令值来更新竖直位置像素值的自定义指令:
这会把该元素固定在距离页面顶部 200 像素的位置。但如果场景是我们需要把元素固定在左侧而不是顶部又该怎么办呢?这时使用动态参数就可以非常方便地根据每个组件实例来进行更新。
Scroll down inside this section ↓ I am pinned onto the page at 200px to the left.
//通过 Vue.directive('pin', { bind: function (el, binding, vnode) {
el.style.position = 'fixed'
var s = (binding.arg == 'left' ? 'left' : 'top')
el.style[s] = binding.value + 'px'
} })
new Vue({ el: '#dynamicexample', data: function () {
return {
direction: 'left'
}
} })
渲染函数render
`createElement` 到底会返回什么呢?其实不是一个*实际的* DOM 元素。它更准确的名字可能是 `createNodeDescription`,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为“**VNode**”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼
## vue-router
index.html
链接到vue的router中
About
Home
展示跳转显示的模板位置
js/index.js
导入router
定义router:router
router/index.js
导入组件About 组件中导入的地址是相对自身文件的
new VueRouter({
routes:[
{
path:'/about',
component:About
}
]
})
你可能感兴趣的:(程序员)
程序员集体失业?DeepSeek这6个反常识用法竟能替代写代码
后端
上周三凌晨两点,我盯着满屏报错的SpringBoot项目抓耳挠腮时,无意间在GitHubtrending榜发现了个宝藏项目。这个让3000+程序员连夜改简历的AI工具,居然把我的烂代码变成了性能提升40%的优雅实现——这可不是什么天方夜谭,而是我亲身经历的DeepSeek实战故事。你可能不信,现在用自然语言描述需求就能生成可运行代码。就像上周我接到个紧急任务:要在三天内完成电商平台的优惠券系统。当
python 正则表达式的语法及使用
主打Python
正则表达式 python 基础语法 正则表达式 python
python正则表达式的语法及使用概念:按照程序员的指示,字符串里提取你要的数据。应用:爬虫清洗数据,匹配电话,匹配邮箱,匹配账号……最重要的就是(.*?)正则语法(元字符)1、?:前面的内容出现0-1次2、+:前面的内容出现1-多次3、*:前面的内容出现0-多次‘’’正则(Regular):记住的点:1、(.?)2、re.findall()结果是一个列表3、用(.?)的是后,一定要复制,而不是手
打开 WIN10 命令框的几种姿势
夜璨如炽
脚本办公 cmd
前言作为一个程序员,命令窗一定是每个人都会接触使用的东西,最近发现身边好多人还只会在开始里找,其实还有很多便捷的打开方式,一定还有很多人不知道吧。这里给分享一下。一、WIN+R键这个应该是知道最多的吧,首先win+R键打开运行框然后输入cmd或者cmd.exe然后回车ENTER,或者点击确定。OK二、文件夹地址栏启动平时一般桌面上都会开启几个文件夹直接在红线地址栏部分,输入cmd回车,OK
程序员不用写代码?DeepSeek这个隐藏功能让我惊掉下巴
后端
凌晨三点半,显示器蓝光映着我的黑眼圈。就在我第18次修改接口文档时,同事老王突然在微信甩来个神秘链接:"用这个,今晚能睡个好觉"。我点开那个叫DeepSeek的页面,没想到接下来的三个小时,我经历了职业生涯最魔幻的加班夜。你见过会自己写测试用例的AI吗?那天晚上,我把项目需求文档往DeepSeek的对话框一扔,它竟然像资深架构师似的,先把需求拆解成模块,接着自动生成了带注释的接口文档。最绝的是,在
程序员别再用GitHub了!这个国产神器让你的开发效率原地起飞
后端
去年这个时候,我还在为团队协作的代码管理头疼不已。直到某天凌晨三点,盯着满屏的Git指令的我突然发现,自己居然把feature分支合并到了生产环境——这个要命的失误让我在茶水间被同事调侃了整整三个月。就在我准备写辞职信的时候,一个偶然的机会让我遇到了DeepSeek,这个国产开发神器彻底改变了我的职业生涯。你可能很难想象,现在我的团队每天要处理200多个合并请求,但再也没出现过那次凌晨三点的事故。
Java常用API
EmbodiedTech
Java架构栈 java dubbo 开发语言
一、今日内容介绍、API概述常用API(全称是ApplicationProgramInterface应用程序接口),说人话就是:别人写好的一些程序,给咱们程序员直接拿去调用。Java官方其实已经给我们写好了很多很多类,每一个类中又提供了一系列方法来解决与这个类相关的问题。比如String类,表示字符串,提供的方法全都是对字符串操作的。比如ArrayList类,表示一个容器,提供的方法都是对容器中的
程序员996写bug?这个AI工具让你头发越秃代码越香
后端
凌晨三点的写字楼里,小王第18次按下F5刷新浏览器,控制台又跳出了新的报错信息。咖啡杯底的褐色痕迹在显示器蓝光下格外刺眼,他突然想起入职时主管说的"程序员越秃越强",摸了摸发际线苦笑——原来这句话的潜台词是"用头发换代码"啊。直到上个月团建时,我发现隔壁工位的老张居然在团建现场掏出笔记本写代码。凑近一看,他正在用DeepSeek的智能提示功能自动补全单元测试。更气人的是,这厮今年居然还长出了新发茬
Redis查看所有key的命令
abckingaa
Bee DB redis 数据库 database
Redis查看所有key的命令keys*启动了Redis服务器和客户端,在客户端输入keys*即可(若需要密码登录,先输入密码)Bee,互联网新时代的JavaORM工具,更快、更简单、更自动,开发速度快,运行快,更智能!Bee让程序员/软件工程师,从手工编码中解放出来,Bee更适合智能软件制造时代!十分钟即可入门!立志做最懂用户的软件!
C++语言的声明式编程
俞嫦曦
包罗万象 golang 开发语言 后端
C++语言的声明式编程引言声明式编程是一种编程范式,它强调描述程序的“要做什么”而不是“怎么做”。在传统的命令式编程中,程序员通常需要详细地指定操作步骤,而在声明式编程中,程序员则可以专注于结果的描述。这一编程风格在C++语言的使用中,虽然不如某些其他语言(如Haskell或SQL)那样突出,但依然通过一些特性和标准库提供了支持。本文将深入探讨C++中的声明式编程,包括其基本概念、与命令式编程的对
C++核心编程手册
易方达蓝筹
C or 计算机网络 c++ 开发语言 后端
C++核心编程本阶段主要针对C++面向对象编程技术做详细讲解,探讨C++中的核心和精髓。1内存分区模型C++程序在执行时,将内存大方向划分为4个区域代码区:存放函数体的二进制代码,由操作系统进行管理的全局区:存放全局变量和静态变量以及常量栈区:由编译器自动分配释放,存放函数的参数值,局部变量等堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收内存四区意义:不同区域存放的数据,赋予不
程序员都在偷偷用的黑科技工具,老板发现后竟主动要求加薪?
后端
上周三凌晨两点,我正对着满屏的SQL报错信息抓耳挠腮。同事老王突然在微信群里甩来一行代码:"试试用DeepSeek分析你的数据库日志。"我半信半疑地复制粘贴,没想到这个看似普通的指令,居然在十秒内就定位到了索引缺失的根源。更魔幻的是,第二天早会上,那个总板着脸的CTO居然在全员面前点名表扬了我的"超强问题排查能力"。这就是DeepSeek最让我着迷的地方——它总能把复杂的代码问题变成幼儿园算术题。
Hyperlane:轻量、高效、安全的 Rust Web 框架新选择
LTPP
安全 rust 前端 github ssl 开发语言 后端
Hyperlane:轻量、高效、安全的RustWeb框架新选择在Web开发的世界中,框架的选择往往决定了项目的效率与未来。Hyperlane,一款基于Rust语言打造的轻量级Web框架,正以其卓越的性能、简洁的设计和可靠的安全性,迅速成为开发者的新宠。无论你是追求极致性能的资深程序员,还是希望快速上手的初学者,Hyperlane都能为你带来惊喜。让我们一起走进Hyperlane的世界,探索它的魅力
Unreal Engine开发:Unreal Engine基础入门_蓝图基础
chenlz2007
游戏开发2 虚幻 游戏引擎 java 前端 网络
蓝图基础蓝图概述什么是蓝图?蓝图(Blueprint)是UnrealEngine中的一个可视化脚本系统,允许开发者通过拖拽和连接节点来创建游戏逻辑、关卡脚本和自定义行为。蓝图使得非程序员也能轻松地进行游戏开发,同时也为程序员提供了一个快速迭代和调试的工具。蓝图系统基于C++的底层架构,因此可以实现与使用C++相同的功能,但更加直观和易于理解。蓝图的类型UnrealEngine中的蓝图主要有以下几种
Spring之Bean生命周期源码解析-一文掌握(一)
小徐Chao努力
源码分析 spring java 后端
Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建Bean对象做准备,所以我们先明白Spring到底是怎么去创建Bean的,也就是先弄明白Bean的生命周期。Bean的生命周期就是指:在Spring中,一个Bean是如何生成的,如何销毁的Bean的生成过程1.生成BeanDefinitionSpring启动的时候会进行扫描,会先调用org.springfr
5.C语言基础入门:数据类型、变量声明与创建详解
CILMY23
C语言 c语言 变量 数据类型 内置类型 自定义类型
C语言基础入门:数据类型、变量声明与创建详解C语言往期系列文章目录往期回顾:C语言是什么?编程界的‘常青树’,它的辉煌你不可不知VS2022社区版C语言的安装教程,不要再卡在下载0B/s啦C语言入门:解锁基础概念,动手实现首个C程序C语言概念之旅:解锁关键字,字符,字符串的秘密,揭秘语句和注释,程序员的宝藏文章目录C语言基础入门:数据类型、变量声明与创建详解C语言往期系列文章目录前言回顾一、数据类
程序员必看!DeepSeek全栈开发实战指南:从代码生成到性能优化
AI创享派
后端
一、DeepSeek技术新突破:程序员效率革命(开篇结合最新技术动态)2025年2月25日,DeepSeek接连放出两大技术王牌:全球首个面向MoE模型的全栈通信库DeepEP开源,以及深度思考R1模型的全面升级。这两项技术突破对程序员群体意义重大:通信效率飞跃:DeepEP通过NVLink优化实现GPU间158GB/s传输速度,后端开发者训练大模型时可节省60%集群资源推理性能突破:R1模型在H
PMP冲刺每日一题(33)答案解析
PM简读馆
PMP每日打卡 产品经理
作者简介:程序员转项目管理领域优质创作者个人邮箱:[
[email protected] ]PMP资料导航:PM菜鸟(查阅PMP大纲考点)座右铭:上善若水,水善利万物而不争。绿泡泡:PM简读馆(包含更多PM常用免费资料)目录试题1试题2试题3试题4试题5试题1标题:项目启动一个月后,副总裁表示,由于需求不完整,项目应停止。若要确认这一点,项目经理应该查阅哪份文件?选项A:概述可行需求选项的会议备忘录分
PMP冲刺每日一题(33)
PM简读馆
PMP每日打卡 产品经理
作者简介:程序员转项目管理领域优质创作者个人邮箱:[
[email protected] ]PMP资料导航:PM菜鸟(查阅PMP大纲考点)座右铭:上善若水,水善利万物而不争。绿泡泡:PM简读馆(包含更多PM常用免费资料)试题1标题:项目启动一个月后,副总裁表示,由于需求不完整,项目应停止。若要确认这一点,项目经理应该查阅哪份文件?A、概述可行需求选项的会议备忘录B、项目章程C、客户意向书D、项目使命说
JavaScript 异步编程:从回调到 Async/Await 进化
PM简读馆
技术杂谈 javascript 开发语言 ecmascript
作者简介:程序员转项目管理领域优质创作者个人邮箱:[
[email protected] ]PMP资料导航:PM菜鸟(查阅PMP大纲考点)座右铭:上善若水,水善利万物而不争。绿泡泡:PM简读馆(包含更多PM常用免费资料)目录1.回调函数(Callback)2.Promise3.Generator4.Async/Await在JavaScript中,异步编程是一个非常重要的概念,因为JavaScript是
高薪程序员&面试题精讲系列131之Eureka如何实现高可用?自我保护机制是怎么回事?
一一哥Sun
Java高薪面试题精讲系列 eureka spring cloud java
一.面试题及剖析1.今日面试题你熟悉Eureka吗?服务治理是怎么回事?Eureka的服务治理包含哪些内容?自我保护机制是怎么回事?Eureka怎么实现高可用?Eureka挂了,服务间还能通信吗?Eureka的工作原理是怎么样的?2.题目剖析在上一篇文章中,
大模型转型之路:必要性与未来前景,迎接智能时代的浪潮_转行大模型
大模型入门学习
人工智能 语言模型 AI 大模型 AI大模型 程序员 转行
随着人工智能(AI)技术的迅猛发展,特别是大型语言模型(LLM,LargeLanguageModels)的崛起,各行各业正迎来一场前所未有的技术革命。对于普通程序员而言,转行进入大模型领域不仅是对个人职业发展的战略性投资,也是顺应时代潮流、把握未来机遇的重要选择。本文将探讨转行大模型的必然性和该领域的未来发展前景。一、转行大模型的必然性技术普及化与学习资源丰富互联网的发展极大地降低了知识获取的成本
实现RPC框架的流量控制与限流策略
AI天才研究院
计算 编程实践 架构师必知必会系列 计算 大数据 人工智能 语言模型 AI 大模型 LLM Java Python 架构设计 Agent RPA
1.背景介绍实现RPC框架的流量控制与限流策略作者:禅与计算机程序设计艺术1.背景介绍1.1RPC简介RPC(RemoteProcedureCall),即远程过程调用,是一种常见的分布式系统中的通信方式。它允许程序员像调用本地函数一样去调用网络上位于其他机器上的函数。RPC通过将参数序列化为消息,然后发送到服务器上执行相应的函数,最后将结果反序列化返回给客户端。1.2流量控制与限流策略在分布式系统
2024年HarmonyOS鸿蒙最新鸿蒙应用开发当前支持的颜色枚举值(2),2024年最新社招面试题目
2401_84850323
程序员 鸿蒙 面试 学习
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新需要这份系统化的资料的朋
侯捷 C++ 课程学习笔记:C++常用标准库
Three~stone
c++ 学习 笔记
标准库#include万能头是一个简写方式,用来一次性包含C++标准库中的许多常用部分,比如输入输出流(iostream)、算法(algorithm)、向量(vector)、列表(list)、队列(queue)、栈(stack)、映射(map)、集合(set)等。使用它可以让程序员在编写解决特定问题的代码时,不必一一列出所需的所有头文件,简化了代码的编写过程。在实际的工程项目或更专业的编程实践中,
学懂C++(六): C++ 数据抽象特性详解
猿享天开
c++ 开发语言 数据抽象 虚函数
数据抽象是面向对象编程中的一个核心特性,它允许程序员将复杂的现实世界问题简化为易于管理和理解的模型。在C++中,数据抽象通过类和对象的机制实现。以下是对C++数据抽象特性的详细解析。1.什么是数据抽象数据抽象是一种处理复杂性的方法,它通过隐藏实现细节并只暴露必要的接口来简化程序设计。通过数据抽象,程序员可以专注于对象的功能,而不必关注其内部实现。1.1抽象的好处简化复杂性:仅提供必要的信息,隐藏不
作为普通程序员,我们该如何学习大模型(LLM),学习路线和知识体系
和老莫一起学AI
学习 人工智能 深度学习 语言模型 ai 程序员 转行
前言原谅我的后知后觉,才开始从头写,我是已经上了一阶段大模型的课,也搜集了些资料,并自己做了小部分实践,回过头来,才想开始整理些文章。起初,大家都在写,都在发,我那会在焦虑。自chatgpt爆火以来,AI技术又被广泛关注,国内外各大厂商也纷纷布局,作为我们每一个普通人,也无不时刻感受着AI一波又一波的冲击。尤其是作为程序员的我,相信绝大多数程序员也有和我一样的感受,从一开始的新奇,到焦虑,到试图去
java面试合集
云端源想
java 面试 开发语言
背景:随着软件行业竞争日益激烈,Java作为最广泛应用的编程语言之一,其开发者在求职过程中面临的面试挑战也日益增大。为了帮助Java程序员更好地准备面试,提升竞争力,我们计划长期更新一个全面、深入的《Java面试合集》专栏。本专栏旨在覆盖从Java基础到高级技术点,以及实战经验分享,为不同层次的Java开发者提供一站式面试资源。《Java面试合集》专栏的设计需要兼顾技术深度、实战场景与行业趋势,采
如何检查Mac电脑是否已安装Python环境
=蜗牛=
mac python python3 环境
1、Python简介Python是一种高级编程语言,由荷兰程序员吉多·范罗苏姆(GuidovanRossum)于1989年底发明,并于1991年首次发布。它的设计理念强调代码的可读性和简洁的语法,使得程序员能够以较少的代码行数表达思想,从而提高开发效率。Python的名字来源于吉多·范罗苏姆喜欢的喜剧团体“蒙提·派森”(MontyPython),这也体现了Python社区幽默、开放的文化氛围。2、
缓存:节省使用大模型的成本
雪碧没气阿
spring 人工智能 机器人 自然语言处理 AI 大模型 缓存
稍有经验的程序员对缓存都不陌生,在任何一个正式的工程项目上都少不了缓存的身影。硬件里面有缓存,软件里面也有缓存,缓存已经成了程序员的必修课。我们为什么要使用缓存呢?主要就是为了减少访问低速服务的次数,提高访问速度。大模型显然就是一个低速服务,甚至比普通的服务还要慢。为了改善大模型的使用体验,人们已经做出了一些努力,比如采用流式响应,提升第一个字出现在用户面前的速度。缓存,显然是另外一个可以解决大模
HarmonyOS NEXT 开发环境搭建与出行导航类应用开发
harmonyos
随着华为鸿蒙操作系统HarmonyOSNEXT的推出,越来越多的开发者开始关注并投入到鸿蒙生态的开发中。本文将详细介绍如何在HarmonyOSNEXT环境下搭建开发环境,并通过一个出行导航类交通地图应用的实例,展示如何进行应用程序的开发。本文面向具有一定开发经验的程序员,旨在帮助他们快速上手鸿蒙应用开发。开发环境搭建安装DevEcoStudio:DevEcoStudio是华为官方提供的集成开发环境
apache 安装linux windows
墙头上一根草
apache inux windows
linux安装Apache 有两种方式一种是手动安装通过二进制的文件进行安装,另外一种就是通过yum 安装,此中安装方式,需要物理机联网。以下分别介绍两种的安装方式
通过二进制文件安装Apache需要的软件有apr,apr-util,pcre
1,安装 apr 下载地址:htt
fill_parent、wrap_content和match_parent的区别
Cb123456
match_parent fill_parent
fill_parent、wrap_content和match_parent的区别:
1)fill_parent
设置一个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间。这跟Windows控件的dockstyle属性大体一致。设置一个顶部布局或控件为fill_parent将强制性让它布满整个屏幕。
2) wrap_conte
网页自适应设计
天子之骄
html css 响应式设计 页面自适应
网页自适应设计
网页对浏览器窗口的自适应支持变得越来越重要了。自适应响应设计更是异常火爆。再加上移动端的崛起,更是如日中天。以前为了适应不同屏幕分布率和浏览器窗口的扩大和缩小,需要设计几套css样式,用js脚本判断窗口大小,选择加载。结构臃肿,加载负担较大。现笔者经过一定时间的学习,有所心得,故分享于此,加强交流,共同进步。同时希望对大家有所
[sql server] 分组取最大最小常用sql
一炮送你回车库
SQL Server
--分组取最大最小常用sql--测试环境if OBJECT_ID('tb') is not null drop table tb;gocreate table tb( col1 int, col2 int, Fcount int)insert into tbselect 11,20,1 union allselect 11,22,1 union allselect 1
ImageIO写图片输出到硬盘
3213213333332132
java image
package awt;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imagei
自己的String动态数组
宝剑锋梅花香
java 动态数组 数组
数组还是好说,学过一两门编程语言的就知道,需要注意的是数组声明时需要把大小给它定下来,比如声明一个字符串类型的数组:String str[]=new String[10]; 但是问题就来了,每次都是大小确定的数组,我需要数组大小不固定随时变化怎么办呢? 动态数组就这样应运而生,龙哥给我们讲的是自己用代码写动态数组,并非用的ArrayList 看看字符
pinyin4j工具类
darkranger
.net
pinyin4j工具类Java工具类 2010-04-24 00:47:00 阅读69 评论0 字号:大中小
引入pinyin4j-2.5.0.jar包:
pinyin4j是一个功能强悍的汉语拼音工具包,主要是从汉语获取各种格式和需求的拼音,功能强悍,下面看看如何使用pinyin4j。
本人以前用AscII编码提取工具,效果不理想,现在用pinyin4j简单实现了一个。功能还不是很完美,
StarUML学习笔记----基本概念
aijuans
UML建模
介绍StarUML的基本概念,这些都是有效运用StarUML?所需要的。包括对模型、视图、图、项目、单元、方法、框架、模型块及其差异以及UML轮廓。
模型、视与图(Model, View and Diagram)
&
Activiti最终总结
avords
Activiti id 工作流
1、流程定义ID:ProcessDefinitionId,当定义一个流程就会产生。
2、流程实例ID:ProcessInstanceId,当开始一个具体的流程时就会产生,也就是不同的流程实例ID可能有相同的流程定义ID。
3、TaskId,每一个userTask都会有一个Id这个是存在于流程实例上的。
4、TaskDefinitionKey和(ActivityImpl activityId
从省市区多重级联想到的,react和jquery的差别
bee1314
jquery UI react
在我们的前端项目里经常会用到级联的select,比如省市区这样。通常这种级联大多是动态的。比如先加载了省,点击省加载市,点击市加载区。然后数据通常ajax返回。如果没有数据则说明到了叶子节点。 针对这种场景,如果我们使用jquery来实现,要考虑很多的问题,数据部分,以及大量的dom操作。比如这个页面上显示了某个区,这时候我切换省,要把市重新初始化数据,然后区域的部分要从页面
Eclipse快捷键大全
bijian1013
java eclipse 快捷键
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)Alt+↑ 当前行和上面一行交互位置(同上)Alt+← 前一个编辑的页面Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)Alt+En
js 笔记 函数
征客丶
JavaScript
一、函数的使用
1.1、定义函数变量
var vName = funcation(params){
}
1.2、函数的调用
函数变量的调用: vName(params);
函数定义时自发调用:(function(params){})(params);
1.3、函数中变量赋值
var a = 'a';
var ff
【Scala四】分析Spark源代码总结的Scala语法二
bit1129
scala
1. Some操作
在下面的代码中,使用了Some操作:if (self.partitioner == Some(partitioner)),那么Some(partitioner)表示什么含义?首先partitioner是方法combineByKey传入的变量,
Some的文档说明:
/** Class `Some[A]` represents existin
java 匿名内部类
BlueSkator
java匿名内部类
组合优先于继承
Java的匿名类,就是提供了一个快捷方便的手段,令继承关系可以方便地变成组合关系
继承只有一个时候才能用,当你要求子类的实例可以替代父类实例的位置时才可以用继承。
在Java中内部类主要分为成员内部类、局部内部类、匿名内部类、静态内部类。
内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相
盗版win装在MAC有害发热,苹果的东西不值得买,win应该不用
ljy325
游戏 apple windows XP OS
Mac mini 型号: MC270CH-A RMB:5,688
Apple 对windows的产品支持不好,有以下问题:
1.装完了xp,发现机身很热虽然没有运行任何程序!貌似显卡跑游戏发热一样,按照那样的发热量,那部机子损耗很大,使用寿命受到严重的影响!
2.反观安装了Mac os的展示机,发热量很小,运行了1天温度也没有那么高
&nbs
读《研磨设计模式》-代码笔记-生成器模式-Builder
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
/**
* 生成器模式的意图在于将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示(GoF)
* 个人理解:
* 构建一个复杂的对象,对于创建者(Builder)来说,一是要有数据来源(rawData),二是要返回构
JIRA与SVN插件安装
chenyu19891124
SVN jira
JIRA安装好后提交代码并要显示在JIRA上,这得需要用SVN的插件才能看见开发人员提交的代码。
1.下载svn与jira插件安装包,解压后在安装包(atlassian-jira-subversion-plugin-0.10.1)
2.解压出来的包里下的lib文件夹下的jar拷贝到(C:\Program Files\Atlassian\JIRA 4.3.4\atlassian-jira\WEB
常用数学思想方法
comsci
工作
对于搞工程和技术的朋友来讲,在工作中常常遇到一些实际问题,而采用常规的思维方式无法很好的解决这些问题,那么这个时候我们就需要用数学语言和数学工具,而使用数学工具的前提却是用数学思想的方法来描述问题。。下面转帖几种常用的数学思想方法,仅供学习和参考
函数思想
把某一数学问题用函数表示出来,并且利用函数探究这个问题的一般规律。这是最基本、最常用的数学方法
pl/sql集合类型
daizj
oracle 集合 type pl/sql
--集合类型
/*
单行单列的数据,使用标量变量
单行多列数据,使用记录
单列多行数据,使用集合(。。。)
*集合:类似于数组也就是。pl/sql集合类型包括索引表(pl/sql table)、嵌套表(Nested Table)、变长数组(VARRAY)等
*/
/*
--集合方法
&n
[Ofbiz]ofbiz初用
dinguangx
电商 ofbiz
从github下载最新的ofbiz(截止2015-7-13),从源码进行ofbiz的试用
1. 加载测试库
ofbiz内置derby,通过下面的命令初始化测试库
./ant load-demo (与load-seed有一些区别)
2. 启动内置tomcat
./ant start
或
./startofbiz.sh
或
java -jar ofbiz.jar
&
结构体中最后一个元素是长度为0的数组
dcj3sjt126com
c gcc
在Linux源代码中,有很多的结构体最后都定义了一个元素个数为0个的数组,如/usr/include/linux/if_pppox.h中有这样一个结构体: struct pppoe_tag { __u16 tag_type; __u16 tag_len; &n
Linux cp 实现强行覆盖
dcj3sjt126com
linux
发现在Fedora 10 /ubutun 里面用cp -fr src dest,即使加了-f也是不能强行覆盖的,这时怎么回事的呢?一两个文件还好说,就输几个yes吧,但是要是n多文件怎么办,那还不输死人呢?下面提供三种解决办法。 方法一
我们输入alias命令,看看系统给cp起了一个什么别名。
[root@localhost ~]# aliasalias cp=’cp -i’a
Memcached(一)、HelloWorld
frank1234
memcached
一、简介
高性能的架构离不开缓存,分布式缓存中的佼佼者当属memcached,它通过客户端将不同的key hash到不同的memcached服务器中,而获取的时候也到相同的服务器中获取,由于不需要做集群同步,也就省去了集群间同步的开销和延迟,所以它相对于ehcache等缓存来说能更好的支持分布式应用,具有更强的横向伸缩能力。
二、客户端
选择一个memcached客户端,我这里用的是memc
Search in Rotated Sorted Array II
hcx2013
search
Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given ta
Spring4新特性——更好的Java泛型操作API
jinnianshilongnian
spring4 generic type
Spring4新特性——泛型限定式依赖注入
Spring4新特性——核心容器的其他改进
Spring4新特性——Web开发的增强
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
Spring4新特性——Groovy Bean定义DSL
Spring4新特性——更好的Java泛型操作API
Spring4新
CentOS安装JDK
liuxingguome
centos
1、行卸载原来的:
[root@localhost opt]# rpm -qa | grep java
tzdata-java-2014g-1.el6.noarch
java-1.7.0-openjdk-1.7.0.65-2.5.1.2.el6_5.x86_64
java-1.6.0-openjdk-1.6.0.0-11.1.13.4.el6.x86_64
[root@localhost
二分搜索专题2-在有序二维数组中搜索一个元素
OpenMind
二维数组 算法 二分搜索
1,设二维数组p的每行每列都按照下标递增的顺序递增。
用数学语言描述如下:p满足
(1),对任意的x1,x2,y,如果x1<x2,则p(x1,y)<p(x2,y);
(2),对任意的x,y1,y2, 如果y1<y2,则p(x,y1)<p(x,y2);
2,问题:
给定满足1的数组p和一个整数k,求是否存在x0,y0使得p(x0,y0)=k?
3,算法分析:
(
java 随机数 Math与Random
SaraWon
java Math Random
今天需要在程序中产生随机数,知道有两种方法可以使用,但是使用Math和Random的区别还不是特别清楚,看到一篇文章是关于的,觉得写的还挺不错的,原文地址是
http://www.oschina.net/question/157182_45274?sort=default&p=1#answers
产生1到10之间的随机数的两种实现方式:
//Math
Math.roun
oracle创建表空间
tugn
oracle
create temporary tablespace TXSJ_TEMP
tempfile 'E:\Oracle\oradata\TXSJ_TEMP.dbf'
size 32m
autoextend on
next 32m maxsize 2048m
extent m
使用Java8实现自己的个性化搜索引擎
yangshangchuan
java superword 搜索引擎 java8 全文检索
需要对249本软件著作实现句子级别全文检索,这些著作均为PDF文件,不使用现有的框架如lucene,自己实现的方法如下:
1、从PDF文件中提取文本,这里的重点是如何最大可能地还原文本。提取之后的文本,一个句子一行保存为文本文件。
2、将所有文本文件合并为一个单一的文本文件,这样,每一个句子就有一个唯一行号。
3、对每一行文本进行分词,建立倒排表,倒排表的格式为:词=包含该词的总行数N=行号