[物語を忘れました]°のブログへようこそ

Vue 学习笔记 [Part 1]

作者:故事我忘了
个人微信公众号:程序猿的月光宝盒

最近项目上需要用到Vue,又重新学习了一遍.期望10天左右完全掌握并能用于生产吧.

好记性不如烂笔头

一. 邂逅Vuejs

1.1. 认识Vuejs

  • 为什么学习Vuejs

    • 可能你的公司正要将原有的项目使用Vue进行重构。
    • 可能是你的公司新项目决定使用Vue的技术栈。
    • 如果你现在正在换工作,你会发现招聘前端或者后端的需求中,10个有8个都对Vue有或多或少的要求。
    • 作为终生学习者我们知道Vuejs目前非常火,可以说是前端必备的一个技能。
  • Vue的读音

    • (读音 /vjuː/,类似于 view)
  • Vue的渐进式

    • 渐进式

      渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验。

      或者如果你希望将更多的业务逻辑使用Vue实现,那么将会用到Vue的核心库以及其生态系统。

      比如Core+Vue-router+Vuex,也可以满足你各种各样的需求。

  • Vue的特点

    • 解耦视图和数据
    • 可复用的组件
    • 前端路由技术
    • 状态管理
    • 虚拟DOM

1.2. 安装Vue

  • CDN引入

    • 你可以选择引入开发环境版本还是生产环境版本

      <!-- 开发环境版本,包含了有帮助的命令行警告 --> 
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      <!-- 生产环境版本,优化了尺寸和速度 -->
      <script src="https://cdn.jsdelivr.net/npm/vue"></script>
      
  • 下载引入

    开发环境 https://vuejs.org/js/vue.js 
    生产环境 https://vuejs.org/js/vue.min.js
    
  • npm安装

    • 后续通过webpackCLI的使用,项目上大多数用到

1.3. Vue的初体验

  • Hello Vuejs

    • mustache 语法-> 体验vue响应式

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>Vue初体験</title>
        <script src="../js/vue.js"></script>
      </head>
      <body>
      <div id="vm">
        <span>{{message}}</span>
      </div>
      </body>
      <script>
        /*
        * let(变量)/const(常量)
        *   此编程范式为:
        *     声明式编程
        *
        * 传统js做法
        * 元素js的做法(编程范式: 命令式编程)
        *   1.创建div元素,设置id属性
        *
        *   2.定义一个变量叫message
        *
        *   3.将message变量放在前面的div元素中显示
        *
        *   4.修改message的数据: 今天天气不错!
        *
        * 5.将修改后的数据再次替换到div元素
        * 是一步一步做的,故编程范式为:
        *   命令式编程
        * */
        const vm = new Vue({
          el: "#vm",//用户挂载要管理的id为vm的元素
          data: {//定义数据
            message: "初めまして、Vue さん。僕は金聖聰と申します"
          }
        })
      </script>
      </html>
      

      以上代码做了那些事?

      1. JavaScript代码中,创建了一个Vue对象。
      2. 创建Vue对象的时候,传入了一些options:{}
      3. {}中包含了el属性:该属性决定了这个Vue对象挂载到哪一个元素上,很明显,我们这里是挂载到了id为app的元素上
      4. {}中包含了data属性:该属性中通常会存储一些数据
      5. data中的数据可以是我们直接定义出来的,比如像上面这样。也可能是来自网络,从服务器加载的。

      浏览器执行代码的流程:

      1. 执行到9~11行代码显然出对应的HTML
      2. 执行第33行代码创建Vue实例,并且对原HTML进行解析和修改。并且,目前的代码是可以做到响应式的。
  • Vue列表展示

    • v-for

    • 后面给数组追加元素的时候, 新的元素也可以在界面中渲染出来

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>列表展示</title>
        <script src="../js/vue.js"></script>
      </head>
      <body>
      <div id="vm">
        <ul>
          <li v-for="item in movieList">{{item}}</li>
        </ul>
      </div>
      </body>
      <script>
        const vm = new Vue({
          el: "#vm",
          data: {
            movieList: ["大话西游", "情癫大圣", "大圣娶亲"]
          }
        })
      </script>
      </html>
      

      代码做了那些事?

      1. HTML代码中,使用v-for指令,该指令后面会详细讲解,这里先学会使用。
      2. 再也不需要在JavaScript代码中完成DOM的拼接相关操作了,更重要的是,它还是响应式的。
  • Vue计数器小案例

    • 事件监听: click -> methods

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>计数器</title>
        <script src="../js/vue.js"></script>
      </head>
      <body>
      <div id="vm">
        <h2>当前计数{{count}}</h2>
        <!--@click是v-on:click的语法糖-->
        <button @click="add">+</button>
        <button @click="sub">-</button>
      </div>
      </body>
      <script>
        const vm = new Vue({
          el: '#vm',//接管对应区域的管理
          data: {
            count: 0
          },
          methods: {//在vue对象中定义方法
            add: function () {
              this.count++;
            },
            sub: function () {
              this.count--;
            }
          }
        })
      </script>
      </html>
      

      新的指令和属性

      新的属性:``methods``,该属性用于在Vue对象中定义方法。
      
      新的指令:``@click``, 该指令用于监听某个元素的点击事件,并且需要指定当发生点击时,执行的方法(方法通常是methods中定义的方法)
      

1.4. Vue中的MVVM

图片

View层

视图层

在前端开发中,通常就是DOM层。

主要的作用:	给用户展示各种信息。

Model层

数据层

数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。

在计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。

ViewModel层

视图模型层

视图模型层是View和Model沟通的桥梁。

一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中

另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
1.4.5 计数器的MVVM

上面的计数器中就有严格的MVVM思想

View

	依然是DOM

Model

	就是抽离出来的obj

ViewModel

	就是创建的Vue对象实例

图片

它们之间如何工作呢?

首先ViewModel通过Data Binding让obj中的数据实时的在DOM中显示。

其次ViewModel通过DOM Listener来监听DOM事件,并且通过methods中的操作,来改变obj中的数据。

1.5. 创建Vue时, options可以放那些东西

  • el:
    • 类型:string | HTMLElement
    • 作用:决定之后Vue实例会管理哪一个DOM。
  • data:
    • 类型:Object | Function (组件当中data必须是一个函数)
    • 作用:Vue实例对应的数据对象。
  • methods:
    • 类型:
    • 作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用。
  • 生命周期函数

图片

图片

二.插值语法

  • mustache语法

    • 可以通过Mustache语法(也就是双大括号)。

    • Mustache: 胡子/胡须.

      图片

  • v-once

    • 该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)

    • 该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变。

      图片

  • v-html

    • 某些情况下,我们从服务器请求到的数据本身就是一个HTML代码

    • 如果我们直接通过{{}}来输出,会将HTML代码也一起输出。

    • 但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。

      Ø该指令后面往往会跟上一个string类型

      Ø会将string的html解析出来并且进行渲染

      图片

  • v-text

    • 和Mustache比较相似:都是用于将数据显示在界面中

    • v-text通常情况下,接受一个string类型

      图片

  • v-pre:

    • 跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。

    • 第一个p元素中的内容会被编译解析出来对应的内容

      第二个p元素中会直接显示{{message}}

      图片

  • v-cloak: 斗篷

    • 在某些情况下,比如网络原因,浏览器可能会直接显然出未编译的Mustache标签。这时候就用他来影藏.但是一般后面也不这么用

      图片

三. v-bind

作用动态绑定属性

缩写(语法糖):

预期any (with argument) | Object (without argument)

参数attrOrProp (optional)

3.1. v-bind绑定基本属性

  • v-bind:src

  • :href

    图片

3.2. v-bind动态绑定class

  • 对象语法:

    • 对象语法的含义是:class后面跟的是一个对象。

      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>Title</title>
      
        <style>
          .active {
            color: red;
          }
        </style>
      </head>
      <body>
      
      <div id="app">
        <!--<h2 class="active">{{message}}</h2>-->
        <!--<h2 :class="active">{{message}}</h2>-->
      
        <!--<h2 v-bind:class="{key1: value1, key2: value2}">{{message}}</h2>-->
        <!--<h2 v-bind:class="{类名1: true, 类名2: boolean}">{{message}}</h2>-->
        <h2 class="title" v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
        <h2 class="title" v-bind:class="getClasses()">{{message}}</h2>
        <button v-on:click="btnClick">你倒是变啊</button>
      </div>
      
      <script src="../js/vue.js"></script>
      <script>
        const app = new Vue({
          el: '#app',
          data: {
            message: '我变',
            isActive: true,
            isLine: true
          },
          methods: {
            btnClick: function () {
              this.isActive = !this.isActive
            },
            getClasses: function () {
              return {active: this.isActive, line: this.isLine}
            }
          }
        })
      </script>
      
      </body>
      </html>
      
  • 数组语法:

    用法一:直接通过[]绑定一个类
    <h2 :class="['active']">Hello World</h2>
    
    用法二:也可以传入多个值
    <h2 :class=“[‘active’, 'line']">Hello World</h2>
    
    用法三:和普通的类同时存在,并不冲突
    注:会有title/active/line三个类
    <h2 class="title" :class=“[‘active’, 'line']">Hello World</h2>
    
    用法四:如果过于复杂,可以放在一个methods或者computed中
    注:classes是一个计算属性
    <h2 class="title" :class="classes">Hello World</h2>
    
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
    </head>
    <body>
    
    <div id="app">
      <h2 class="title" :class="[active, line]">{{message}}</h2>
      <h2 class="title" :class="getClasses()">{{message}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: '你好',
          active: 'aaa',
          line: 'bbb'
        },
        methods: {
          getClasses: function () {
            return [this.active, this.line]
          }
        }
      })
    </script>
    
    </body>
    </html>
    

3.3. v-bind动态绑定style

绑定一些CSS内联样式。

	在写CSS属性名的时候,比如font-size

		可以使用驼峰式 (camelCase) fontSize 

		或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’
  • 对象语法:

    :style="{color: currentColor, fontSize: fontSize + 'px'}"
    style后面跟的是一个对象类型
    对象的key是CSS属性名称
    对象的value是具体赋的值,值可以来自于data中的属性
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <style>
        .title {
          font-size: 50px;
          color: red;
        }
      </style>
    </head>
    <body>
    
    <div id="app">
      <!--<h2 :style="{key(属性名): value(属性值)}">{{message}}</h2>-->
    
      <!--'50px'必须加上单引号, 否则是当做一个变量去解析-->
      <!--<h2 :style="{fontSize: '50px'}">{{message}}</h2>-->
    
      <!--finalSize当成一个变量使用-->
      <!--<h2 :style="{fontSize: finalSize}">{{message}}</h2>-->
      <h2 :style="{fontSize: finalSize + 'px', backgroundColor: finalColor}">{{message}}</h2>
      <h2 :style="getStyles()">{{message}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          message: '你好啊',
          finalSize: 100,
          finalColor: 'red',
        },
        methods: {
          getStyles: function () {
            return {fontSize: this.finalSize + 'px', backgroundColor: this.finalColor}
          }
        }
      })
    </script>
    
    </body>
    </html>
    
  • 数组语法:

    <div v-bind:style="[baseStyles, overridingStyles]"></div>
    style后面跟的是一个数组类型
    多个值以 , 分割即可
    
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h2 :style="[baseStyle, baseStyle1]">{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      baseStyle: {backgroundColor: 'red'},
      baseStyle1: {fontSize: '100px'},
    }
  })
</script>

</body>
</html>

四. 计算属性

什么是计算属性

在模板中可以直接通过插值语法显示一些data中的数据。

但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

	比如我们有firstName和lastName两个变量,我们需要显示完整的名称。

	但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}

故,我们可以将上面的代码换成计算属性:

然后,我们发现计算属性是写在实例的computed选项中的。

  • 案例一: firstName+lastName

    图片

  • 案例二: books -> price

    这个是更加复杂的操作

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
    </head>
    <body>
    
    <div id="app">
      <h2>总价格: {{totalPrice}}</h2>
    </div>
    
    <script src="../js/vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        data: {
          books: [
            {id: 110, name: 'Java从入门到入坟', price: 119},
            {id: 111, name: 'Oracle从入库到删库', price: 105},
            {id: 112, name: 'Mysql从入门到跑路', price: 98},
            {id: 113, name: 'Python从摸蛇到摸鱼', price: 87},
          ]
        },
        computed: {
          totalPrice: function () {
            let result = 0;
    
            //方式1
            // for (let i=0; i < this.books.length; i++) {
            //   result += this.books[i].price
            // }
    
            //方式2
            // for (let i in this.books) {
            //   result += this.books[i].price
            // }
    
            //方式3
            for (let book of this.books) {
              result += book.price
            }
    
            return result;
    
          }
        }
      })
    </script>
    
    </body>
    </html>
    

五. 练习

需求:一个列表 默认第一行红色,之后点某行某行变红

用到v-for="(m,index) in movieList"

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>鼠标点击变色</title>
  <style>
    .Red {
      color: red;
    }
  </style>
</head>
<body>
<div id="vm">
  <ul>
    <li v-for="(m,index) in movieList" @click="changeColor(index)"
        :class="{Red: index === currentIndex}">
      {{m}}
    </li>
  </ul>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
  const vm = new Vue({
    el:"#vm",
    data:{
      movieList:["西游记","东成西就","大圣娶亲","大话西游"],
      // 初始化0,表示默认选中第一个li
      currentIndex: 0
    },
    methods:{
      // 传的index 就是当前的li的index
      changeColor(index) {
        //改变 currentIndex 为 传入的值
        this.currentIndex =index
      }
    }
  })
</script>
</html>
posted @ 2020-05-12 20:24  故事我忘了°  阅读(439)  评论(0编辑  收藏  举报