Vue.js--基础

Vue
1、基本概念
  • 渐进式框架
      渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验
  • 特点
    • 解耦视图和数据
    • 可复用的组件
    • 前端路由技术
    • 状态管理
    • 虚拟DOM
2、安装Vue.js

 1. 直接CDN引入

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

  2. 下载后项目中引入js文件
  3. 使用npm安装

3、 初体验
<div id="app">
        <h2>{{message}}</h2>
        <ul>
                <li v-for="item in movies">{{item}}</li>
        </ul>

    <h2>{{count}}</h2>
    <button type="button" @click="add">+</button>
    <button type="button"  @click="sub">-</button>
    </div>
    //数据和视图分离  引入vue的js文件
    <script src="../js/vue.js"></script>
        <script>
            //let(ES6定义变量)/const(常量)
            let app=new Vue({
                el:'#app',//用于挂载要管理的元素,id的方式就用#
                data:{//定义数据
                    message:'Hello Vue',
                    // 数组
                    movies:['Hello','World','VUE']
                },
                methods:{
                    add:function(){
                        console.log('add执行');
                        this.count++;
                    },
                    sub:function(){
                        console.log('sub执行');
                        this.count--;
                        
                    }
                }
            });
    </script>
  • 演示
    演示
4、什么是MVVM
  • View层
    视图层
    在我们前端开发中,通常就是DOM层。
    主要的作用是给用户展示各种信息。
  • Model层
    数据层
    数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
    在我们计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。
  • VueModel层
    视图模型层
    视图模型层是View和Model沟通的桥梁。
    一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中
    另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
    官网模型
6、Vue实例的Options
  • el:
    类型:string | HTMLElement
    作用:决定之后Vue实例会管理哪一个DOM
  • data:
    类型:Object | Function (组件当中data必须是一个函数)
    作用:Vue实例对应的数据对象
  • methods:
    类型:{ [key: string]: Function }
    作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用
7、Vue的生命周期

视频老师整理的图片

  • 官方解释
    官方
8、语法

8.1、插入操作
8.1.1、Mustache

  • 就是两个{{}},并且可以在里面写入简单的表达式
 <h2>{{firstName + lastName}}</h2>

8.1.2、v-once

  • 有时候我们想一些界面数据不跟随其他的进行改变,该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变。
<h2 v-once>{{message}}</h2>

演示
8.1.3、v-html

  • 某些情况下,我们从服务器请求到的数据本身就是一个HTML代码
    • 如果我们直接通过{{}}来输出,会将HTML代码也一起输出
    • 但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容
 <h2 v-html="url"></h2>
//则显示的时候是相当于正常使用a标签显示一样
url: '<a href="http://www.baidu.com">百度一下</a>'

8.1.4、v-text

  • v-text作用和Mustache比较相似:都是用于将数据显示在界面中
<h2 v-text="message"></h2>

8.1.5、v-pre

  • v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法
<h2 v-pre>{{message}}</h2>
  • 直接显示出{{message}}

8.1.6、v-cloak

  • 在某些情况下,我们浏览器可能会直接显然出未编译的Mustache标签
  • 防止闪烁…防止htlml先显示{{message}}之类的
<div id="app" v-cloak>
  <h2>{{message}}</h2>
</div>

8.2、绑定属性
8.2.1、v-bind

  • v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值
    <div id="app">
            <a v-bind:href="ahref">百度</a>
    </div>      
    <script>    
        let app=new Vue({
            el:'#app',//用于挂载要管理的元素
            data:{//定义数据
                ahref:'http://www.baidu.com'
            }   
        });
    </script>
//简写 : <a :href="ahref">xxx</a>

8.2.2、v-bind绑定class-对象语法

  • 直接通过{}绑定一个类
<h2 :class="{'active': isActive}">Hello World</h2>
  • 也可以通过判断,传入多个值
<h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2>
  • 和普通的类同时存在,并不冲突
    注:如果isActive和isLine都为true,那么会有title/active/line三个类
<h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
  • 如果过于复杂,可以放在一个methods或者computed中
    注:classes是一个计算属性
<h2 class="title" :class="classes">Hello World</h2>

8.2.3、v-bind绑定class-数组语法

  • 直接通过{}绑定一个类
<h2 :class="['active']">Hello World</h2>
  • 也可以通过判断,传入多个值
<h2 :class=“[‘active’, 'line']">Hello World</h2>
  • 和普通的类同时存在,并不冲突
    注:如果isActive和isLine都为true,那么会有title/active/line三个类
<h2 class="title" :class=“[‘active’, 'line']">Hello World</h2>
  • 如果过于复杂,可以放在一个methods或者computed中
    注:classes是一个计算属性
<h2 class="title" :class="classes">Hello World</h2>

8.2.4、v-bind绑定style

  • 在写CSS属性名的时候,比如font-size
  • 我们可以使用驼峰式 (camelCase) fontSize
  • 或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’
    8.2.5、v-bind绑定style–对象语法
:style="{color: currentColor, fontSize: fontSize + 'px'}"

style后面跟的是一个对象类型

  • 对象的key是CSS属性名称
  • 对象的value是具体赋的值,值可以来自于data中的属性

8.2.5、v-bind绑定style–数组语法

<div v-bind:style="[baseStyles, overridingStyles]"></div>

style后面跟的是一个数组类型

  • 多个值以,分割即可

8.3、计算属性

  • 我们知道,在模板中可以直接通过插值语法显示一些data中的数据。
  • 但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示
    比如我们有firstName和lastName两个变量,我们需要显示完整的名称。
  • 但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}},重复的东西太多这在开发当中是非常忌讳的
<div id="app">
  <h2>{{firstName + ' ' + lastName}}</h2>
  <h2>{{firstName}} {{lastName}}</h2>
  <h2>{{getFullName()}}</h2>
  <h2>{{fullName}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      firstName: 'Lebron',
      lastName: 'James'
    },
    // computed: 计算属性()
    computed: {
      fullName: function () {
        return this.firstName + ' ' + this.lastName
      }
      //上面的可以简写成如下
      fullName() {
        return this.firstName + ' ' + this.lastName
      }
    },
    //同样上述的可以写成方法进行实现,记住调用的时候有些不一样
    methods: {
      getFullName() {
        return this.firstName + ' ' + this.lastName
      }
    }
  })
</script>
  • Tips

计算属性是基于它们的依赖进行缓存的。只有依赖值改变时,计算属性才重新求值。依赖不变时,多次访问计算属性,会直接返回之前的计算结果,不必再次执行函数。
而每次访问调用方法时,它都会再次执行函数。即使当前页面已经调用过一次了,新调用时还会重新计算

计算属性只有在改变的时候才会再次执行对应函数,方法则每次都会再次执行函数

计算属性会进行缓存,如果多次使用时,计算属性只会调用一次(内容没修改的前提下)
8.3.1、复杂操作
图片1.png
8.3.2、计算属性的setter、getter

// 计算属性一般是没有set方法, 只读属性.
      fullName: {
        set: function(newValue) {
          // console.log('-----', newValue);
          const names = newValue.split(' ');
          this.firstName = names[0];
          this.lastName = names[1];
        },
        get: function () {
          return this.firstName + ' ' + this.lastName
        }
      }
//一般还是直接简写成上面的那种形式
  • 使用set的情况:如果我在控制台修改:fuuName=“xxx xxx”,默认会调用set方法。

8.4、事件监听

  • 在前端开发中,我们需要经常和用于交互。
    • 这个时候,我们就必须监听用户发生的时间,比如点击、拖拽、键盘事件等等

8.4.1、v-on的使用

  • 绑定事件监听器
  • 缩写:@
<button v-on:click="increment">+</button>
//简写
<button @click="decrement">-</button>

8.4.2、v-on参数

  • 如果该方法不需要额外参数,那么方法后的()可以不添加
<button @click="decrement()">-</button>
//直接写成如下形式
<button @click="decrement">-</button>
  <!--2.在事件定义时, 写方法时省略了小括号, 
但是方法本身是需要一个参数的, 这个时候, Vue会默认将
浏览器生产的event事件对象作为参数传入到方法-->
<button @click="btn2Click">按钮2</button>
 <!--3.方法定义时, 我们需要event对象, 同时又需要其他参数-->
  <!-- 在调用方式, 如何手动的获取到浏览器参数的event对象: $event-->
<button @click="btn3Click(abc, $event)">按钮3</button>

      //对应的方法
       btn2Click(event) {
        console.log('--------', event);
      },
      btn3Click(abc, event) {
        console.log('++++++++', abc, event);
      }
  • 演示
    image.png
    9.1.3、v-on修饰符
    演示.png

8.5、条件判断

  • v-if后面的条件为false时,对应的元素以及其子元素不会渲染。
  • 也就是根本没有不会有对应的标签出现在DOM中
<div id="app">
  <h2 v-if="score>=90">优秀</h2>
  <h2 v-else-if="score>=80">良好</h2>
  <h2 v-else-if="score>=60">及格</h2>
  <h2 v-else>不及格</h2>
  //也可以写在计算属性当中
  <h1>{{result}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      score: 99
    },
    computed: {
      result() {
        let showMessage = '';
        if (this.score >= 90) {
          showMessage = '优秀'
        } else if (this.score >= 80) {
          showMessage = '良好'
        }
        return showMessage
      }
    }
  })
</script>

8.5.1、小案例

  • 用户再登录时,可以切换使用用户账号登录还是邮箱地址登录
<div id="app">
  <span v-if="isUser">
    <label for="username">用户账号</label>
    <input type="text" id="username" placeholder="用户账号">
  </span>
  <span v-else>
    <label for="email">用户邮箱</label>
    <input type="text" id="email" placeholder="用户邮箱">
  </span>
  <button @click="isUser = !isUser">切换类型</button>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      isUser: true
    }
  })
</script>
  • 我们可以发现随便测试能够实现我们的功能,但是存在一个问题,如果我们在用户账号的输入框输入内容的时候,我们再点击用户邮箱时,会发现输入框里面的内容也任然是存在的,文字依然显示之前的输入的内容。
    Q:为什么会存在这种问题么?另一个input原本是没有内容的。
    A:这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素,任然会复用原本的input
  • 解决
    这时候我们需要保证key的不同,避免复用,将上述代码添加各自的key,确保唯一!
<input type="text" id="username" placeholder="用户账号" key="username">
<input type="text" id="email" placeholder="用户邮箱" key="email">

8.6、v-show

  • v-show的用法和v-if非常相似,也用于决定一个元素是否渲染

v-if和v-show对比

  • v-if当条件为false时,压根不会有对应的元素在DOM中。
  • v-show当条件为false时,仅仅是将元素的display属性设置为none而已

如何选择?

  • 当需要在显示与隐藏之间切片很频繁时,使用v-show
  • 当只有一次切换时,通过使用v-if
<!--v-show: 当条件为false时, v-show只是给我们的元素添加一个行内样式: display: none-->
<h2 v-show="isShow" id="bbb">{{message}}</h2>

8.7、循环遍历–数组

  • 格式:item in items的形式
  //不需要索引值
  <!--1.在遍历的过程中,没有使用索引值(下标值)-->
  <ul>
    <li v-for="item in names">{{item}}</li>
  </ul>
  <!--2.在遍历的过程中, 获取索引值-->
  //其中的index就代表了取出的item在原数组的索引值
  <ul>
    <li v-for="(item, index) in names">
      {{index+1}}.{{item}}
    </li>
  </ul>

8.7.1、循环遍历–对象

<div id="app">
  <!--1.在遍历对象的过程中, 如果只是获取一个值, 那么获取到的是value-->
  <ul>
    <li v-for="item in info">{{item}}</li>
  </ul>
  <!--2.获取key和value 格式: (value, key) -->
  <ul>
    <li v-for="(value, key) in info">{{value}}-{{key}}</li>
  </ul>
  <!--3.获取key和value和index 格式: (value, key, index) -->
  <ul>
    <li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
  </ul>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      info: {
        name: 'why',
        age: 18,
        height: 1.88
      }
    }
  })
</script>

8.7.2、组件的key属性

  • 官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性
  • 这其实和Vue的虚拟DOM的Diff算法有关系
  • 可以这么理解,好比有一个数组,我们得我往中间插入一个数据,那么就需要插入位置后面的数据全部往后面移动一位,显然这是很没有效率的
  • 所以就需要通过key给每一个节点做一个唯一标识,通过Diff算法就可以正确的识别此节点了,并且找到正确的位置区插入新的节点
  • key的作用主要是为了高效的更新虚拟DOM
<div id="app">
  <ul>
    <li v-for="item in letters" :key="item">{{item}}</li>
  </ul>
</div>

8.8、检测数组更新

  • vue是响应式的,当数据发生改变,Vue检测到data数据改变就会重新渲染dom
  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
    相关代码

8.9、小案例–图书购物车

<div id="app">
  <div v-if="books.length">
    <table>
      <thead>
      <tr>
        <th></th>
        <th>书籍名称</th>
        <th>出版日期</th>
        <th>价格</th>
        <th>购买数量</th>
        <th>操作</th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="(item, index) in books">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.date}}</td>
        <td>{{item.price | showPrice}}</td>
        <td>
          <button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
          {{item.count}}
          <button @click="increment(index)">+</button>
        </td>
        <td><button @click="removeHandle(index)">移除</button></td>
      </tr>
      </tbody>
    </table>
    <h2>总价格: {{totalPrice | showPrice}}</h2>
  </div>
  <h2 v-else>购物车为空</h2>
</div>
<script>const app = new Vue({
  el: '#app',
  data: {
    books: [
      {
        id: 1,
        name: '《算法导论》',
        date: '2006-9',
        price: 85.00,
        count: 1
      },
      {
        id: 2,
        name: '《UNIX编程艺术》',
        date: '2006-2',
        price: 59.00,
        count: 1
      }
    ]
  },
  methods: {
    increment(index) {
      this.books[index].count++
    },
    decrement(index) {
      this.books[index].count--
    },
    removeHandle(index) {
      this.books.splice(index, 1)
    }
  },
  computed: {
    totalPrice() {
      let totalPrice = 0
      for (let i = 0; i < this.books.length; i++) {
        totalPrice += this.books[i].price * this.books[i].count
      }
      return totalPrice
    }
  },
  filters: {
    showPrice(price) {
      return '¥' + price.toFixed(2)
    }
  }
})
</script>

image.png

9、表单绑定v-model

  • Vue中使用v-model指令来实现表单元素和数据的双向绑定
  • 当我们在输入框输入内容时
  • 因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message发生改变。
  • 当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
  • 所以,通过v-model实现了双向的绑定。
<div id="app">
  <input type="text" v-model="message">
  {{message}}
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })
</script>

演示

9.1、v-model的原理

  • v-model其实是一个语法糖,它的背后本质上是包含两个操作:
    • v-bind绑定一个value属性
    • v-on指令给当前元素绑定input事件
<input type="text" v-model="message">
等同于
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">

9.1.1、v-model:radio

  • 单选框
<div id="app">
  <label for="male">
    <input type="radio" id="male" value="男" v-model="sex">男
  </label>
  <label for="female">
    <input type="radio" id="female" value="女" v-model="sex">女
  </label>
  <h2>您选择的性别是: {{sex}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      sex: '女'
    }
  })
</script>

9.1.1、v-model:checkbox

  • 多选框

单个勾选框:

  • v-model即为布尔值。
  • 此时input的value并不影响v-model的值。

多个复选框:

  • 当是多个复选框时,因为可以选中多个,所以对应的data-中属性是一个数组。
  • 当选中某一个时,就会将input的value添加到数组中。
<!--1.checkbox单选框-->
  <label for="agree">
    <input type="checkbox" id="agree" v-model="isAgree">同意协议
  </label>
  <h2>您选择的是: {{isAgree}}</h2>
  <button :disabled="!isAgree">下一步</button>
  <!--2.checkbox多选框-->
  <input type="checkbox" value="篮球" v-model="hobbies">篮球
  <input type="checkbox" value="足球" v-model="hobbies">足球
  <input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
  <input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
  <h2>您的爱好是: {{hobbies}}</h2>

  <label v-for="item in originHobbies" :for="item">
    <input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
  </label>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      isAgree: false, // 单选框
      hobbies: [], // 多选框,
      originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球']
    }
  })
</script>

9.2.3、v-model:select

单选:只能选中一个值。

  • v-model绑定的是一个值。
  • 当我们选中option中的一个时,会将它对应的value赋值到mySelect中

多选:可以选中多个值。

  • v-model绑定的是一个数组。
  • 当选中多个值时,就会将选中的option对应的value添加到数组mySelects中
<div id="app">
  <!--1.选择一个-->
  <select name="abc" v-model="fruit">
    <option value="苹果">苹果</option>
    <option value="香蕉">香蕉</option>
    <option value="榴莲">榴莲</option>
    <option value="葡萄">葡萄</option>
  </select>
  <h2>您选择的水果是: {{fruit}}</h2>

  <!--2.选择多个值 增加multiple-->
  <select name="abc" v-model="fruits" multiple>
    <option value="苹果">苹果</option>
    <option value="香蕉">香蕉</option>
    <option value="榴莲">榴莲</option>
    <option value="葡萄">葡萄</option>
  </select>
  <h2>您选择的水果是: {{fruits}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      fruit: '香蕉',
      fruits: []
    }
  })
</script>

9.3、值绑定
9.4、修饰符

  1. lazy修饰符:
  • 默认情况下,v-model默认是在input事件中同步输入框的数据的。
  • 也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。
  • lazy修饰符可以让数据在失去焦点或者回车时才会更新:
<input type="text" v-model.lazy="message">
  1. number修饰符:
  • 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
  • 但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。
  • number修饰符可以让在输入框中输入的内容自动转成数字类型:
<input type="number" v-model.number="age">
  1. trim修饰符:
  • 如果输入的内容首尾有很多空格,通常我们希望将其去除
  • trim修饰符可以过滤内容左右两边的空格
<input type="text" v-model.trim="name">
观看的网站

个人感觉讲的很清晰
https://www.bilibili.com/video/av59594689

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值