This commit is contained in:
huayu 2022-01-22 10:02:50 +08:00
parent efcea763dd
commit 76bc12c2d2
28 changed files with 1395 additions and 19 deletions

27
jvm/JVM内存模型JMM.md Normal file
View File

@ -0,0 +1,27 @@
大对象,新生代存储不下的对象,分配担保直接到老年代。
1. 年龄超过15
2. 相同年龄超过50%
3. 动态年龄分配,不同年龄特别多。
4. 内存担保,新生代垃圾回收无法完成,直接放入老年代。 **在GC前还会进行一次判断如果要分配的内存>=Eden区大小的一半那么会直接把要分配的内存放入老年代中。否则才会进入担保机制。**
TLAB的全称是Thread Local Allocation Buffer即线程本地分配缓存区这是一个线程专用的内存分配区域。
java -XX:+PrintCommandLineFlags -version
什么样的对象要被GC
判断回收算法
- 引用计数法,相互引用,循环引用
- 可达性分析GCroot本地变量表引用对象用来关联对象关系、方法区中的静态变量和常量虚拟机栈中本地变量表局部变量static成员常量引用本地方法栈中变量类加载器Thread
- 不可达对象finalize可以挽回一次防止回收。
- 本地方法栈中JNI引用的对象
### 对象头内存分配
![](img\对象头描述.png)
![](img\对象头信息分布.png)
![](img\锁描述.png)

9
jvm/JVM垃圾回收.md Normal file
View File

@ -0,0 +1,9 @@
## GC范围
GC管理的主要区域是Java堆一般情况下只针对堆进行垃圾回收。方法区、栈和本地方法区不被GC所管理,因而选择这些区域内的对象的引用作为GC roots被GC roots引用的对象不被GC回收。
## 垃圾收集器
- 并行parallel多个垃圾收集线程并行工作此时用户线程处于等待状态。
- 并发concurrent用户线程和垃圾收集线程同时执行。
- 吞吐量:用户代码执行时间/(用户代码执行时间+垃圾收集时间)

View File

@ -1,28 +1,28 @@
# JVM简介
write once run everywhere
优势:
1. write once run everywhere
2. 内存管理
## jvm空间加载运行
参考jvm规范https://docs.oracle.com/javase/specs/index.html
### 空间、运行时数据区
- 线程共享
- Heap堆在虚拟机启动时创建此内存区域的唯一目的就是存放对象实例几乎所有的对象实例都在这里分配内存。存储数据不是线程安全的<u>**堆和常量池**</u>空间不足时会触发OutOfMemoryError
- MetaSpace元数据区在1.8之后取代Method Area 方法区永久代不在jvm中使用本地内存受操作系统内存限制。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
- 线程隔离
- VM Stack虚拟机栈每个线程创建一个单独的运行时堆栈。对于每一个方法调用一个称为栈内存栈帧被创建。所有局部变量将被创建在栈内存中。栈区域时线程安全的因为他不是一个共享资源。
- Navive Method Stack本地方法栈与虚拟机所发挥的作用是非常相似的其区别不过是虚拟机栈为虚拟机执行java方法也就是字节码服务而本地方法栈则是为虚拟机使用到的Native方法服务。
- Program Counter Register 程序计数器:每个线程必须分开程序计数器登记,当前执行的指令一旦被执行,程序计数器更新下一个指令。一块较小的内存空间。他的作用可以看做是当前线程所执行的字节码的行号指示器。
-
### 加载
![](img\class文件加载.png)
- 类加载器
- Bootstrap加载环境变量中$JAVA_HOME/jre/lib/rt.jar里所有的class不是ClassLoader子类。
- Extension加载java平台中扩展功能的一些jar包。包括环境变量中$JAVA_HOME/jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包。
- Application加载classpath中指定的jar包及目录中class。
- Custom自定义应用程序根据自身需要自定义的ClassLoader如tomcat、jboss都会根据j2ee规范自行是实现ClassLoader
- 双亲委派
- 写类String写main方法无法启动Bootstrap Class Loader 中已经加载了String其中无main方法无法启动。委派给父类所有父类都加载不到才会有子类加载。不让jdk代码被修改。
### 链接
@ -34,12 +34,39 @@ write once run everywhere
- 类或接口的初始化由执行类或接口初始化方法构成,这里所有的静态变量与原来的值将被指派,静态块将被执行。
### 线程空间
![](img\线程内存使用.png)
![](img\虚拟机栈.png)
- 线程共享
- Heap堆在虚拟机启动时创建此内存区域的唯一目的就是存放对象实例几乎所有的对象实例都在这里分配内存。存储数据不是线程安全的<u>**堆和常量池**</u>空间不足时会触发OutOfMemoryError
- MetaSpace元数据区在1.8之后取代Method Area 方法区永久代不在jvm中使用本地内存受操作系统内存限制。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
- 线程隔离
- VM Stack虚拟机栈每个线程创建一个单独的运行时堆栈。对于每一个方法调用一个称为栈内存栈帧被创建。所有局部变量将被创建在栈内存中。栈区域时线程安全的因为他不是一个共享资源。
- Navive Method Stack本地方法栈与虚拟机所发挥的作用是非常相似的其区别不过是虚拟机栈为虚拟机执行java方法也就是字节码服务而本地方法栈则是为虚拟机使用到的Native方法服务。
- Program Counter Register 程序计数器:每个线程必须分开程序计数器登记,当前执行的指令一旦被执行,程序计数器更新下一个指令。一块较小的内存空间。他的作用可以看做是当前线程所执行的字节码的行号指示器。
### 运行时数据区
- 程序计数器:指向当前线程正在执行的字节码指令的地址和行号
- 虚拟机栈:存储当前线程运行方法所需的数据、指令、返回地址(动态链接,注入使用查找实例)。
- - 栈帧:局部变量表,操作数栈、动态链接、出口
- javap -c -v .class > p.txt
- 本地方法 native
- 方法区 类信息、常量、静态变量、JITjust in time编译时信息永久代对方法的实现
- Heap 堆内存模型存放new出来的对象
- - 新生代
- 老年代
- 永久代/元数据区(方法区、非堆)
## 内存空间分配
![image-20211020152033799](img\image-20211020152033799.png)
## 垃圾收集器
- 并行parallel多个垃圾收集线程并行工作此时用户线程处于等待状态。
- 并发concurrent用户线程和垃圾收集线程同时执行。
- 吞吐量:用户代码执行时间/(用户代码执行时间+垃圾收集时间)

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
jvm/img/对象头描述.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
jvm/img/虚拟机栈.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
jvm/img/锁描述.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
mq/rabbitmq/img/mqport.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

25
mq/rabbitmq/rabbitmq.md Normal file
View File

@ -0,0 +1,25 @@
## 安装
https://www.rabbitmq.com/install-debian.html
## 启动
```shell
## 启动
systemctl start rabbitmq-server
## 启动web ui
rabbitmq-plugins enable rabbitmq_management
## 启动websocket
rabbitmq-plugins enable rabbitmq_web_stomp
# create a user
rabbitmqctl add_user full_access s3crEt
# tag the user with "administrator" for full management UI and HTTP API access
rabbitmqctl set_user_tags full_access administrator
```
## 端口
https://www.rabbitmq.com/install-debian.html
![](img\mqport.png)

0
netty/netty注释.md Normal file
View File

View File

@ -0,0 +1,24 @@
# debug findAll
1. JpaSpecificationExecutor::Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);
2. SimpleJpaRepository::public Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable)
3. CriteriaQueryTypeQueryAdapter::getResultList()
4. AbstractProducedQuery::list()
5. AbstractProducedQuery::beforeQuery()
6. 执行第一条sqlfinal PreparedStatement st = prepareQueryStatement( sql, queryParameters, limitHandler, scroll, session );
根据结果获取内容
```java
final List results = getRowsFromResultSet(
rs,
queryParameters,
session,
returnProxies,
forcedResultTransformer,
maxRows,
nullSeparatedHydratedObjectsPerRow,
subselectResultKeys
);
```

206
vue/1-vue官网学习.md Normal file
View File

@ -0,0 +1,206 @@
#### 绑定 v-bind
v-bind attribute :将这个元素节点的 `title` attribute 和 Vue 实例的 `message` property 保持一致
```javascript
<div id="app-2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
var app2 = new Vue({
el: '#app-2',
data: {
message: '页面加载于 ' + new Date().toLocaleString()
}
})
```
在控制台输入改变信息app2.message = '新消息'
#### 控制元素显示 v-if
```js
<div id="app-3">
<p v-if="seen">现在你看到我了</p>
</div>
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
```
直接在控制台改变属性app3.seen = false
#### 循环展示 v-for
```js
<div id="app-4">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div>
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: '学习 JavaScript' },
{ text: '学习 Vue' },
{ text: '整个牛项目' }
]
}
})
```
在控制台改变内容app4.todos.push({ text: '新项目' })
#### 添加一个事件监听器 v-on
```javascript
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">反转消息</button>
</div>
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
```
#### 表单输入和应用状态之间的双向绑定 v-model
```js
<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div>
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
```
#### 组件
- 任意类型的应用界面都可以抽象为一个组件树。
- 子单元通过 prop 接口与父单元进行了良好的解耦。
- 所有的 Vue 组件都是 Vue 实例。
```js
Vue.component('todo-item', {
// todo-item 组件现在接受一个
// "prop",类似于一个自定义 attribute。
// 这个 prop 名为 todo。
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
<div id="app-7">
<ol>
<!--
现在我们为每个 todo-item 提供 todo 对象
todo 对象是变量,即其内容可以是动态的。
我们也需要为每个组件提供一个“key”稍后再
作详细解释。
-->
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div>
var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: '蔬菜' },
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' }
]
}
})
```
#### 响应式
- 当一个 Vue 实例被创建时,它将 `data` 对象中的所有的 property 加入到 Vue 的**响应式系统**中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
- 值得注意的是只有当实例被创建时就已经存在于 `data` 中的 property 才是**响应式**的。
- `Object.freeze()`,这会阻止修改现有的 property也意味着响应系统无法再*追踪*变化。
```js
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
<div id="app">
<p>{{ foo }}</p>
<!-- 这里的 `foo` 不会更新! -->
<button v-on:click="foo = 'baz'">Change it</button>
</div>
```
- 除了数据 propertyVue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 `$`,以便与用户定义的 property 区分开来。
```js
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
```
#### 生命周期钩子
- 生命周期钩子的 `this` 上下文指向调用它的 Vue 实例。
- 不要在选项 property 或回调上使用箭头函数
```js
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
```
![](img\lifecycle.png)

110
vue/2-模板语法.md Normal file
View File

@ -0,0 +1,110 @@
如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,[直接写渲染 (render) 函数](https://cn.vuejs.org/v2/guide/render-function.html),使用可选的 JSX 语法。
#### 数据绑定
- 数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值。
- 通过使用 [v-once 指令](https://cn.vuejs.org/v2/api/#v-once)你也能执行一次性地插值当数据改变时插值处的内容不会更新类似Object.freeze()。但请留心这会影响到该节点上的其它数据绑定。
```js
<span>Message: {{ msg }}</span>
<span v-once>这个将不会改变: {{ msg }}</span>
```
#### v-html
- 双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML你需要使用 v-html 指令
```js
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
```
#### v-bind
- Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind
```js
<div v-bind:id="dynamicId"></div>
// 如果 isButtonDisabled 的值是 null、undefined 或 false则 disabled attribute 甚至不会被包含在渲染出来的 <button> 元素中。
<button v-bind:disabled="isButtonDisabled">Button</button>
```
#### javascript语法
```
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
```
- 数据绑定支持javascript语法
- 每个绑定都只能包含**单个表达式**
- 模板表达式都被放在沙盒中,只能访问[全局变量的一个白名单](https://github.com/vuejs/vue/blob/v2.6.10/src/core/instance/proxy.js#L9),如 `Math``Date` 。你不应该在模板表达式中试图访问用户定义的全局变量。
```js
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}
```
#### 指令v-
- 指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
```js
<p v-if="seen">现在你看到我了</p>
```
#### 参数
```js
<a v-bind:href="url">...</a>
// 在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。
<a v-on:click="doSomething">...</a>
// 在这里参数是监听的事件名。
<a v-bind:[attributeName]="url"> ... </a>
// 这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property // attributeName其值为 "href",那么这个绑定将等价于 v-bind:href。
<a v-on:[eventName]="doSomething"> ... </a>
// 当 eventName 的值为 "focus" 时v-on:[eventName] 将等价于 v-on:focus。
```
- 在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写
```js
<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`
除非在实例中有一个名为“someattr”的 property否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>
```
#### 修饰符
- 修饰符 (modifier) 是以半角句号 `.` 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,`.prevent` 修饰符告诉 `v-on` 指令对于触发的事件调用 `event.preventDefault()`
```js
<form v-on:submit.prevent="onSubmit">...</form>
```
#### 缩写:@
```js
<!-- v-bind 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>
<!-- v-on 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
```

View File

@ -0,0 +1,154 @@
## computed
#### 计算属性
- 计算属性是基于它们的响应式依赖进行缓存的
```js
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
```
#### 监听属性
- 类似watch
```js
<div id="demo">{{ fullName }}</div>
// watch
var vm = new Vue({
el: '#demo',
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
}
}
})
//
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
```
#### set
```js
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 = 'John Doe' 时setter 会被调用vm.firstName 和 vm.lastName 也会相应地被更新。
```
## 监听器
- 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
- 在这个示例中,使用 `watch` 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
```js
<div id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question">
</p>
<p>{{ answer }}</p>
</div>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
el: '#watch-example',
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
},
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
created: function () {
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
// 请参考https://lodash.com/docs#debounce
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
},
methods: {
getAnswer: function () {
if (this.question.indexOf('?') === -1) {
this.answer = 'Questions usually contain a question mark. ;-)'
return
}
this.answer = 'Thinking...'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function (response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function (error) {
vm.answer = 'Error! Could not reach the API. ' + error
})
}
}
})
</script>
```

View File

@ -0,0 +1,86 @@
### v-bind:class
#### 属性
- 我们可以传给 `v-bind:class` 一个对象,以动态地切换 class
```js
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
data: {
isActive: true,
hasError: false
}
```
#### 对象
```js
<div class="static active"></div>
//绑定的数据对象不必内联定义在模板里:
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
```
#### 数组
```js
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
<div class="active text-danger"></div>
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
```
#### 用在组件上
组件中信息不会被覆盖而是追加
### 绑定内联样式 v-bind:style
- CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case记得用引号括起来) 来命名
```html
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<div v-bind:style="styleObject"></div>
<div v-bind:style="[baseStyles, overridingStyles]"></div>
```
```js
data: {
activeColor: 'red',
fontSize: 30
}
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
```

71
vue/5-条件渲染.md Normal file
View File

@ -0,0 +1,71 @@
#### v-if
- 当 `v-if``v-for` 一起使用时,`v-for` 具有比 `v-if` 更高的优先级。不推荐两个一起使用
```html
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
```
#### key管理可复用元素
- 那么在上面的代码中切换 `loginType` 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,`<input>` 不会被替换掉——仅仅是替换了它的 `placeholder`
```html
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
```
- 这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 `key` attribute 即可
```html
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
```
#### v-show
```html
<h1 v-show="ok">Hello!</h1>
```
- v-show` 不支持 `<template>` 元素,也不支持 `v-else

221
vue/6-列表渲染.md Normal file
View File

@ -0,0 +1,221 @@
#### v-for
```html
<ul id="example-1">
<li v-for="item in items" :key="item.message">
{{ item.message }}
</li>
</ul>
```
```js
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
```
```html
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
```
```js
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
```
### v-for遍历一个对象的元素
```html
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>
```
```js
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
```
#### 显示过滤/排序后的结果
- 有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。
```html
<li v-for="n in evenNumbers">{{ n }}</li>
```
```js
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
```
- 在计算属性不适用的情况下 (例如,在嵌套 `v-for` 循环中) 可以使用一个方法
```html
<ul v-for="set in sets">
<li v-for="n in even(set)">{{ n }}</li>
</ul>
```
```js
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
})
}
}
```
```html
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
```
#### v-for,v-if 一同使用
- 当它们处于同一节点,`v-for` 的优先级比 `v-if` 更高,这意味着 `v-if` 将分别重复运行于每个 `v-for` 循环中。当你只想为*部分*项渲染节点时,这种优先级的机制会十分有用。
-
```html
<--代码将只渲染未完成的 todo-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
```
#### v-for在组件中
```html
<div id="todo-list-example">
<form v-on:submit.prevent="addNewTodo">
<label for="new-todo">Add a todo</label>
<input
v-model="newTodoText"
id="new-todo"
placeholder="E.g. Feed the cat"
>
<button>Add</button>
</form>
<ul>
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-on:remove="todos.splice(index, 1)"
></li>
</ul>
</div>
```
```js
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">Remove</button>\
</li>\
',
props: ['title']
})
new Vue({
el: '#todo-list-example',
data: {
newTodoText: '',
todos: [
{
id: 1,
title: 'Do the dishes',
},
{
id: 2,
title: 'Take out the trash',
},
{
id: 3,
title: 'Mow the lawn'
}
],
nextTodoId: 4
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
})
```

125
vue/7-事件处理.md Normal file
View File

@ -0,0 +1,125 @@
```html
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
<div id="example-2">
<!-- `greet` 是在下面定义的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
```
```js
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
// 也可以用 JavaScript 直接调用方法
example2.greet() // => 'Hello Vue.js!'
```
#### 内联处理器中的方法调用
- 有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 `$event` 把它传入方法
```html
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
</div>
```
```js
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
},
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
})
```
#### [事件修饰符](https://cn.vuejs.org/v2/guide/events.html#事件修饰符)
- 键盘按键处理
- 鼠标按键处理
```html
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
<!-- 只有在 `key``Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<input v-on:keyup.page-down="onPageDown">
<input v-on:keyup.13="submit">
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
<!-- Alt + C -->
<input v-on:keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div v-on:click.ctrl="doSomething">Do something</div>
```

View File

@ -0,0 +1,27 @@
## v-model
```html
<div id="example-6">
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
```
```js
new Vue({
el: 'example-6',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
```

56
vue/9-组件基础.md Normal file
View File

@ -0,0 +1,56 @@
- 因为组件是可复用的 Vue 实例,所以它们与 `new Vue` 接收相同的选项,例如 `data`、`computed`、`watch`、`methods` 以及生命周期钩子等。仅有的例外是像 `el` 这样根实例特有的选项。
- 一个组件的 `data` 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
- 通过prop向组件传递数据`v-on` 监听子组件实例的任意事件
- [从一个 API 获取博文列表](https://codesandbox.io/s/github/vuejs/vuejs.org/tree/master/src/v2/examples/vue-20-component-blog-post-example)
```js
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
```
```html
<div id="components-demo">
<button-counter></button-counter>
</div>
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></blog-post>
```
```html
new Vue({ el: '#components-demo' })
new Vue({
el: '#blog-post-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
})
```
## [动态组件](https://cn.vuejs.org/v2/guide/components.html#动态组件)
https://codesandbox.io/s/github/vuejs/vuejs.org/tree/master/src/v2/examples/vue-20-dynamic-components

View File

@ -1,4 +1,4 @@
目录查看
### 目录查看
1. node_modules安装依赖打包
2. public图片文件index.html
@ -34,3 +34,76 @@
17. vue.config.js:
vue-cli-service serve
### 总结
当配置baseURL时代理不生效。
```js
const request = axios.create({
timeout: 30000, // 请求超时时间
baseURL: process.env.VUE_APP_URL,
withCredentials: true
});
proxy: {
'/': { // 代理api
target: 'http://localhost:8085', // 服务器api地址
changeOrigin: true//, // 是否跨域
// pathRewrite: {
// '^/': 'http://qiankun.bj-fanuc.com.cn/finance-admin/charts/selectChartDataByPageModel' // 路径重写
// }
}
}
```
## 启动跟踪
```js
npm run dev
```
文件package.json
```json
"dev": "webpack-dev-server --inline --progress --module-bind production --config build/webpack.dev.conf.js "
```
文件build/webpack.dev.conf.js
```js
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
},
proxy: {
'/*': { // 代理api
target: 'http://localhost8080/', // 服务器api地址
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/*': 'http://localhost:8081/' // 路径重写
}
}
}
},
```

BIN
vue/img/lifecycle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

98
vue/webpack打包.md Normal file
View File

@ -0,0 +1,98 @@
## 基本参数
[基本参数说明](https://webpack.docschina.org/concepts)
1. 入口(entry)
2. 输出(output)
3. loader
4. 插件(plugin)
5. 模式(mode)
6. 浏览器兼容性(browser compatibility)
7. 环境(environment)
## 默认配置
1. 入口起点为 `src/index.js`
2. 然后会在 `dist/main.js` 输出结果
3. 并且在生产环境开启压缩和优化
4. 通常你的项目还需要继续扩展此能力,为此你可以在项目根目录下创建一个 `webpack.config.js` 文件,然后 webpack 会自动使用它。
[webpack.config.js配置](https://webpack.docschina.org/configuration)
**“webpack 配置的可扩展”** 是指,这些配置可以重复使用,并且可以与其他配置组合使用。这是一种流行的技术,用于将关注点从环境(environment)、构建目标(build target)、运行时(runtime)中分离。然后使用专门的工具(如 [webpack-merge](https://github.com/survivejs/webpack-merge))将它们合并起来。
- 使用 JavaScript 控制流表达式,例如 `?:` 操作符
- 精心编写的 **模块** 提供了可靠的抽象和封装界限,使得应用程序中每个模块都具备了条理清晰的设计和明确的目的。
- 应保证 loader 的先后顺序:[`'style-loader'`](https://webpack.docschina.org/loaders/style-loader) 在前,而 [`'css-loader'`](https://webpack.docschina.org/loaders/css-loader) 在后
## 基础文件
1. index.html是主入口
2. app.js是我们写的模块,并依据CommonJS规范导出这个模块
3. main.js其实是一个组件,它的目的是将我们写的一些代码模块返回并插入到页面中
不兼容问题升级
```js
npm i -D html-webpack-plugin@webpack-contrib/html-webpack-plugin
```
临时删除一些错误包
```
"eslint-loader": "^2.0.0",
"element-ui": "^2.15.7",
"less-loader": "6.0.0",
"jest": "^27.4.5",
"jest-serializer-vue": "^0.3.0",
"babel-jest": "^27.4.5",
"vue-jest": "^1.0.2",
"friendly-errors-webpack-plugin": "2.0.0-beta.2",
"uglifyjs-webpack-plugin": "2.2.0",
"babel-plugin-transform-runtime": "^7.14.0",
"@babel/core": "^7.12.3",
"@babel/plugin-transform-runtime": "7.12.13",
"@babel/preset-env": "^7.16.7",
"babel-eslint": "^10.0.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-plugin-transform-vue-jsx": "4.0.1",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"@babel/preset-env":"7.16.7"
"babel-plugin-react-intl": "^8.2.15",
npm instal babel-preset-env
npm install babel-preset-stage-2
"babel-plugin-transform-runtime": "^6.23.0",
"babel-plugin-transform-vue-jsx": "^4.0.1",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-2": "^6.24.1",
-----------------------------------
"@babel/core": "^7.16.7",
"@babel/preset-env": "^7.16.7",
"babel-loader": "^8.2.3",
"babel-preset-stage-2": "7.0.0-beta.3",
"babel-runtime": "6.26.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"babel-preset-env": "^1.7.0",
"@babel/preset-stage-2": "^7.8.3",
TypeError: src/main.js: this.setDynamic is not a function
```

View File

@ -0,0 +1,36 @@
组件类似与java中的类(对象)。
#### 全局组件
```js
Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })
new Vue({ el: '#app' })
```
```html
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
```
#### 局部组件
```js
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
```

View File

@ -20,3 +20,4 @@
18. ~~解决方案文档~~
19. 修改接口确保之前逻辑不变
19. EntityGraph多看源码注释下同级别有类似注释。
19. 用心做好每件事,每个人每件事,都值得被认真对待。