2

前端学习记录 week 1

基础知识

CSS盒模型

所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容

  • Margin - 清除边框外的区域,外边距是透明的。
  • Border - 围绕在内边距和内容外的边框。
  • Padding - 清除内容周围的区域,内边距是透明的。
  • Content(内容) - 盒子的内容,显示文本和图像。
  • CSS3新增box-sizing;border-box:将padding、border的宽度计算在宽度width里面。

html5标签

  • template: 通过 JavaScript 在运行时实例化内容的容器。
  • header: 定义页面或章节的头部。它经常包含 logo、页面标题和导航性的目录。
  • footer: 定义页面或章节的尾部。它经常包含版权信息、法律信息链接和反馈建议用的地址。
  • aside: 定义和页面内容关联度较低的内容——如果被删除,剩下的内容仍然很合理。
  • section: 定义文档中的一个章节。
  • nav: 定义只包含导航链接的章节。
  • audio:定义音频内容(属性:autoplay、controls、loop、muted、preload)
  • video: 定义视频(属性同上)

- JavaScript数据类型及数据结构

JavaScript是一种弱类型语言

  • 6种原始类型

    • Bool
    • Object
    • String
    • Null
    • Undefined
    • Number

*可以使用typeof 判断数据类型,数组以及null都属于Object
*Object属于引用类型,具有:constructor、hasOwnProperty、isPropertyOf、propertyIsEnumerable等方法。

  • 对象的属性

    • 数据属性:包含一个数据值的位置,可以读写包含Configurable、Enumerable、Writable、Value 4个特性
    • 访问器属性: 不含数据值可以包含getter、setter函数,读取以及写入会分别触发这两个方法,包含Configurable、Enumerable、get、set特性

修改默认特性使用defineProperty(),访问器属性不能直接定义,只能调该用方法。

  • 对象的创建

    • 工厂模式
    • 构造函数
    • 原型模式

构造函数:

  function Person(name, age ,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        console.log(this.name);
    }
  }
  
  let person1 = new Person("name", 20, "job");

原型模式:

  function Person(){
  }
  
  Person.prototype.name = "name";
  Person.prototype.age = 20;
  Person.prototype.job = "job";
  Person.prototype.sayName = function(){
     console.log(this.name);
  }
  
  let person1 = new Person();
    • JavaScript常用的字符串操作

      • substring() – 返回字符串的一个子串。传入参数是起始位置和结束位置。
      • substr() - 返回字符串的一个子串。传入参数是起始位置和个数。
      • replace() – 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。
      • slice() – 提取字符串的一部分,并返回一个新字符串。
      • split() – 通过将字符串划分成子串,将一个字符串做成一个字符串数组。
      • length – 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。
      • toLowerCase() – 将整个字符串转成小写字母。
      • toUpperCase() – 将整个字符串转成大写字母。
      • concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串。
      • indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1 。
      • charAt() – 返回指定位置的字符。
      • match() – 检查一个字符串是否匹配一个正则表达式
    • JavaScript常用的数组操作

      - concat - 合并数组
      - push、pop - 分别为添加、删除元素,堆栈形式
      - unshift、shift  - 添加、删除元素,队列形式
      - reverse - 反转
      - sort() - 排序, arr.sort(function(a,b){return a-b;} 输入比较函数
      - slice、splice - 删除,参数为起始位置和个数,slice不改变原素组,返回新数组,splice会改变原素组,返回被删除的数组。
      - substring、substr - 截取数组,类似于上面字符串中的这两个方法。

    JavaScript模块化

    为了不让分块的代码污染全局,以及更好地使用别人的代码所以产生了JavaScript模块化的需求

    可以使用立即执行函数

      var params = 'test';
      
      var module = (function(params){
        var mod = function(){
          //...
        };
        return {mod: mod};
      })(params);

    外部不能直接访问模块内部的变量,传入外部变量后,在内部改变它的值也不影响全局。

    • 闭包

    CSS3部分新特性

    • border-radius: 边框圆角
    • box-sizing:border-box、content-box
    • box-shadow: 阴影
    • background-size
    • background-origin:背景显示区域,content-box、padding-box 或 border-box
    • text-shadow:文字阴影
    • word-wrap:文本强制换行
    • @font-face: 字体
    • transform:2D,3D转换 ratate、translate、scale、skew
    • transition:过度
    • animation:动画
    • @keyframes:创建动画规则

    vue基础

    常用指令
    • v-if、v-else-if、v-else
    • v-show
    • v-on 缩写@
    • v-bind
    • v-model
    • v-for
    • v-html
    • v-text

    特性

    • ref:在元素上添加该属性,替代原生JavaScript获取dom操作 this.$refs.name
    绑定内联样式以及类

    以下写法涉及到了所有样式以及类名的绑定方式,不详细说明了

    • 样式
    :style=“[item.a,item.b]” 
    :style="{width:item.value+'px'}"   
    :style="{color: activeColor, fontSize: fontSize + 'px' }"
    :style="item.titlefont"
    :style="a<0? 'color:red':'color:black'"
    :style="item.choosetype==3?{width:ul_width+'px'}:''"
    :class="{a:item.x==1}"     
    :class="[b ,{a:item.x==1}]"    
    :class="{a:item.x==1, b:item.x==2}"    
    <div v-bind:class="[isActive ? activeClass : '', errorClass]">

    实践

    一、个人中心-生活馆页面

    遇到的问题以及学习到的知识点

    1. 内层div的margin-top属性转移到了外层div上
        <div class="member-card">
            <!--header外边距体现在外层div上-->
          <header>{{constellation}}</header>
            <footer>
            <div>{{memberGrade}}</div>
            <div>{{memberName}}</div>
          </footer>
        </div>

    原因

    • 当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
    • 当一个元素包含在另一个元素中时(如果没有内边距或边框把外边距分隔开),它们的上和/或下外边距也会发生合并。
    • 空元素,它有外边距,但是没有边框或填充,则上下边距会发生合并

    解决方法

    • 给外层元素加内边距边框
    • 去掉内层元素的mqrgin改为直接设置外层元素padding
    2.事件冒泡
      <div class="root">
        <div class="father">
          <div class="child"></div>
        </div>
      </div>
      let root = document.getElementsByClassName('root')[0];
      let father = document.getElementsByClassName('father')[0];
      let child = document.getElementsByClassName('child')[0];
    
      root.onclick = function () {
        console.log("root");
      };
      father.onclick = function () {
        console.log("father");
      };
      child.onclick = function () {
        console.log("child");
      };
     

    点击最内层div时控制台依次显示:child、father、root。按照DOM层次结构像至低向上直到顶端,这就是事件冒泡。

    3. 阻止冒泡

    实现弹窗,然后点击空其他任意地方隐藏弹窗

      <!--html-->
      <div class="father">
        <div class="child"></div>
      </div>
    /*javascript*/
      let father = document.getElementsByClassName('root')[0];
      let child = document.getElementsByClassName('child')[0];
    
      father.onclick = function () {
        console.log("father");
      };
      child.onclick = function (e) {
        let ev = e||window.event;
        ev.stopPropagation();
      };
    <!--vue-->
      <div class="father">
        <div class="child" @click.stop=""></div>
      </div>

    二、根据现有项目学习编码规范以及项目结构并尝试编写

    *模仿网易云音乐播放器页面
    地址:https://gitee.com/zhangweiqin...

    代码规范
    1. tab = 2Space
    2. 移动端使用rem布局
    3. 生命周期排列顺序:name、props、components、data、create、mounted、computed、watch、beforedestroy、methods
    4. 自定义组件使用小驼峰命名
    目录结构

    图片描述

    • 根组件App.vue
    • 页面组件:src/view
    • 页面模块:src/view/modules
    • 路由:src/router
    • 通用组件:src/components
    rem自适应布局

    先了解:rem、em、px

    • px:相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
    • em:是相对长度单位,是所在元素的字体大小,没设置则一层层往上直获取字体大小至浏览器默认字体大小。
    • rem:相对长度大小,相对于根元素字体大小

    因为rem大小只和根元素字体大小有关所以只要根据设备设置不同的根元素大小,然后以相同的rem作单位得到的实际大小是不同的,实现自适应。

    document.documentElement.style.fontSize = document.documentElement/375*20 + 'px';
    /*
    这样 如果在宽度为375(iphone6/7/8)的环境下1rem = 20px.
    也可以选择在宽度为360(大部分1080p屏幕)的环境下开发则相应的除以360,
    根据设计稿的宽度不同选择方便计算的方式。
    */
    项目路由

    App.vue下目前只有主页面以及歌单页面,主界面下两个子路由:我的音乐、发现,两个组件:个人设置页面、播放控制条。

    {path: "/", redirect: "/index/myMusic"}, //重定向
      {//主界面
        path: '/index',
        name: 'index',
        component: index,
        children: [
          {//我的音乐
            path: '/index/myMusic',
            name: 'myMusic',
            component: myMusic
          }, {//发现
            path: '/index/findMusic',
            name: 'findMusic',
            component: findMusic
          }
        ]
      },
      {//歌单页面
        path: '/songList',
        name: 'songList',
        component: songList
      }

    路由的使用以及传参:(两种方式)

    {
      path: 'helloWorld',
      name: helloWorld,
      component: ···
    }
    this.$router.push({path: '/helloWorld',query: {msg: 'hello'}});
    <router-link :to="{ name: 'helloWorld', query: { msg: 'hello!' }}"></router-link>
    
    this.$router.push({ name: 'helloWorld', params: { msg: 'hello'}});
     <router-link :to="{ name: 'helloWorld', params: { msg: 'hello' }}"></router-link>
    
    console.log(this.$route.query);  //{msg:hello},不同的是query传递参数会被附加到url地址上
    console.log(this.$route.params); //{msg:hello}
    组件的使用以及组件数据传递
    • 引入组件,两种加载方式
      1. import userSetting from '@/view/modules/userSetting.vue';
      2. const userSetting = resolve => require(['@/view/modules/userSetting.vue'],resolve);  //懒加载

    异步加载,优点:最大化的实现随用随载,减少首页加载延迟;缺点:可能会造成网页显示过慢且渲染参差不齐的问题

    • 组件注册
        //单文件组件
        components: {
          userSetting
        },
    • 数据传递

    父组件->子组件:

      <!--发送-->
      <userSetting :data="'msg from father'">
      </userSetting>
      //接收
      export default {
        name: "user-setting",
        props:['data']
      }

    子组件->父组件:

      <!--发送-->
      <div class="set-item" 
           @click="$emit('msgFromSon','msg from son')">
           高级设置
      </div>
      <!--接收-->
      <userSetting
        v-show="setting"
        @msgFromSon="recive">
      </userSetting>
      methods: {
        recive(msg) {
          console.log(msg);  //msg from son
        }  
      }
    Vue.extend()、$mount()

    Vue.extend(): 使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。

      let alertOptions = {
        data:function(){
          return {
            title: title,
            text: text,
          }
        },
        methods:{
          close() {
            resolve('ok');
            dialogClose(vm);
          }
        },
        template: '<alert @close="close" :title="this.title" :text="this.text"></alert>',
          components: {alert}
      }
    
      let creator = Vue.extend(alertOptions)

    vm.$mount():手动地挂载一个未挂载的实例。

      //挂在到#app下
      new creator().$mount('#app')
      
      //在文档之外渲染并且随后挂载
      vm = new creator().$mount()
      dialogContainer.appendChild(vm.$el)

    不快乐的程序员
    393 声望13 粉丝