①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)

Vue

  • Vue的基本认识
    • 与其它前端 JS 框架的关联
    • Vue的特点简介
    • Vue扩展插件简介
  • Vue的基本使用 ※
  • 模板语法 ※
  • 计算属性和监视 ※
  • class与style的绑定 ※
  • 条件渲染 ※
  • 列表渲染 ※
  • 列表的搜索和排序 ※
  • 事件处理 ※
  • 表单输入绑定 ※
  • 生命周期 ※
  • 过渡&动画 ※
  • 过滤器 ※
  • 指令 ※
  • 自定义指令 ※
  • 做一个简单插件


本人是个新手,写下博客用于自我复习、自我总结。
如有错误之处,请各位大佬指出。
学习资料来源于:尚硅谷


Vue的基本认识

大家只要进入到Vue官网,就会知道一个信息:
①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第1张图片
何为渐进式?Vue的库分为核心库以及相关的插件,核心库比较小,能实现一些基本的功能。显然做项目时,只有核心库肯定不够,需要时就要用其他相关的插件。
所以渐进式就是:我们先只用核心库,当我们需要用到某些特定的功能时,我们就添加我们所需要的这些插件。

Vue的作用:动态构建用户界面。即将后台的数据,在前台的界面上动态渲染显示出来。


与其它前端 JS 框架的关联

在这里插入图片描述


Vue的特点简介

①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第2张图片


Vue扩展插件简介

①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第3张图片
vue-cli:帮我们下载基于Vue的项目,而且项目里写好了配置,设置好了依赖。


Vue的基本使用 ※

这里用的Vue版本是2.x版本,目前大部分情况用的也是2.x版本。

如何下载:https://blog.csdn.net/qq_42345237/article/details/80888518

(在这里需要说的是,Vue的中文官网也是配有教程讲解的,如果遇到什么问题查阅官方文档很方便)

Vue.js存放的目录:
在这里插入图片描述
在这里,如果之前学了AngularJS,那么对这里的理解就很方便了,而且语法也十分相近,比如,在Angular中,用的是ng-model,这里用的就是v-model。同时可以用{{}}来获取属性。

数据绑定: 数据从一个位置自动流向另一个位置。
View–>Model
Model–>View

单向数据绑定: 只支持一个方向。

双向数据绑定:数据可以从View(视图层)流向Model(模型),也可以从Model流向View。

和Angular中一样,v-model是双向数据绑定, 而{{}}是单向数据绑定。如果有需要,可以去我之前的AngularJS博文简单的看一看数据绑定部分,因为很好理解且是很简单的语法。

test.html


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01_HelloWorldtitle>
head>
<body>



<div id="test"> 
  <input type="text" v-model="msg">
  <br>
  <input type="text" v-model="msg">
  <p>hello {{msg}}p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  // 创建Vue示例
  const vm = new Vue({ // 配置对象 options
    // 配置选项(option)
    el: '#test',  // element: 指定用vue来管理页面中的哪个标签区域
    data: {  // 数据 model
      msg: 'hello'
    }
  })
script>
body>
html>

①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第4张图片
在Vue里,这个MVVM到底是什么,到底是如何办到上面代码效果的:
首先有一个监听,会监听这个输入框内容,当输入框中的内容发生了改变,监听器就触发。这个监听器的回调函数就会把输入框的内容保存到data里,同时将这个数据输出到页面里去显示。而这个过程就会用到DOM监听和数据绑定。具体的之后会有涉及。

MVVM:
model:模型,数据对象(data)
view:视图,模板页面
viewModel:视图模型(Vue的实例)

在代码中的体现:
①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第5张图片


模板语法 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>02_模板语法title>
head>
<body>


<div id="app">
  <h2>1. 双大括号表达式h2>
  <p>{{content}}p>
  <p>{{content.toUpperCase()}}p>
  <p v-text="content">p> 
  
  <p v-html="content2">p> 

  <h2>2. 指令一: 强制数据绑定h2>
  <a href="url">访问指定站点a><br>
  <a v-bind:href="url">访问指定站点2a><br>
  <a :href="url">访问指定站点2a><br>

  <h2>3. 指令二: 绑定事件监听h2>
  <button v-on:click="test">点我1button>
  <button @click="test2(content)">点我2button>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#app',
    data: {
      content: 'I Love This Game',
      content2: 'baidu',
      url: 'http://www.baidu.com'
    },
    methods: {
      test () {
        alert('妙啊!!!')
      },
      test2(msg){
        alert(msg)
      }
    }
  })
script>
body>
html>

计算属性和监视 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>03_计算属性和监视title>
head>
<body>

<div id="demo">
  姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
  名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
  
  姓名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>

  <p>{{fullName1}}p>
  <p>{{fullName1}}p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  const vm = new Vue({
    el: '#demo',
    data: {
      firstName: 'A',
      lastName: 'B',
      /*
      * 对于这第二种方式监听来说,如果输入框没有改动,它就不会去触发。
      * 那么就需要传递一个初始值了,否则初始值就肯定是undefined。
      * 而且第二种方式显然比较麻烦,所以通常使用第一种。
      * */
      fullName2: 'A-B'
    },
    // 计算属性配置: 值为对象
    computed: {
      // 什么时候执行:初始化显示/相关的data属性数据发生改变
      fullName1 () { // 计算属性中的一个方法,方法的返回值作为属性值,相当于属性的get
        return this.firstName + '-' + this.lastName
      },
      /*前两种实现方式都是单向的,第三种方式可以双向*/
      fullName3: {
        // 回调函数,当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
        get () {
          return this.firstName + '-' + this.lastName
        },
        // 回调函数,当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
        set (value) {
          // 更新firstName和lastName
          const names = value.split('-')
          this.firstName = names[0]
          this.lastName = names[1]
        }
      }
    },
    /*监听的第一种方式*/
    watch: {
      // 配置监视firstName
      firstName: function (value) { // 相当于属性的set
        // 更新fullName2
        this.fullName2 = value + '-' + this.lastName
      }
    }
  })
  /*监听的第二种方式*/
  // 监视lastName
  vm.$watch('lastName', function (value) {
    // 更新fullName2
    this.fullName2 = this.firstName + '-' + value
  })
script>
body>
html>

class与style的绑定 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>04_class与style绑定title>
  <style>
    .classA {
      color: red;
    }
    .classB {
      color: blue;
    }
    .classC {
      font-size: 20px;
    }
  style>
head>
<body>



<div id="demo">
  <h2>1. class绑定: :class='xxx'h2>
  <p class="classC" :class="myClass">xxx是字符串p>
  <p :class="{classA: hasClassA, classB: hasClassB}">xxx是对象p>
  <p :class="['classA', 'classB']">xxx是数组p>

  <h2>2. style绑定h2>
  <p :style="{color:activeColor, fontSize: fontSize}">:style="{ color: activeColor, fontSize: fontSize }"p>

  <button @click="update">更新button>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      myClass: 'classA',
      hasClassA: true,
      hasClassB: false,
      activeColor: 'red',
      fontSize: '20px'
    },
    methods: {
      update () {
        this.myClass = 'classB'
        this.hasClassA = !this.hasClassA
        this.hasClassB = !this.hasClassB
        this.activeColor = 'yellow'
        this.fontSize = '30px'
      }
    }
  })
script>
body>
html>

条件渲染 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>05_条件渲染title>
head>
<body>

<div id="demo">
  <p v-if="ok">成功p>
  <p v-else>失败p>
  <hr>
  <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: '#demo',
    data: {
      ok: true
    }
  })
script>
body>
html>

列表渲染 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>06_列表渲染title>
head>
<body>



<div id="demo">
  <h2>测试: v-for 遍历数组h2>
  <ul>
    <li v-for="(p, index) in persons" :key="index">
      {{index}}--{{p.name}}--{{p.age}}
      --<button @click="deleteP(index)">删除button>
      --<button @click="updateP(index, {name:'Cat', age: 16})">更新button>
    li>
  ul>
  <button @click="addP({name: 'xfzhang', age: 18})">添加button>

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

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      persons: [
        // vue本身只监视了persons的改变,没有监视数组内部数据的改变
        {name: 'Tom', age:18},
        {name: 'Jack', age:17},
        {name: 'Bob', age:19},
        {name: 'Mary', age:16}
      ]
    },
    methods: {
      deleteP (index) {
        //删除persons中指定index的p
        /*
        * 上面说到vue本身只监视persons的改变,那么splice方法也只是改变内部数据,为什么会被监听到?
        * 因为这个splice已经不是数组本身的splice方法了,它已经是个变异方法了,即它只是对原方法的一个包装。
        * 简单来说就是当你调用原来这个方法,vue就会对它重写,让它能够因为数组内部改变,而界面自动变化。
        * */
        this.persons.splice(index, 1)
      },
      updateP (index, newP) {
        // 数组内部发生变化,但没有调用变异方法,所以不能使用这种方式
        // this.persons[index] = newP
        this.persons.splice(index, 1, newP)
        //这个splice方法,不仅能删除,修改,还能增加:
        //this.persons.splice(index,0,newP)
      },
      addP (newP) {
        this.persons.push(newP)
      }
    }
  })
script>
body>
html>

列表的搜索和排序 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>06_列表渲染_过滤与排序title>
head>
<body>

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

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      searchName: '',
      orderType: 0, // 0代表不排序, 1代表降序, 2代表升序
      persons: [
        {name: 'Tom', age:18},
        {name: 'Jack', age:17},
        {name: 'Bob', age:19},
        {name: 'Mary', age:16}
      ]
    },
    computed: {
      filterPersons () {
        // 取出相关数据
        const {searchName, persons, orderType} = this
        // 最终需要显示的数组
        let arr = [...persons]
        // 过滤数组
        if(searchName.trim()) {
          arr = persons.filter(p => p.name.indexOf(searchName)!==-1)
        }
        // 排序
        if(orderType!==0) {
          arr.sort(function (p1, p2) { // 如果返回负数,p1在前,返回正数,p2在前
            if(orderType===1) { // 降序
              return p2.age-p1.age
            } else { // 升序
              return p1.age-p2.age
            }
          })
        }
        return arr
      }
    },
    methods: {
      setOrderType (orderType) {
        this.orderType = orderType
      }
    }
  })
script>
body>
html>

事件处理 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>07_事件处理title>
head>
<body>

<div id="example">

  <h2>1. 绑定监听h2>
  <button @click="test1">test1button>
  <button @click="test2('abc')">test2button>
  <button @click="test3('abcd', $event)">test3button>

  <h2>2. 事件修饰符h2>
  <a href="http://www.baidu.com" @click.prevent="test4">百度一下a>
  <div style="width: 200px;height: 200px;background: red  " @click="test5">
    <div style="width: 100px;height: 100px;background: blue" @click.stop="test6">div>
  div>

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

div>

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

    },
    methods: {
      test1(event) {
        alert(event.target.innerHTML)
      },
      test2 (msg) {
        alert(msg)
      },
      test3 (msg, event) {
        alert(msg+'---'+event.target.textContent)
      },
      test4 () {
        alert('点击了链接')
      },
      test5 () {
        alert('out')
      },
      test6 () {
        alert('inner')
      },
      test7 (event) {
        console.log(event.keyCode)
        alert(event.target.value)
      }
    }
  })
script>
body>
html>

表单输入绑定 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>08_表单输入绑定title>
head>
<body>

<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="pwd"><br>

    <span>性别: span>
    <input type="radio" id="female" value="" v-model="sex">
    <label for="female">label>
    <input type="radio" id="male" value="" v-model="sex">
    <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 :value="city.id" v-for="(city, index) in allCitys" :key="city.id">{{city.name}}option>
    select><br>
    <span>介绍: span>
    <textarea rows="10" v-model="info">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: '',
      pwd: '',
      sex: '男',
      likes: ['foot'],
      allCitys: [{id: 1, name: 'BJ'}, {id: 2, name: 'SS'}, {id: 3, name: 'SZ'}],
      cityId: '2',
      info: ''
    },
    methods: {
      handleSubmit () {
        console.log(this.username, this.pwd, this.sex, this.likes, this.cityId, this.info)
        alert('提交注册的ajax请求')
      }
    }
  })
script>
body>
html>

生命周期 ※

根据图示,我们可以看到Vue生命周期的几个阶段。首先,当建立了一个Vue实例后,马上就会调用beforeCreate,之后Vue做一些准备工作:监视属性值的变化用来实现数据绑定以及初始化事件。之后调用created

接着就进行判断,就是判断我们用的el有没有设置。当我们设置了,也就指定了Vue会为谁服务,假如我们不设置,也可以通过手动设置(显然,我们没必要手动设置,使用el很简单)。然后判断是否设置了template,像我们之前没有设置过,那它就会以el指定的区域作为模板,来进行解析。在这里有一个概念叫批量处理。即在解析的时候并不是在页面上直接进行解析,而是先在内存中对所有内容进行解析处理(批量处理),编译好之后再一次性全部送回到页面。而送回之前就是beforeMount,送回之后就是mounted。 到这里为止是生命周期的第一个阶段,初始化显示

生命周期的第二个阶段:更新。在数据发生改变之前就是beforeUpdate,更新后就是updated

生命周期的第三个阶段:销毁 / 死亡。当调用到了vm.$destroy()就意味着要开始进行销毁了。通常使用beforeDestroy来做一些销毁前的工作,比如清除定时器。在Vue里销毁会把组件移除掉,页面中也许还会有显示,但是会失去绑定,失去交互。销毁后就是destroyed
①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第6张图片


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>09_Vue实例_生命周期title>
head>
<body>

<div id="test">
  <button @click="destroyVue">destory vuebutton>
  <p v-if="isShow">hellop>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#test',
    data: {
      isShow: true
    },
    mounted () { //初始化显示之后立即调用
      // 执行异步任务
      this.intervalId = setInterval(() => {
        this.isShow = !this.isShow
      }, 1000)
    },
    beforeDestroy() { //死亡之前调用1次
      console.log('beforeDestroy()')
      // 执行收尾的工作,清除定时器
      clearInterval(this.intervalId)
    },
    methods: {
      destroyVue () {
        this.$destroy()
      }
    }
  })
script>
body>
html>

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>09_Vue实例_生命周期title>
head>
<body>

<div id="test">
  <button @click="destroyVue">destory vuebutton>
  <p v-if="isShow">hellop>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#test',
    data: {
      isShow: true
    },
    //1、初始化阶段
    beforeCreate() {
      console.log('beforeCreate()')
    },
    created() {
      console.log('created()')
    },
    beforeMount() {
      console.log('beforeMount()')
    },
    mounted () {/*常用*/
      console.log('mounted()')
      // 执行异步任务
      this.intervalId = setInterval(() => {
        this.isShow = !this.isShow
      }, 1000)
    },
    //2、更新阶段
    beforeUpdate() {
      console.log('beforeUpdate()')
    },
    updated () {
      console.log('updated()')
    },
    //3、死亡阶段
    beforeDestroy() { /*常用*/
      console.log('beforeDestroy()')
      clearInterval(this.intervalId)
    },
    destroyed() {
      console.log('destroyed()')
    },
    methods: {
      destroyVue () {
        this.$destroy()
      }
    }
  })
script>
body>
html>

阶段输出示意图:(当点击了按钮才会触发销毁,否则肯定会更新无数次)
①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第7张图片


过渡&动画 ※

对于Vue里的过渡和动画,实际上操作的就是css的trasition或animation。
当我们想使用的时候,我们需要在在目标元素外包裹
(注意:这个name可以为任何值)。
先看一个简例,完整代码在下面。

<transition name="xxx">
    <p v-show="show">hellop>
transition>

在这里想实现的效果就是hello的消失与出现。简单来看,这段代码貌似没有什么办法可以触发过渡和动画效果,实际上Vue帮我们做了一个事:给目标元素添加/移除特定的class。比如它的效果应该是这样的:

就像下图中展示的过程,在这里就以出现和消失举例,其他效果也是同理的。
当最开始的时候,元素是隐藏的状态,即Opacity:0,它会给元素加一个类名:
xxx-enter,也就是通过xxx-enter来指定了元素隐藏时候的样式。元素要出现时(出现的过程),就会给它加xxx-enter-active的类名,过渡/动画 效果结束的时候,就会给它加xxx-enter-to的类名。

对于消失部分也是同样的,在要消失前是xxx-leave,消失的过程是
xxx-leave-active,消失后就是xxx-leave-to,同时通过xxx-leave-to来指定了元素隐藏时候的样式。

(当然 过渡/动画 效果不仅限于出现和消失,也会有其他效果,在这里以出现和消失举例,并不意味着这种方法只能实现出现和消失或者必须实现出现和消失)

所以通过整个过程的分析,也就不难看出,对于该元素来将:
xxx-enterxxx-leave-to,都用来指定隐藏时的样式,只不过一个是出现前,一个是出现后,通常一起实现。
xxx-enter-activexxx-leave-active,分别用来记录出现的过程和消失的过程,即用它们来指定过渡效果。

在这里需要注意的是,xxx-enter-toxxx-leave只代表着 过渡/动画 效果结束时和元素准备实现动画效果这两个瞬间,即这两个类名不会长时间存在。所以通常也不实现它们。
(在这时,我本以为 对xxx-enter-to加一些css样式就会在 过渡/动画 效果实现后触发,只要不触发leave操作,这个类名就可以长时间存在。但是只要尝试后就会发现,确实是不行。)

①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第8张图片


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>10_过渡&动画1title>
  <style>
    /*指定过渡样式*/
    .xxx-enter-active, .xxx-leave-active {
      transition: opacity 1s;
    }
    /*指定隐藏时的样式*/
    .xxx-enter, .xxx-leave-to {
      opacity: 0;
    }
    .move-enter-active {
      transition: all 1s
    }
    .move-leave-active {
      transition: all 3s
    }
    .move-enter, .move-leave-to {
      opacity: 0;
      transform: translateX(20px)
    }
  style>
head>
<body>

<div id="demo">
  <button @click="show = !show">Togglebutton>
  <transition name="xxx">
    <p v-show="show">hellop>
  transition>
div>
<hr>
<div id="demo2">
  <button @click="show = !show">Toggle2button>
  <transition name="move">
    <p v-show="show">hellop>
  transition>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      show: true
    }
  })
  new Vue({
    el: '#demo2',
    data: {
      show: true
    }
  })
script>
body>
html>

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>10_过渡&动画2title>
  <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>
head>
<body>

<div id="example-2">
  <button @click="show = !show">Toggle showbutton>
  <br>
  <transition name="bounce">
    <p v-if="show" style="display: inline-block">Loremp>
  transition>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script>
  new Vue({
    el: '#example-2',
    data: {
      show: true
    }
  })
script>
body>
html>

过滤器 ※

对于具体moment.js的使用,大家可以去moment查看官方文档查看,这里就展示一下格式:
①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第9张图片


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>11_过滤器title>
head>
<body>


<div id="test">
  <h2>显示格式化的日期时间h2>
  <p>{{time}}p>
  <p>最完整的: {{time | dateString}}p>
  <p>年月日: {{time | dateString('YYYY-MM-DD')}}p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.22.1/moment.js">script>
<script>
  // 定义过滤器
  Vue.filter('dateString', function (value, format='YYYY-MM-DD HH:mm:ss') {
    return moment(value).format(format);
  })
  
  new Vue({
    el: '#test',
    data: {
      time: new Date()
    },
    mounted () {
      setInterval(() => {
        this.time = new Date()
      }, 1000)
    }
  })
script>
body>
html>

指令 ※


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>12_指令_内置指令title>
  <style>
    [v-cloak] { display: none }
  style>
head>
<body>

<div id="example">
  <p v-cloak>{{content}}p>
  <p v-text="content">p>   
  <p v-html="content">p>  

  <p ref="msg">abcdp>
  <button @click="hint">提示button>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#example',
    data: {
      content: '百度一下'
    },
    methods: {
      hint () {
        alert(this.$refs.msg.innerHTML)
      }
    }
  })
script>
body>
html>

在这里需要说一下v-cloak:其实这些指令有一种特性就是:就是在页面被解析后,这些指令就消失了,如下图所示。而v-cloak正是用了这样的特性,在没被解析之前,因为这个指令的存在,设置了css样式display:none,所以指定的标签就不会出现,当页面被解析后,因为指令的消失从而让标签内容出现。
①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第10张图片
为什么需要这么用?当你去掉v-cloak后,如果你第一次进网页(网页还没被解析时),你会看到它的表达式形式,即:{{content}}。正常看大家可能看不出效果,可以在新建Vue对象前,加一个alert,看一下效果。也就是说,为了避免这种情况,我们就可以使用v-cloak
①Vue介绍及基本用法(模板语法、计算属性和监视、条件渲染、列表渲染、列表搜索和排序、事件处理、表单输入绑定、生命周期、动画、过滤器、指令)_第11张图片


自定义指令 ※

显然,Vue提供的指令可能不能满足所有需求,所以自定义指令的存在就格外重要了。


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>12_指令_自定义指令title>
head>
<body>


<div id="test">
  <p v-upper-text="msg">p>
  <p v-lower-text="msg">p>
div>

<div id="test2">
  <p v-upper-text="msg">p>
  <p v-lower-text="msg">p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  // 注册一个全局指令
  // el: 指令所在的标签对象
  // binding: 包含指令相关数据的容器对象
  Vue.directive('upper-text', function (el, binding) {
    console.log(el, binding)
    el.textContent = binding.value.toUpperCase()
  })
  new Vue({
    el: '#test',
    data: {
      msg: "I Like You"
    },
    // 注册局部指令
    directives: {
      'lower-text'(el, binding) {
        console.log(el, binding)
        el.textContent = binding.value.toLowerCase()
      }
    }
  })
  new Vue({
    el: '#test2',
    data: {
      msg: "I Like You Too"
    }
  })
script>
body>
html>

做一个简单插件

以后当我们想用其他人的插件的时候,就也需要用Vue.use()


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>17_插件title>
head>
<body>

<div id="test">
  <p v-my-directive="msg">p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript" src="vue-myPlugin.js">script>
<script type="text/javascript">
  // 声明使用插件(安装插件: 调用插件的install())
  Vue.use(MyPlugin) // 内部会调用插件对象的install()

  const vm = new Vue({
    el: '#test',
    data: {
      msg: 'HaHa'
    }
  })
  Vue.myGlobalMethod()
  vm.$myMethod()
script>
body>
html>

vue-myPlugin.js

(function (window) {
  const MyPlugin = {}
  MyPlugin.install = function (Vue, options) {
    // 1. 添加全局方法或属性
    Vue.myGlobalMethod = function () {
      console.log('Vue函数对象的myGlobalMethod()')
    }

    // 2. 添加全局资源
    Vue.directive('my-directive',function (el, binding) {
      el.textContent = 'my-directive----'+binding.value
    })

    // 3. 添加实例方法
    Vue.prototype.$myMethod = function () {
      console.log('vm $myMethod()')
    }
  }
  window.MyPlugin = MyPlugin
})(window)

你可能感兴趣的:(#,Vue)