CMoney软件工程师战斗营_Vue框架_Week 15

欧拉~
本周结束了分领域
虽然每周都为了Web的演示以及庞大的作业量追着跑
但是结束并没有感到松一口气
因为接下来迎接我的就是



期末专题拉!
真的同时被 学习前端技术 & 准备期末专题 搞得焦头烂额T_T

本周最後一次的前端内容是教有名的框架:Vue
以下提供不专业笔记:

运作方式

  • index.html:所有的内容都会从 src 中打包注入到 id 为 app 的 div 下方。
  • main.js:所有 vue.js 的进入点,也就是注入 index.html 的主档案。主要是 import App.vue 作为 component 使用。
  • App.vue:专案的主档。规划共用与非共用区域。
    • 里面有三种档案类型:template掌管HTML, Script掌管JS, Style掌管CSS

元件名称大写开头

import引用(印用某一套件,但还不能使用)→components注册→template使用(定义成标签)

CSS有个属性→帮你产生乱码名字,就不会让className与别人重复

Vue语法

字串模板

  • {{与资料绑定的变数名称}}

  • v-text="与资料绑定的变数名称"

  • v-html="与资料绑定的变数名称"

    • ex

      <h1>{{ msg }}<h1>
      <p v-text="msg"></p>//=elem.textContent="...";
      <p v-html="htmlcode"></p>//=elem.innerHTML=`...`;
      
  • 属性绑定

    • v-bind:src="与资料绑定的变数名称"

    • :src="与资料绑定的变数名称"

    • ex

      <img v-bind:src="src" v-bind:alt="alt" v-bind:class="className" />
      <img :src="item.src" :alt="item.alt" :class="item.className" />
      
          return {
            msg: "Hello Away",
            htmlCode: `<a href="https://www.cmoney.tw" style="font-size: 1.5em">Link</a>`,
            src: "https://www.wdh2o.idv.tw/wp-content/uploads/2012/12/paper.jpg",
            alt: "Illustrator – 摺纸效果",
            className: "img-resp",
            item: {
              src:
                "https://www.wdh2o.idv.tw/wp-content/uploads/2015/08/ingress_xmp.jpg",
              alt: "Ingress Weapon – Xmp Burster",
              className: "img-nl",
            },
      
  • v-if, v-else, v-show, v-else-if

    v-if 与 v-show 所呈现的视觉化效果是相同的,差异在於:

    • v-show:是利用 CSS 的 inline style 来进行显示或隐藏。
    • v-if:连 DOM 都不会在网页中。

    一次性的显示或隐藏,建议使用 v-if;若是让使用者切换的显示或隐藏,建议使用 v-show。

    • ex

      <p v-if="!isMale">男</p>
            <p v-else>女</p>
            <p v-show="isShow">//如果false还是会渲染出来display:none
              v-show 是利用 CSS 的 inline style 来进行显示或隐藏。
            </p>
      
  • class与style绑定/样式控制

    • class

      <p :class="{'text-danger': isActive}">文字内容</p>
      
            <div class="box" :class="classList">
              <div class="box__item"></div>
              <div class="box__item"></div>
              <div class="box__item"></div>
            </div>
      return{
      isActive: true,
      classList: {
      	        "box-stack": true,----表示垂直样式的class是true
              "box-matrix": false,
            },
      }
      
  • 列表渲染

    • v-for

    • ex

      <ul>
           <li v-for="(item, index) in listData" :key="index">{{ item }}</li>
      </ul>
      //(listData: ["html", "rwd", "javascript", "vue", "sass"],)->会藉由v-for逐一列出item
            <div>
              <img
                v-for="(item, index) in ad.picItems"
                :src="item"
                :key="index"
                alt=""
              />
      			</div>
      //picItems: [
                "https://www.wdh2o.idv.tw/wp-content/uploads/2015/12/ingress_guardian.jpg",
                "https://www.wdh2o.idv.tw/wp-content/uploads/2015/08/ingress_xmp.jpg",
                "https://www.wdh2o.idv.tw/wp-content/uploads/2015/08/ingress_intro.jpg",
                "https://www.wdh2o.idv.tw/wp-content/uploads/2013/01/html5.jpg",
                "https://www.wdh2o.idv.tw/wp-content/uploads/2012/12/spry-menu.jpg",
              ],
      
    • 不要同时使用 v-for 与 v-if

      如果这两项在同一个节点上,v-for 的优先权会比 v-if 更高,也就是 v-if 将会重复执行在每个 v-for 之中。

      • ex

        <ul v-if="listData">
          <li v-for="item in listData"> {{ item }} </li>
        </ul>
        <p v-else> 目前没有资料 </p>
        
  • computed(在vue里面是个计算的属性)

    • ex:筛选出40岁以下的员工

      <ul v-if="computedFilter && computedFilter.length">
              <li v-for="(item, index) in computedFilter" :key="index">
                {{ index }} - {{ item.name }},年龄 {{ item.age }} 岁,专长 {{ item.skill }}
              </li>
            </ul>
      
      computed: {
          computedFilter() {
            return this.employeeData.filter(item => item.age < 40);
          },
      employeeData: [
              { name: "Away", age: 40, skill: "RWD" },
              { name: "Zero", age: 30, skill: "APP" },
              { name: "Jamei", age: 20, skill: "Data Base" },
              { name: "Rick", age: 10, skill: "F2E" },
            ],
      

生命周期

beforeCreate(在元件创造之前)→created(资料在此挂载)→beforeMount(元件建立之前,只有元素外层,像空的div)→mounted(可控制DOM,div里面内容出现)→资料开始有所变动:beforeUpdate(资料变了,元素还未改变)→updated→beforeDestroy→destroyed元件失效死亡

  • 通常切分页元件会自动死亡

axios

  • npm install --save axios vue-axios
this.axios.get(api).then((response) => {
  console.log(response.data)
})
--------------or------------------
this.$http.get(api).then((response) => {
  console.log(response.data)
})
post必须是物件
这边不需要手动转json
  • ex

    export default {
      name: 'App',
      data(){
        return {
          data: [],
        };
      },
      created() {
        this.$http.get('./static/data.json').then(res => {
          this.data = res.data;
        });
      },
    }
    

元件

记得要记得要运行就要:引入→注册→挂载到画面

  • 元件化:将html抽出去

  • 元件包装:一个vue档里面包其他vue档

  • 向内传递

    利用props:[ ]阵列

    • 静态传递:自己在挂载地方更改

    • ex

      //在Pic.vue里
      <template>
        <figure>
          <img :src="imgSrc">
          <figcaption>{{ imgCaption }}</figcaption>
        </figure>
      </template>
      
      <script>
      export default {
        props:['imgSrc', 'imgCaption'],
      }
      </script>
      //在App.vue里
      <h2>静态传递</h2>
          <Pic
            img-src="https://www.apple.com/v/mac/home/at/images/overview/compare/macbook_pro_16__x90efpvdutu6_large_2x.jpg"
            img-caption="静态传递的文字内容"
          />
      
    • 动态传递:利用资料传递

    • ex

      
      //在App.vue里的HTML
      <h2>动态传递</h2>
          <Pic
            :img-src="src"
            :img-caption="title"
          />
      //在App.vue里的Script
      return {
            src:
              'https://www.apple.com/v/mac/home/at/images/overview/compare/macbook_air__bfz9o93hnyuq_large_2x.jpg',
            title: '动态传递的文字内容',
          };
        },
      
  • 向外传递

    利用$emit

    • ex

      //在Post元件里
      <button type="button" @click="$emit('updateSize')">放大文字</button>
      //在App.vue的template里
      <Post
            :style="{ fontSize: `${textSize1}em` }"
            @updateSize="textSize1 += .1"
          />
      

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/484d74e5-1836-4c69-bfae-96d731e91e42/_2021-06-04_10.31.33.png

事件

Click

  • ex

    在App.vue里

    <template>
      <div id="app">
        <Click />
        <ClickCounter />
        <ClickToggle />
        <ClickModifier />
        <KeyUp />
      </div>
    </template>
    
    <script>
    import Click from "./components/Click
    export default {
      name: "App",
      components: {
        Click,
      },
    };
    </script>
    

    在Click.vue里

    <template>
      <div>
        <img
          :src="src"
          :alt="title"
          v-on:click="atClick"----> v-on: 可改成@
        >
      </div>
    </template>
    
    <script>
    export default {
      name: "BaseClick",
      data() {
        return {
          title: "HTML5",
          url: "https://www.wdh2o.idv.tw",
          src: "https://www.wdh2o.idv.tw/images/html5/html5.jpg",
        };
      },
      methods: {
        atClick(e) {
          alert(this.title);
          open(this.url, '_blank');
        },
      },
    };
    </script>
    
  • a标签按的时候如果没有网址会重整画面,我已改他修饰符号.preven取消预设

ClickModifier(修饰符)

  • normal:冒泡,从内向外
  • capture:从外层进来(与冒泡相反)
  • stop:停止传播
  • self:只会出现自己
  • once:只能使用一次,冒泡出来的东西也不能再使用

KeyUp

  • ex

    在KeyUp.vue里
    <template>
      <div>
        <h1 class="text-center">Vue - KeyUp</h1>
        <h2>enter</h2>
        <div>
          <input type="text" @keyup.enter="atKeyUp('enter')" />
        </div>
    
        <h2>space</h2>
        <div>
          <input type="text" @keyup.space="atKeyUp('space')" />
        </div>
    
        <h2>ctrl + enter</h2>
        <div>
          <input type="text" @keyup.ctrl.enter="atKeyUp('ctrl + enter')" />
        </div>
      </div>
    </template>
    
    <script>
    export default {
      methods: {
        atKeyUp(m) {
          console.log(m);
        },
      },
    };
    </script>
    

    同场加应本周演示幸运抽到的题目:

computed 与 methods 的差异

Computed

vue的计算属性

介绍

  • 在 Vue 中 computed 是经常会使用到的属性,因为在 Vue 中透过 computed 会 cache 住没有改变的资料,因此正确且适当的使用 computed 将可以减少资料重新运算的次数,让网页的效能提升。

基本概念

  • computed 的属性可以被视为像是 data 一样,可以读取和设值分成 getter(读取) 和 setter(设值),在没有写 setter 的情况下,computed 预设只有 getter ,也就是只能读取,不能改变设值。
  • 特别注意:在getter中需要搭配使用return把值返回出来

基本范例:

  • 预设只有 getter 的 computed

    new Vue({
        computed: {
            computedData: function () {
                return // ...
            }
        }
    })
    
  • 有 setter 和 getter 的 computed

    new Vue({
        computed: {
            computedData: {
                get: function () {
                    return // ...
                },
                set: function () {
                    // ...
                }
            }
        }
    })
    

重头戏

  • 翻转字

    <div id="example">
      {{ message.split('').reverse().join('') }}
    </div>
    

→当我们遇到计算过於复杂还会重复使用时候就使用computed

  • 改成computed
<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // a computed getter
    reversedMessage: function () {
      // `this` points to the vm instance
      return this.message.split('').reverse().join('')
    }
  }
})

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c6277c68-d8e8-4a8a-a83e-29d0ae3fefa5/_2021-06-02_11.05.01.png

注意

  • 不能重复宣告

  • 如果使用箭头函式的话, this 将指向 window ,而非 Vue

  • 只要 computed property 原始依赖响应的资料 没有更动,Vue 并不会重新求取 computed property,而是访问其 缓存结果

    computed: {
      now: function () {
        return Date.now()
      }
    }
    //Date.now() is not a reactive dependency
    

    computed是依照资料来源所连动,Date未经Vue处理过

Computed VS methods

  • 阅读性

    computed > methods

    在表达上computed就是资料型态,显示上比较容易辨别

  • Catch

    computed 有Catch!

    假设computed的原始资料来源没变动,他就只会执行一次,然後把内容catch住,你在跟他要的时候他会直接拿出来回应你。

总结

看完以上的范例,来做个小总结,computed 优点在於由於缓存的特性,一旦使用的大量的计算,在既有响应依赖资料没有更动的前提下,computed 不会重新计算求值,减少性能上的开销;

反之,若是有需要随时更新、不希望缓存的情境,则可以使用 method 替代。


以上就是我本周分领域的笔记~


<<:  伸缩自如的Flask [day 23] GCP app engine (介绍)

>>:  [PoEAA] Domain Logic Pattern - Table Module

Day20_CSS语法3

ID选择器(ID selector) : 符合指定id的HTML元素做为要套用样式规则的对象,命名格...

[Day11] 排版的小孩子才做选择 ~ Grid 跟 Flex 我全都要!

本日文章没有前言XD 但没有前言真的有点怪怪的,总之本日文章想要分享过去我在使用 Grid 跟 Fl...

[Day12] WebDriver安装教学aka自动发文器第二集

在上篇有提到用 Selenium + WebDriver 就可以让程序帮你自动发文, 但有试过的朋友...

(33)试着学 Hexo-番外篇之更新 NexT 主题

前言 接下来这一篇将会介绍如何更新 NexT 主题与介绍 Hexo5 之後的 NexT 之後有什麽样...

Day 28 | Circular timer animation

今天要来分享我看 Youtube 影片做出来的 timer, 照惯例先放影片连结, 用他里面提到的观...