分类目录归档:Css/Html

javascript 面向对象程序设计

面向对象程序设计

假如没有对象,那么你就自己new 一个对象出来呗

1.工厂模式

function createPerson (name, age, job) {
  var o = new Object()
  o.name = name
  o.age = age
  o.job = job
  o.sayName = function () {
    console.log(this.name)
  } 
  o._this = this
  return o
}

var p = createPerson('chris', 18, 'softwate engineer') 
p.sayName()
console.log(p._this === this) // 这里的Person 的 this 指向windows全局

2.构造函数模式

ECMAScript可以使用构造函数创建特定的类型对象

使用new操作符实例化新对象

1)创建一个新对象

2)将构造函数的作用域复制给新对象(this指向这个对象)

3)执行构造函数中的代码(为这个新对象添加属性)

4)返回新对象

function Person (name, age, job) {
  this.name = name
  this.age = age
  this.jpb = job
  this._this = this
  this.sayName = function () {
    console.log(this.name)
  }
}
// 作为构造函数调用
var p1 = new Person('chris', 18, 'software engineer')// 这里的this指向Person构造函数
p1.sayName()
console.log(p1._this === this)
/*****************************/
// 作为普通函数调用
Person('p2name', 18, 'software engineer') // Person 挂载在全局上
window.sayName()

/*****************************/
// 在另外一个作用域中调用
var o = new Object();
Person.call(o, 'kisten', 25, 'Nurce')
o.sayName()

缺点

每个方法都要在每个实例中重新创造一遍。

即:p1.sayName() 与 p2.sayName() 不相同

3.原型模式

每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象。这个对象的用途就是包含所有实例共享的属性和方法。

function Person(){}
Person.prototype.name = 'chris'
Person.prototype.age = 18
Person.prototype.sayName = function () {
  console.log(this.name)
}
var p1 = new Person()
p1.sayName()
var p2 = new Person()
p2.sayName()
console.log(p1.sayName() === p2.sayName())

使用字面量 构建原型

function Person(){}
Person.prototype = {
  constructor: Person, // 使用过prototype等于重写了整个原型对象,所以需要在构造方法中重新指向Person()
  name: 'chris',
  age: 18,
  sayName: function () {
    console.log(this.name)
  }
}
var p1 = new Person()
p1.sayName()
var p2 = new Person()
p2.sayName()
console.log(p1.sayName() === p2.sayName())

缺点

原型中很多属性都是共享等,对于函数非常方便,对于属性就不是很方便。而且修改其中一个属性会影响另外实例的属性(因为属性和方法共享)

function Person(){}
Person.prototype = {
  constructor: Person, // 使用过prototype等于重写了整个原型对象,所以需要在构造方法中重新指向Person()
  name: 'chris',
  age: 18,
  arr: [1,2],
  sayName: function () {
    console.log(this.name)
  }
}

var p1 = new Person()
var p2 = new Person()
console.log(p1.arr, p2.arr) // [1,2], [1,2]
p1.arr.push(12)
console.log(p1.arr, p2.arr) // [1, 2, 12] [1, 2, 12]

4.组合使用构造函数模式和原型模式

function Person (name, age){
  this.name = name
  this.age = age
}

Person.prototype = {
  constructor: Person,
  sayName () {
    console.log(this.name)
  }
}

var p1 = new Person('p1', 18)
var p2 = new Person('p2', 18)
console.log(p1.name, p2.name)

Hybird App 开发中返回逻辑的控制

Hybird App 开发中返回逻辑的控制

开发中碰到一个问题。

假如有三个页面

第一个页面为 /list 列表页面,

第二个页面为/add 资料添加页面(form表单),

第三个页面是/detail 添加成功之后返回的详情页面。

三个页面的操作逻辑是。list -> add -> detail

在list页面上点击一个按钮,进入添加add的表单页面,add页面添加成功之后会跳转到detail页面。那么如果在app上点击goback到时候,就会跳转到add的form表单。这对于用于体验来说简直是灾难。

我们需要的逻辑是 点击goback的时候直接跳转到list页面,而不是add页面。

我这里采用了参考方案的解决方案一

解决方案一

add页面或detail页面添加成功标记

你可以在add 页面或者 detail页面添加添加成功的标记

window.sessionStorage.setItem("addStatus","true")

这里使用sessionStorage,通过设置一个状态标记添加成功。

然后在list页面,需要刷新addStatus的状态

sessionStorage.clear()

参考

css常用技巧 | css水平居中元素 | css垂直居中元素| 浮动模块父元素高度为0

css常用技巧

之前写css的时候,总会有一些疑惑,所以需要总结一下,并归纳整理。

css水平居中一个元素

  • 如果需要居中的元素为常规流中inline元素,为父元素设置text-align: center;即可实现
  • 如果需要居中的元素为常规流中block元素,1)为元素设置宽度,2)设置左右margin为auto。3)IE6下需在父元素上设置text-align: center;,再给子元素恢复需要的值
<body>
    <div class="content">
    aaaaaa aaaaaa a a a a a a a a
    </div>
</body>

<style>
    body {
        background: #DDD;
        text-align: center; /* 3 */
    }
    .content {
        width: 500px;      /* 1 */
        text-align: left;  /* 3 */
        margin: 0 auto;    /* 2 */

        background: purple;
    }
</style>
  • 如果需要居中的元素为浮动元素,1)为元素设置宽度,2)position: relative;,3)浮动方向偏移量(left或者right)设置为50%,4)浮动方向上的margin设置为元素宽度一半乘以-1
<body>
    <div class="content">
    aaaaaa aaaaaa a a a a a a a a
    </div>
</body>

<style>
    body {
        background: #DDD;
    }
    .content {
        width: 500px;         /* 1 */
        float: left;

        position: relative;   /* 2 */
        left: 50%;            /* 3 */
        margin-left: -250px;  /* 4 */

        background-color: purple;
    }
</style>

  • 如果需要居中的元素为绝对定位元素,1)为元素设置宽度,2)偏移量设置为50%,3)偏移方向外边距设置为元素宽度一半乘以-1
<body>
    <div class="content">
    aaaaaa aaaaaa a a a a a a a a
    </div>
</body>

<style>
    body {
        background: #DDD;
        position: relative;
    }
    .content {
        width: 800px;

        position: absolute;
        left: 50%;
        margin-left: -400px;

        background-color: purple;
    }
</style>

  • 如果需要居中的元素为绝对定位元素,1)为元素设置宽度,2)设置左右偏移量都为0,3)设置左右外边距都为auto
<body>
    <div class="content">
    aaaaaa aaaaaa a a a a a a a a
    </div>
</body>

<style>
    body {
        background: #DDD;
        position: relative;
    }
    .content {
        width: 800px;

        position: absolute;
        margin: 0 auto;
        left: 0;
        right: 0;

        background-color: purple;
    }
</style>

如何竖直居中一个元素

参考资料:6 Methods For Vertical Centering With CSS盘点8种CSS实现垂直居中

  • 需要居中元素为单行文本,为包含文本的元素设置大于font-sizeline-height
<p class="text">center text</p>

<style>
.text {
    line-height: 200px;
}
</style>
  • 垂直水平居中

看content4使用margin和postition来使用定位,但是必须规定长度或者宽度。在移动端可以配合淘宝的flexiable和rem来实现

<body>
    <div class="test4">
        <div class="content4">
            dafdasf
        </div>
    </div>
</body>

<style>
    body {
        background: #DDD;
        text-align: center; /* 3 */
    }
    .content4 {  
        margin: auto;  
        position: absolute;  
        top: 0; left: 0; bottom: 0; right: 0;  
        height: 100px;
        width: 100px;
    }  
</style>

清除css浮动父元素高度为0

方案一

在浮动元素下面加一个清除浮动的元素:div{clear:both}

html

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div

css

.clearfix:after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
}

方案二

将父元素也设置为浮动的

html

<div style="float: left;">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>

方案三

为父元素显式的设置高度,不推荐

html

<div style="height: 400px;">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>        
</div>

方案四

为父元素加入overflow:hidded属性或者overflow:auto属性

html

<div style="overflow: hidden;">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>        
</div>

上面四种方案,方案一比较靠谱,兼容性最强

参考1

参考2

vue组件通讯|vue父子组件通讯demo

vue组件通讯

最近一直在写报表的页面,也碰到了非常多组件通讯的问题,最近准备重构和总结一下。因为之前是第一次上手vue-cli + echarts + mint-ui,所以前一次写的代码自己非常的不满意。第一次的报表完成图,大致如下gif所示。下面就是总结一下一些组件通讯的方式吧。温故知新。

报表页面

父子组件通讯

数据从父组件到子组件

数据从父组件到子组件是最容易理解的,因为vue是单向数据流,所以数据就像水流一样,从高处到低处,这里为理解为,从父组件流向子组件。

vue

目录如下所示

vue

Main.vue

<template>
  <div class="main">
    //需要传递到子组件的数据,并且绑定到type上
    <header-nav :type="type"></header-nav>
  </div>
</template>

<script>
import HeaderNav from './HeaderNav.vue';
export default {
  name: 'hello',
  components: {
    HeaderNav
  },
  data() {
    return {
      type: {
        summary: '汇总',
        trend: '走势',
      },
      selected: 1
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style lang="stylus" rel="stylesheet/stylus">

</style>

HeaderNav

<template>
  <div class="header">
    <mt-navbar v-model="selected">
      <mt-tab-item id="summary">{{type.summary}}</mt-tab-item>
      <mt-tab-item id="trend">{{type.trend}}</mt-tab-item>
    </mt-navbar>

    <!-- tab-container -->
    <mt-tab-container v-model="selected">
      <mt-tab-container-item id="1">
        summary
      </mt-tab-container-item>
      <mt-tab-container-item id="2">
        trend
      </mt-tab-container-item>
    </mt-tab-container>
  </div>
</template>

<script>
export default {
  name: 'headerNav',
  //父组件传递来的数据
  props: ['type'],
  data() {
    return {
        selected:"summary"
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="stylus" rel="stylesheet/stylus">
  .test
    font-size 50px
</style>

数据从子组件到父组

子组件将数据传递到父组件,主要到方法是$emit()和$on方法

vue自定义事件

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

Main.vue

<template>
  <div class="main">
    <!--通过on-v绑定transferUser自定义事件监听 transferUser为子组件中的自定义事件-->
    <header-nav :type="type" @transferUser="getUser"></header-nav>
    <span>this is name</span>
    <span>{{user}}</span>
    <br>
    <router-link to='/selectTime'>
      selectTime
    </router-link>
  </div>
</template>

<script>
import HeaderNav from './HeaderNav.vue';
import selectTime from './selectTime.vue';
export default {
  name: 'hello',
  components: {
    HeaderNav,
    selectTime
  },
  data() {
    return {
      type: {
        summary: '汇总',
        trend: '走势',
      },
      selected: 1,
      user: '',
    }
  },
  methods: {
    getUser(msg){
      this.user = msg
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style lang="stylus" rel="stylesheet/stylus">

</style>

HeaderNav.vue

<template>
  <div class="header">
    <!--出发change事件调用setUser,绑定自定义事件transferUser,并传入参数-->
    <input type="text" v-model="username" @change="setUser">
  </div>
</template>

<script>
export default {
  name: 'headerNav',
  props: ['type'],
  data() {
    return {
        selected:"summary",
        username:''
    }
  },
  methods: {
    // 触发自定义事件
    setUser:function(){
      this.$emit('transferUser', this.username)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="stylus" rel="stylesheet/stylus">
  .test
    font-size 50px
</style>