初步认识Vue.js

Vue 是我接触的第一个前端框架,所以必须要认真学学,记录一下学到的知识点。

Vue 的特点

  1. 遵循 MVVM 模式
  2. 代码简洁,体积小,运行效率高,适合PC/移动端的开发
  3. 只关注 UI ,当然也可以引入 vue 插件或其他第三方开源库

HelloVue

第一个 vue demo

<body>
  <div id="app">
    <h2>{{msg}}</h2>
  </div>

  <!-- 引入 vue.js 文件 -->
  <script src="../js/vue.js"></script>
  <script>
  	// 创建一个 Vue 的实例对象
    const vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello vue'
      }
    })
  </script>
</body>
  1. 首先在 JS 中先创建一个 Vue 的实例对象
  2. el 表示需要操作的 Element 节点,它的值是一个CSS选择器
  3. data 中存放的是数据,它是一个对象,它可以存放任意类型的值

运行后在界面上输出了
在这里插入图片描述
MVVM 模式

  1. 第一个 M 指的是 Model(模型) ,它本质上就是 数据对象 data
  2. 第一个 V 指的是 View(视图) ,它就是我们的模板页面
  3. VM 指的是 ViewModel(视图模型) ,它本质上一个 Vue 的实例对象 ,所以我们一般创建的时候都是这样创建的。
// vm 就是 Vue 对象的实例
const vm = new Vue({
	el:'#app',
	data:{  // model
		...
	}
})

在这里插入图片描述
在VM (视图模型) 中有两个东西,一个是 DOM Listeners (DOM 监听),一个是 Data Bindings (数据绑定)
DOM Listeners 会监听页面的变化,如果发生改变了,就会通知 model
Data Bindings 可以直接把内存中的数据(data 中的数据)显示到视图层,也就是我们的模板页面上

模板语法

1. 模板的理解:
  动态的html页面
  包含了一些JS语法代码
    大括号表达式
    指令(以v-开头的自定义标签属性)
2. 双大括号表达式
  语法: {{exp}} 
  功能: 向页面输出数据
  可以调用对象的方法
3. 指令一: 强制数据绑定
  功能: 指定变化的属性值
  完整写法:
    v-bind:xxx='yyy'  //yyy会作为表达式解析执行
  简洁写法:
    :xxx='yyy'
4. 指令二: 绑定事件监听
  功能: 绑定指定事件名的回调函数
  完整写法:
    v-on:click='xxx'
  简洁写法:
    @click='xxx'
  1. 双大括号表达式 {{ 显示data中的数据 }}
  2. 强制数据绑定
  3. 绑定事件监听
<!-- 双大括号表达式 -->
<div id="app">
    <h2>1. 双大括号表达式</h2>
    <p>{{ message }}</p> <!-- 大括号表达式 -->
    <p>{{ message.toUpperCase() }}</p> <!-- 转换成大写 -->
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
  new Vue({
    el: '#app',
    data: {
      message: 'i want you',
    }
  })
</script>

在这里插入图片描述

<h2>2. 指令一: 强制数据绑定</h2>
<img v-bind:src="imgURL"> <!-- 基本语法 -->
<img :src="imgURL" alt=""> <!-- 简写 -->

<script type="text/javascript">
new Vue({
  el: '#app',
  data: {
    imgURL: 'https://cn.vuejs.org/images/logo.png'
  }
})
</script>

在这里插入图片描述

<h2>3. 指令二: 绑定事件监听</h2>
<button v-on:click="test">基本语法</button> <!-- 基本语法 -->
<button @click="test2">简写</button> <!-- 简写 -->

<script type="text/javascript">
new Vue({
  el: '#app',
  data: {
    message: 'i want you'
    imgURL: 'https://cn.vuejs.org/images/logo.png'
  },
  methods: {   // 方法写到这里
    test() {
      alert('绑定事件监听!')
    },
    test2() {
      alert('我是简写')
    }
  }
})
</script>

在这里插入图片描述
在这里插入图片描述

计算属性和监视

1. 计算属性
  在computed属性对象中定义计算属性的方法
  在页面中使用{{方法名}}来显示计算的结果
2. 监视属性:
  通过通过vm对象的$watch()或watch配置来监视指定的属性
  当属性变化时, 回调函数自动调用, 在函数内部进行计算
3. 计算属性高级:
  通过getter/setter实现对属性数据的显示和监视
  计算属性存在缓存, 多次读取只执行一次getter计算

  getter:  对应属性的 get 方法
  setter:  对应属性的 set 方法
<div id="app">
    姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
    名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
    <!--fullName1是根据fistName和lastName计算产生-->
    姓名1(单向): <input type="text" placeholder="Full Name1" v-model="fullName1"><br>
    姓名2(单向): <input type="text" placeholder="Full Name2" v-model="fullName2"><br>
    姓名3(双向): <input type="text" placeholder="Full Name3" v-model="fullName3"><br>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({
  el: '#app',
  data: {
    firstName: 'A',
    lastName: 'B',
    fullName2: 'A B'
  },
  computed: { // 计算属性 , 计算属性会缓存数据
    // 在首次初始化的时候执行 / 相关的数据发生了改变的时候自动执行  (firstName,lastName)
    fullName1: function () {
      console.log('function()')
      // 这里的 this 是 vm 对象,也就是 vue 的实例对象
      return this.firstName + ' ' + this.lastName
    },
    // 使用计算属性来实现数据的双向绑定
    fullName3: {
      // 获取
      get() {
        return this.firstName + ' ' + this.lastName
      },
      // 设置,当属性值发生改变时回调,更新相关的属性数据(firstName,lstName)
      set(value) { //  value 就是 fullName3 的最新属性值
        var names = value.split(' ')
        this.firstName = names[0]
        this.lastName = names[1]
      }
    }

  },
  watch: { // 监视方式1   (配置监视)
    // 当 firstName 的值发生变化的时候调用
    firstName: function (value) {
      // 这里的 this 是 vm 对象,也就是 vue 的实例对象
      this.fullName2 = value + ' ' + this.lastName
    }
  }
})

// 监视的方式2
vm.$watch('lastName', function (value) {
  // 这里的 this 也是 vue 的实例对象 vm
  this.fullName2 = this.firstName + ' ' + value
})
</script>

运行效果
在这里插入图片描述

class 与 style 绑定

1. 理解
  在应用界面中, 某个(些)元素的样式是变化的
  class/style绑定就是专门用来实现动态样式效果的技术
2. class绑定: :class='xxx'
  xxx是字符串
  xxx是对象  { class:布尔值,class:布尔值 }
  xxx是数组
3. style绑定
  :style="{ color: activeColor, fontSize: fontSize + 'px' }"
  其中activeColor/fontSize是data属性
<!-- 样式 -->
<style>
.aClass {
  color: red;
}

.bClass {
  color: green;
}

.cClass {
  font-size: 30px;
}
</style>

<!-- 结构 -->
<div id="app">
	<h2>1. class绑定: :class='xxx'</h2>
	<p class="cClass" :class="a">xxx是字符串</p>
	<p :class="{aClass:isA,bClass:isB}">xxx是对象</p>
	<p :class="['bClass','cClass']">xxx是数组</p>
	
	<h2>2. style绑定</h2>
	<p :style="{color: activeColor, fontSize: fontSize + 'px'}">style 样式绑定</p>

	<!-- 点击按钮以后修改 p 的样式 -->
	<button @click="updated">点我更换样式</button>

</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
	new Vue({
	  el: '#app',
	  data: {
	    a: 'aClass',
	    isA: true,
	    isB: false,
	    activeColor: 'pink',
	    fontSize: 20
	  },
	  methods: {
	    updated() {
	      this.a = 'bClass'
	      this.isA = false
	      this.isB = true
	      this.activeColor = 'green'
	      this.fontSize = 30
	    }
	  }
	})
</script>

在这里插入图片描述

条件渲染

1. 条件渲染指令
  v-if  : 在内存中把标签移出
  v-else
  v-show  : 通过display样式来控制元素的显示和隐藏
2. 比较v-if与v-show
  如果需要频繁切换 v-show 较好
<div id="app">
  <p v-if="ok">成功了</p>
  <p v-else>失败了</p>

  <p v-show="ok">入职成功</p>
  <p v-show="!ok">入职失败</p>

  <button @click="ok = !ok">切换</button>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
  new Vue({
    el: '#app',
    data: {
      ok: true
    }
  })
</script>

在这里插入图片描述

列表渲染

1. 列表显示
  数组: v-for / index
  对象: v-for / key
2. 列表的更新显示
  删除item
  替换item
<div id="app">
  <h2>测试: v-for 遍历数组</h2>

  <ul>
    <li v-for="(p,index) in persons" :key="index">{{index}}----{{p.name}}----{{p.age}}
      ---- <button @click="deletePerson(index)">删除</button>
      ---- <button @click="updatePerson(index,{name:'Dog',age:20})">更新</button>

    </li>
  </ul>
  <h2>测试: v-for 遍历对象</h2>
  <ul>
    <li v-for="(value,key) in persons[1]" :key="key">
      {{value}}---{{key}}
    </li>
  </ul>

</div>

  <script type="text/javascript" src="../js/vue.js"></script>
  <script type="text/javascript">
    // vue 本身只是监视了 Persons 的改变,没有监视 数组内部的改变
    // vue 重写了数组中一系列改变数组内部的方法(先调用原生的,更新界面)---> 数组内部改变,界面自动变化
    new Vue({
      el: '#app',
      data: {
        persons: [{
            name: '孙悟空',
            age: 18
          },
          {
            name: '猪八戒',
            age: 23
          },
          {
            name: '沙和尚',
            age: 30
          },
          {
            name: '唐僧',
            age: 25
          },
          {
            name: '观音菩萨',
            age: 30
          }
        ]
      },
      methods: {
        deletePerson(index) {
          // 删除 Persons 中指定 index 的 Person
          this.persons.splice(index, 1)
        },

        updatePerson(index, newP) {
          // 删除 Persons 中指定 index 的 Person
          // 用 splice 方法可以实现增删改
          this.persons.splice(index, 1, newP)

        }

      },
    })
  </script>

在这里插入图片描述
实现功能
在这里插入图片描述

列表的过滤和排序

<div id="app">
	<input type="text" v-model="searchName">
	<ul>
	  <li v-for="(item, index) in filterPersons" :key="index">
	    {{index}}---{{item.name}}---{{item.age}}
	  </li>
	</ul>
	
	<button @click="setOrderType(1)">年龄升序</button>
	<button @click="setOrderType(2)">年龄降序</button>
	<button @click="setOrderType(0)">原本顺序</button>
</div>

  <script type="text/javascript" src="../js/vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        searchName: '',
        orderType: 0, // 0 表示原本顺序
        persons: [{
            name: 'ATom',
            age: 24
          },
          {
            name: 'ABom',
            age: 17
          },
          {
            name: 'Asiner',
            age: 30
          },
          {
            name: 'Ajeer',
            age: 25
          },
          {
            name: 'Acolor',
            age: 32
          }
        ]

      },
      computed: {	// 使用 计算属性
        filterPersons() {
          // 1. 取出相关的数据
          const {
            searchName,
            persons,
            orderType
          } = this

          let fPersons // 最终需要显示的数组


          // 2. 对 persons 进行过滤 , 然后赋值给 fPersons
          fPersons = persons.filter(p => p.name.indexOf(searchName) !== -1)

          // 排序
          if (orderType !== 0) {
            // 自定义排序规则
            fPersons.sort(function (p1, p2) {
              // 1 代表升序  ,2 代表降序  ,0 代表原本顺序
              if (orderType === 2) {
                return p2.age - p1.age
              } else {
                return p1.age - p2.age
              }
            })
          }
          return fPersons

        }
      },
      methods: {
        setOrderType(orderType) {
          this.orderType = orderType
        }
      },
    })
  </script>

在这里插入图片描述

事件绑定

1. 绑定监听:
  v-on:xxx="fun"
  @xxx="fun"
  @xxx="fun(参数)"
  默认事件形参: event
  隐含属性对象: $event
2. 事件修饰符:
  .prevent : 阻止事件的默认行为 event.preventDefault()
  .stop : 停止事件冒泡 event.stopPropagation()
3. 按键修饰符
  .keycode : 操作的是某个keycode值的健
  .enter : 操作的是enter键

<div id="app">

  <h2>1. 绑定监听</h2>
  <button @click="test1">btn01</button>
  <button @click="test2(msg)">btn02</button>
  <button @click="test3($event)">btn03</button>
  <button @click="test4(msg,$event)">btn04</button>

  <h2>2. 事件修饰符</h2>

  <!-- 停止事件冒泡 -->
  <div style="width: 200px;height: 200px; background-color: greenyellow;" @click="test5">
    <div style="width: 100px;height: 100px; background-color: goldenrod;" @click.stop="test6"></div>
  </div>
  <!-- 阻止事件的默认行为 -->
  <a href="http://www.baidu.com" @click.prevent="test7">去百度</a>

  <h2>3. 按键修饰符</h2>
  <input type="text" @keyup.13="test8">
  <input type="text" @keyup.enter="test8">

</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
  new Vue({
    el: '#app',
    data: {
      msg: 'a message'
    },
    methods: {
      test1() {
        alert('test1')
      },
      test2(msg) {
        alert(msg)
      },
      test3(event) {
        alert(event.target.innerHTML)
      },
      test4(msg, event) {
        alert(msg + ' ' + event.target.innerHTML)
      },
      test5() {
        alert('test5')
      },
      test6() {
        alert('test6')
      },
      test7() {
        alert('test7')
      },
      test8(event) {
        alert(event.target.value)
      }

    },

  })
</script>

在这里插入图片描述

表单输入绑定

1. 使用v-model(双向数据绑定)自动收集数据
  text/textarea
  checkbox
  radio
  select
<div id="demo">
  <form action="/xxx" @submit.prevent="handleSubmit">
    <span>用户名: </span>
    <input type="text" v-model="username"><br>

    <span>密码: </span>
    <input type="password" v-model="password"><br>

    <span>性别: </span>
    <input type="radio" id="female" v-model="sex" value="">
    <label for="female"></label>
    <input type="radio" id="male" v-model="sex" value="">
    <label for="male"></label><br>

    <span>爱好: </span>
    <input type="checkbox" id="basket" value="basket" v-model="likes">
    <label for="basket">篮球</label>
    <input type="checkbox" id="foot" value="foot" v-model="likes">
    <label for="foot">足球</label>
    <input type="checkbox" id="pingpang" value="pingpang" v-model="likes">
    <label for="pingpang">乒乓</label><br>

    <span>城市: </span>
    <select v-model="cityId">
      <option value="">未选择</option>
      <option v-for="(city, index) in allCitys" :key="index" :value="city.id">{{city.name}}</option>
    </select><br>
    <span>介绍: </span>
    <textarea rows="10" v-model="desc"></textarea><br><br>

    <input type="submit" value="注册">
  </form>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      username: '',
      password: '',
      sex: '女',
      likes: ['foot'],
      allCitys: [{
          id: 1,
          name: 'beijing'
        },
        {
          id: 2,
          name: 'shanghai'
        },
        {
          id: 3,
          name: 'sandong'
        },
      ],
      cityId: '',
      desc: ''
    },
    methods: {
      handleSubmit() {
        console.log(this.username, this.password, this.sex, this.likes, this.allCitys, this.cityId, this.desc)
      }
    },
  })
</script>

在这里插入图片描述
在这里插入图片描述

Vue 对象的生命周期

1. vue对象的生命周期
  1). 初始化显示
    * beforeCreate()
    * created()
    * beforeMount()
    * mounted()
  2). 更新状态
    * beforeUpdate()
    * updated()
  3). 销毁vue实例: vm.$destory()
    * beforeDestory()
    * destoryed()
2. 常用的生命周期方法
  created()/mounted(): 发送ajax请求, 启动定时器等异步任务
  beforeDestory(): 做收尾工作, 如: 清除定时器
<div id="app">
    <button @click="destoryVM">destory vm</button>
    <p v-show="isShow">小明爱吃肉</p>
  </div>

  <script type="text/javascript" src="../js/vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        isShow: true
      },

      // 初始化阶段
      beforeCreate() {
        console.log('beforeCreate()')
      },
      created() {
        console.log('created()')

      },
      beforeMount() {
        console.log('beforeMount()')

      },

      mounted() { //初始化显示之后,立即调用 一次
        console.log('mounted()')
        this.intervalId = setInterval(() => { // 箭头函数
          console.log('===')
          this.isShow = !this.isShow
        }, 1000);
      },

      // 更新阶段
      beforeUpdate() {
        console.log('beforeUpdate()')

      },
      updated() {
        console.log('updated()')

      },

      // 死亡阶段

      beforeDestroy() { // 死亡之前调用 一次
        console.log('beforeDestroy()')

        // 清除定时器
        clearInterval(this.intervalId)
      },

      destroyed() {
        console.log('destroyed()')

      },

      methods: {
        // 按钮的点击事件
        destoryVM() {
          // 
          this.$destroy()
        }
      },
    })
  </script>

Vue 过渡和动画

过渡

1. vue动画的理解
  操作css的trasition或animation
  vue会给目标元素添加/移除特定的class
2. 基本过渡动画的编码
  1). 在目标元素外包裹<transition name="xxx">
  2). 定义class样式
    1>. 指定过渡样式: transition
    2>. 指定隐藏时的样式: opacity/其它
3. 过渡的类名
  xxx-enter-active: 指定显示的transition
  xxx-leave-active: 指定隐藏的transition
  xxx-enter: 指定隐藏时的样式
 <style>
    .fade-enter-active,
    .fade-leave-active {
      transition: opacity .5s;
    }

    .fade-enter,
    .fade-leave-to {
      opacity: 0;
    }

    .fade2-enter-active {
      transition: opacity 3s, transform 1s;
    }

    .fade2-leave-active {
      transition: opacity 1s, transform 3s;
    }

    .fade2-enter,
    .fade2-leave-to {
      opacity: 0;
      transform: translate(20px);
    }
  </style>


<div id="test">
    <button @click="isShow=!isShow">togger</button>
    <transition name="fade">
      <p v-show="isShow">hello</p>
    </transition>
</div>


<div id="test2">
  <button @click="isShow=!isShow">togger</button>
  <transition name="fade2">
    <p v-show="isShow">hello</p>
  </transition>
</div>

  <script type="text/javascript" src="../js/vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#test',
      data() {
        return {
          isShow: true
        }
      },
    })

    new Vue({
      el: '#test2',
      data() {
        return {
          isShow: true
        }
      },
    })
  </script>

在这里插入图片描述
Animation

<style>
  .bounce-enter-active {
    animation: bounce-in .5s;
  }

  .bounce-leave-active {
    animation: bounce-in .5s reverse;
  }

  @keyframes bounce-in {
    0% {
      transform: scale(0);
    }

    50% {
      transform: scale(1.5);
    }

    100% {
      transform: scale(1);
    }
  }
</style>
<body>
  <div id="example-2">
    <button @click="show = !show">Toggle show</button><br>
    <transition name="bounce">
      <p v-if="show" style="display: inline-block">Lorem ipsum</p>
    </transition>
  </div>
  <script type="text/javascript" src="../js/vue.js"></script>
  <script>
    new Vue({
      el: '#example-2',
      data: {
        show: true
      }
    })
  </script>
</body>

在这里插入图片描述

过滤器

1. 理解过滤器
  功能: 对要显示的数据进行特定格式化后再显示
  注意: 并没有改变原本的数据, 可是产生新的对应的数据
2. 编码
  1). 定义过滤器
    Vue.filter(filterName, function(value[,arg1,arg2,...]){
      // 进行一定的数据处理
      return newValue
    })
  2). 使用过滤器
    <div>{{myData | filterName}}</div>
    <div>{{myData | filterName(arg)}}</div>
<!--需求: 对当前时间进行指定格式显示-->
  <div id="test">
    <h2>显示格式化的日期时间</h2>
    <p>{{date}}</p>
    <p>完整版:{{date | dateString}}</p>
    <p>年月日:{{date | dateString('YYYY-MM-DD')}}</p>
  </div>

  <script type="text/javascript" src="../js/vue.js"></script>
  <!-- 时间格式化的js库 -->
  <script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.22.1/moment.js"></script>
  <script>
    // 自定义过滤器,通过 Vue 的函数对象
    Vue.filter('dateString', function (value, format = 'YYYY-MM-DD HH:mm:ss') {   // 形参默认值
      return moment(value).format(format)
    })

    new Vue({
      el: '#test',
      data: {
        date: new Date(),
      },
    })
  </script>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值