2019-07-11-想到学的

  1. webview的优化

    https://juejin.im/post/5d2605f8f265da1bc23fa07c?utm_source=gold_browser_extension

  2. javaweb简单的知识

  3. Vue

    idea 添加 VUE 的语法支持和开发

    https://blog.csdn.net/sl1990129/article/details/83794024

    getter 获取值

    Setter 比较赋值了,监视当前属性值的变化

    回调函数满足的三个条件:1.你定义的 2.你没有调用 3.但最终它执行了

    双向管理

    虚拟dom

    class和style绑定

    “ ‘a’ “ 相当于写死了 “a” 这个a是个变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- 动态确定类名 -->
    <p :class="{aClass: isA, bClass: isB}">
    xxx是个对象
    </p>

    <!-- style来确定 -->
    <p :style="{color: firstColor, fontSize: fontSize +'px'}">
    style来进行绑定
    </p>

    条件渲染

    1
    2
    3
    4
    5
    6
    7
    8
    <!--    v-if的隐藏会移除 -->
    <p v-if="ok"> 成功了!!!</p>
    <p v-else> 失败了!!!</p>
    <!-- v-show的隐藏只是应酬,标签其实还在内存里面 -->
    <p v-show="ok">你好</p>
    <p v-show="!ok">不好好</p>

    <button @click="{ok=!ok}">切换</button>

    v-for

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // vue只是监听本身,如果数组没有改变本身,只是里面的值改变,这个时候是不会刷新的
    //方法如果是个关键字,可能不生效,直接就报错了delete->是个关键字,所以不能行
    //
    <!-- 遍历数组-->
    <ul>
    <li v-for="(p, index) in persons" :key="index">
    {{index}}----{{p.name}}---{{p.age}}
    ---
    <button @click="deleteP(index)">删除</button>
    ---
    <button @click="addP(index, {name:'xxx', age:28},)">添加</button>
    </li>
    </ul>
    <!-- 遍历对象-->
    <ul>
    <li v-for="(value, key) in persons[1] " :key="key">
    {{value}} -- {{key}}
    </li>
    </ul>



    列表的收缩过滤和排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    filterPerson() {
    //取出相关的数据
    const {persons, searchName, orderType} = this;

    let fPersons;
    fPersons = persons.filter(p => p.name.indexOf(searchName) !== -1);
    if (orderType != 0) { //原本的顺序不进行排序处理
    fPersons.sort(function (p1, p2) { //如果返回-1 p1在前 返回正数 p2在前
    if (orderType == 2) {
    return p2.age - p1.age;
    } else {
    return p1.age - p2.age;
    }
    });
    }

    //对person进行过滤
    return fPersons;
    }

    绑定监听

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //默认的情况下test1方法相当于  test1($event) 默认传递了event
    //如果需要自己传值的话test1('你好', $event) 最好自己传一个$event,不然就没有默认传递$event对象了
    <button @click="test1">test1</button>
    <button @click="test2('你好', $event)">test2</button>

    data: {
    test1() {
    alert("assdfa");
    },
    test2(msg, event) {
    alert(msg+"---" + event.target.innerHTML)
    }
    }

    js event 停止事件冒泡

    1
    2
    3
    4
    5
    6
    7
    @click.stop="test6('inner')"

    <div @click="test4('outter')" style="background: blue; width:200px; height: 200px">
    <div @click.stop="test6('inner')" style="background: red; width:100px; height: 100px">

    </div>
    </div>

    阻止事件的行为

    1
    2
    3
    4
    <a href="http://www.baidu.com" @click.prevent="test6('prevent')">百度</a>

    <h2>按键修饰符</h2>
    <input type="text" @keyup.enter="test7">

    表单数据的自动收集

    生命周期函数(钩子函数):

    初始化显示

    更新

    死亡

    mounted 挂载

    1
    2
    3
    4
    //匿名函数,函数作为参数的时候
    setInterval(() => {
    this.isShow = !this.isShow
    }, 1000)

    el去进行配置,也可以动态的配置 el

生命周期

在内存中挂载好后,然后再进行页面更新

created beforeMount mounted

beforeUpdated updated

beforeDestroy

destroy destroy后页面还在,只是vue不管事情了,比如清除定时器

1
2
 mounted() ajax请求,启动定时器,等异步任务
*beforeDestroy : 做收尾工作,清除定时器

https://www.bootcdn.cn/

https://momentjs.com/

过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 <p>完整版: {{date | dateFormat('YYYY年MM月DD日 HH:mm:ss')}}</p>

//定义过滤器 函数对象
Vue.filter('dateFormat', function (value, formate) {

// return moment(value).format("YYYY年MM月DD日 HH:mm:ss")
return moment(value).format(formate || "HH:mm:ss")
}
);

或者用在参数上这样使用
Vue.filter('dateFormat', function (value, formate="HH:mm:ss") {

// return moment(value).format("YYYY年MM月DD日 HH:mm:ss")
return moment(value).format(formate)
}
);

常用的内置指令

v-cloak 指令的好处

1
2
3
4
5
6
7
[v-cloak] {
display: none;
}

<p v-cloak>{{date}}</p>

这样一开始就不会显示{{date}}了

vue开发插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--引入插件-->
<script src="./vue-myplugin.js"></script>
<script>

//声明使用插件
Vue.use(MyPlugin) //插件安装上

const vm = new Vue({
el: "#example",
data: {
msg: 'NBA I Love this Game'
}
})

</script>

Vue cli安装

项目名不能用大写

vue init webpack vue_demo

Dev.env.js 开发环境

prod.env.js 生产环境

什么是组件:component:局部的功能界面,相关的资源是它的组成部分,

html,css,js 页面三要素

Jsx => js + xml

打包

npm run build

Npm intall -g serve

serve dist

然后把dist改成和 webpack_prod #ouput 加入这个 publicPath :”/demo”

1
2
3

*.js
*.vue

都是组件化编码,组件开发

静态组件

1.拆分组件 2.静态组件(没有交互)3.动态组件 (初始化状态,可以操作)

1
2
<!--    引入CSS样式   -->
<link rel="stylesheet" href="./static/css/bootstrap.css">
1
<template> 标签里面要先写个div

组件间通信 props 定义好后,都可以this访问

1
2
3
4
5
>:comment="comment"  在组件标签里面写这个
>props:['comment'], //这个只进行了属性名的指定
>// props: { 这个是第二种实现
>// comment :Object
>// },
1
2
//数据在哪个组件,更新数据的行为(方法)就应该在哪个组件
//this.comments.unshift(comment) 放到最前面

type:Founction

1
2
3
4
var comment = {
name: this.name,
content: this.content
}

js的等于 是 === 三个等于好 !== 是也是两个

npm info pubsub-js

PubSub

组件间通信 slot

slot可以传标签,传什么标签就显示什么标签

一开始通过站位,先把位置占好,然后传递标签进去,不传就没有,传就显示传的

存储 localStorage

window.localStorage.getItem() 得到的是文本,是个字符串

Json.parse(window.localStorage.getItem() || ‘[]’)

1
2
3
4
5
6
7
8
9
watch: {
arrays: {
deep:true, //深度监视
handler: function(value) {
//json数据存储在LocalStorage
window.localStorage.setItem('todos_key', JSON.stringify(value))
}
}
}

自定义绑定监听

1
2
3
4
5
6
addTodo

@addTodo='addTodo'

//触发事件
this.$emit('addTodo', data)

获取组件对象

1
2
3
4
<TodoHeader ref="header"/>


this.$refs.header

PubSub

PubSub.subscribe(‘search’, (msg, searchName) => {

​ const url = https://api.github.com/search/users?q=${searchName};

})

数组的 map 方法

1
2
3
items.map(item => ({
url: item.html_url
}))

UI库学习

饿了么:

mint UI

Elment

这两个都是饿了么开源的库

npm install –save mint-ui

Import {Button} from ‘mint-ui’

Vue.componet(Button.name, Button)

路由(vue_05)

路由就是一种映射关系

处理请求的回调函数

前台路由,组件

路径和组件名

路由组件

1
2
3
<router-link to="/xx">
当前路由组件
<router-view>

路由组件和非路由组件

views/pages 包名

优化路由配置

嵌套路由

path最左侧的 / 是 根路径

1
2
3
4
5
6
7
8
9
10
11
12
13
{
path: '/home',
component: Home,
children: [
{
path: '/message',
component: Message
}, {
path: '/news',
component: News
}
]
}

正常情况下,路由切换后,被切换的路由会死亡,下次进来的时候,会重新创建

如果要保存起来

说是缓存路由组件实际上 缓存的是 组件的对象

1
2
3
<keep-alive>
<router-view/>
</keep-alive>

实时性比较高,就不能使用缓存来进行

:id 进行占位

query 是?后面的参数

params,就是路径上的 变参数

' ‘ 空串和 undefined 没什么区别,都不会在界面显示

进行查找 方法返回东西,返回值

this.$route.params.id * 1 如果是文本的情况下

allMessageDetails.find(detail => detail.id === this.$route.params.id)

1
2
3
4
5
watch: { //监听路由路径发生改版,就是param 发送变化
$route: function(value) {

}
}

问题:打包的过程

界面适配

:id 这种是变量,就是js变量,就会去获取js变量,进行传值了

msg=”aaa” 直接写就是,把msg作为变量传递过去

跳转页面

window.location = url,可以进行跳转

路由如何实现的, hash,通过改变hash值来进行的,浏览器可以监视这个路由变化,所以我们可以拿到这个变化,可以得到路径进行,匹配显示就可以了。

getState setState

push

replace

基本实现原理

https://github.com/DMQ/mvvm

函数中的this只有在执行的时候被确定。this是一直变化的

节点:document element attr text

数据代理

通过对象代理对另一个对象中属性的操作

//数据代理

Object.definProperty()

![image-20190715175528462](/Users/zhousaito/Library/Application Support/typora-user-images/image-20190715175528462.png)

模板解析

模板,html嵌套js代码。(指令属性,表达式)

1
2
//引入js的时候需要先引入,然后再使用
<script src="../js/compile.js"></script>

js的可以通过 updater[‘aaa’] 可以去方法名 也可以去对象

this.$vm = vm 就变成了内部的对象了

Updater && updaterFn()

1
 
数据绑定
1
2
3
//回调函数什么时候调用
//回调函数做了些什么事情
//回调函数的this是谁

Dep

初始化的给data的属性进行数据劫持时创建

个数?与data中的属性一一对应关系

dep的结构?

​ id:标识

​ subs:[] n个相关的watcher的容器

Watcher

​ 它的实例什么时候创建?

​ 初始化的解析 大括号表达式/一般指令时创建

​ 个数?

​ 与模板中的表达式(不包含事件指令[事件指令在methods里面调用了,不用进行数据绑定])

1
2
3
4
5
this.cb = cb; //用于更新界面的回调
this.vm = vm; // vm
this.expOrFn = expOrFn; //对应的表达式
this.depIds = {}; //相关的n个dep的容器对象
this.value = this.get(); //当前表达式对应的value (改的时候加判断)

Dep和watcher的关系 ( 1对多,多对多,多对一)

什么关系?

​ 多对多的关系

​ data属性—》 Dep —》 n个watcher {{name}} / v-text=”name” 多写几次就是多个watcher了

属性在模板中多次被使用

​ 表达式—》 watcher —》 n个Dep()

​ 一个表达式永远是对应一个watcher a.b 的时候,就2个dep了

多层表达式,就多个Dep()了

多个表达式使用了此属性。

n个Dep(多层表达式:a.b.c)

如何建立的?

dep和watcher创建的先后。 dep先 watcher在后面

data中属性的get()中建立

什么时候建立?

​ 初始化的解析模块中的表达式创建watcher对象时

取属性值的时候,get方法会被调用

双向绑定,就是双向赋值,dep持有watcher ,watcher持有dep

一个表达式对应一个watcher

同一个属性对应同一个Dep

初始化的时候建立了关系

vm.name = ‘abc’ —> data中的name属性变化 —》 name中的set()调用

—》 dep.notify() —> wather. update()

并不是观察的对象本身,观察的是对象中的属性。

observer进行数据劫持

双向绑定

dom事件监听

1
2
3
4
5
6
7
8
9
10
//计算的
computed: {
eventOrAdd () {
if (this.count % 2 === 0) {
return '偶数'
} else {
return '奇数'
}
}
},

vuex的库

vuex是vue的一个插件

vue应用中多个组件的共享状态进行集中式管理(读/写)

state ->data 驱动应用的数据源

view -> 界面 声明的方式将state映射到视图

​ 初始化显示

​ 更新显示

actions是行为,就是更新状态的函数

​ 包含n个更新数据状态的方法

单向数据流

![image-20190716163430568](/Users/zhousaito/Library/Application Support/typora-user-images/image-20190716163430568.png)

多组件共享状态问题

  1. 多个视图依赖于同一状态
  2. 来自不同视图的行为需要变更同一个状态
  3. 原来的解决
    1. 将数据操作行为定义在父组件
    2. 将数据以及操作数据传递到各个组件
  4. vuex就是这样产生的

Vue相关介绍

组件调action

Actions

Mutations

Const state = {}

计算属性的一部分 get

vue.x

depatch(actionName, data) 触发 action

vuex应用

npm install --save vuex

主键里面如何得到一个对象

计算属性,对应的是getters

1
2
this. 表示组件对象
this.$store

vuex结构图(管理多组件的状态)

actions 里面可以进行 ajaix请求

vuex是个全局

每个组件都能看到 $store

dispatch

更新状态就是 dispatch

render

render: h => h(App)

· => · 同时是个函数,还是return

render: function(createElement) {

​ return createElement(App)

}

项目1

  1. 监听回车 @keyup.enter=”addTodo”

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //方法一
    @keyup="toClick"

    toClick (event) { //keycode =13的时候是回车
    console.log(event.keyCode)
    alert(event.keyCode)
    }
    // 方法二
    @keyup.enter="addTodo"
  1. props: [‘todos’] 是跟data()同级的

  2. //取出相关的数据
    const {persons, searchName, orderType} = this;

  3. v-model 去绑定checkbox就可以了

    1
    <input type="checkbox" v-model="todo.complete">
  4. 放入到 computed 里面的方法,每次都会被调用, methods是事件处理的

  5. 不能在子的 vue组件中 进行 父类的 对象改变

    ​ 就是 props 传过来的对象

    ![image-20190717113739958](/Users/zhousaito/Library/Application Support/typora-user-images/image-20190717113739958.png)

  6. mapState

  7. vuex 注意事项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     ...mapState(['todos'])  //是个括号包起来的

    state : {
    todos: []
    }
    dispatch ->
    actions : {
    deleteItem({commit, state}, data) {
    commit('mutations里面的方法名', {data})
    }
    }
    ->
    mutations : {
    mutations里面的方法名(state, {data}) {
    //操作state,然后进行数据操作,最后更新到了界面上
    }
    }
  8. vuex只要更新状态就要进行 dispatch

  9. 状态非常多的时候用modules来进行 状态控制 项目量非常大的时候

    1
    2
    3
    methods: {
    ...mapActions(['deleteSelectItem'])
    },

    ![image-20190719102456735](/Users/zhousaito/Library/Application Support/typora-user-images/image-20190719102456735.png)

  1. 逆向思维

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const arr = []
    let minArr = []
    categorys.forEach(c => {
    if(minArr.lenth === 8) {
    minArr = []
    }
    if(minArr.length === 0) {
    arr.push(minArr)
    }
    minArr.push(c)
    })
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    watch: { //watch里面可以直接写对应的方法
    categroys(value) {
    new Swiper('.swiper-container', {
    loop: true,
    pagination: {
    el:'.swiper-pagination'
    }
    })

    //怎么才能已经把数据加载完了,然后进行相应的设置
    //界面更新后立马创建Swiper对象
    this.$nextTick(()=> {
    //一旦界面更新。理解调用
    //下一次dom完成后调用
    //这条语句要放在数据更新之后调用

    })

    //项目遇到什么问题
    }
    }
  2. item in 6, 提高用户体验

1
2
3
props: {
score: Number
}

{} 对象属性

计算属性,最难的时候,不知道什么时候使用计算属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
:class="'star-'+size"

5个span

<span class="start-item" v-for="(sc, index) in startClasses" :class="sc"/>

类名常量
const CLASS_ON = "on"

小数部分大于等于0.5出现half

const scoreInteger = Math.floor(score)
if(score*10 - scoreInteger*10 >=5) { 小数点不精确,所以 *10
scs.push(CLASS_HALF)
}

while(scs.length<5) {
scs.push(CLASS_SAFT)
}

js对象 {} 在html中都直接这样就好了

观察者设计模式

![image-20190716215758766](/Users/zhousaito/Library/Application Support/typora-user-images/image-20190716215758766.png)

![image-20190716222831469](/Users/zhousaito/Library/Application Support/typora-user-images/image-20190716222831469.png)

定一个小项目

读书(类似fm吗),小视

前端:android、小程序、ios/flutter

后端:java后台进行实现

> 资源储备:
>
>         1. 如何建立表结构,如何设计 (X)
>           2. 后台使用SpringBoot(√)
>
>