vue, 这一篇就够了

257 阅读6分钟
v-text v-cloak

v-text 等价于 {{}} 用于显示内容,但区别在于{{}} 会造成闪烁问题, v-text 不会闪烁 如果还想用 {{}} 又不想有闪烁问题,则使用 v-cloak 来处理, 步骤如下: 在被 Vue 管理的模板入口节点上作用 v-cloak 指令 添加一个属性选择器 [v-cloak] 的CSS 隐藏样式: [v-cloak] {display: none;} 原理:默认一开始被 Vue 管理的模板是隐藏着的,当 Vue 解析处理完 DOM 模板之后,会自动把这个样式去 除,然后就显示出来。

<style>
        /* 将带有 v-clock 属性的标签隐藏 */
        [v-clock] {
            display: none
        }
    </style>
</head>
<body>
    <div id="app" v-clock>
        <!-- v-pre
        1. 用于显示双大括号{{}}
        2. 跳过这个元素和它的子元素的编译过程,这样可以提高性能。 -->
        <span v-pre>{{您好!}}</span>

        <!-- 使用双大括号,会有双括号 {{}} 闪烁出来。
        可以通过 v-text进行解决闪烁问题
            
        如果我就需要使有双大括号,又不想让它有{{}} 闪烁出来
        -->
        <h3>{{message}}</h3>
        <h3>{{message}}</h3>
        <h3>{{message}}</h3>
        <h3 v-text="message"></h3>
        <h3 v-text="message"></h3>
        <h3 v-text="message"></h3>

    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'hello word.....'
            }
        })
    </script>
</body>
计算属性computed

computed 选项定义计算属性 计算属性 类似于 methods 选项中定义的函数

  • 计算属性 会进行缓存,只在相关响应式依赖发生改变时它们才会重新求值。
  • 函数 每次都会执行函数体进行计算。

需求:输入数学与英语分数,采用 methods 与 computed 分别计算出总得分

<body> 
<div id="app">
 数学:<input type="text" v-model="mathScore" >
 英语:<input type="text" v-model="englishScore">
 总分(方法-单向):<input type="text" v-model="sumScore()"> 
 总分(计算属性-单向):<input type="text" v-model="sumScore1"> 
</div> 
<script src="./node_modules/vue/dist/vue.js"></script> 
<script type="text/javascript"> 
 var vm = new Vue({
     el: '#app',
     data: {
            mathScore: 80, 
            englishScore: 90, 
            },
     methods: { //不要少了s 
            sumScore: function () { 
            //在控制台输入 vm.sumScore() 每次都会被调用
            console.info('sumScore被调用') 
            // `this` 指向当前 vm 实例, 减 0 是为了字符串转为数字运算
            return (this.mathScore-0) + (this.englishScore-0) 
           }
         },
     computed: { //计算属性 
           sumScore1 : function () { 
           //在控制台输入vm.sumScore1 不会被重新调用,说明计算属性有缓存
                console.info('sumScore1被调用') 
                return (this.mathScore - 0) + (this.englishScore -0) 
         } 
       } 
     }) 
  </script> 
</body> 

computed 选项内的计算属性默认是 getter 函数,所以上面只支持单向绑定,当修改数学和英语的数据才会 更新总分,而修改总分不会更新数据和英语

计算属性双向绑定

计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter

<body> 
<div id="app"> 
数学:<input type="text" v-model="mathScore" ><br> 
英语:<input type="text" v-model="englishScore"><br> 
总分(方法-单向):<input type="text" v-model="sumScore()"><br> 
总分(计算属性-单向):<input type="text" v-model="sumScore1"><br>
总分(计算属性-双向):<input type="text" v-model="sumScore2"><br>
</div> 
<script src="./node_modules/vue/dist/vue.js"></script> 
<script type="text/javascript"> 
var vm = new Vue({ 
  el: '#app',
  data: {
     mathScore: 80, 
     englishScore: 90, 
     },
  methods: { //不要少了s 
     sumScore: function () { 
     //在控制台输入 vm.sumScore() 每次都会被调用
         console.info('sumScore被调用') 
         // `this` 指向当前 vm 实例, 减 0 是为了字符串转为数字运算 
         return (this.mathScore-0) + (this.englishScore-0) 
       } 
     },
  computed: { 
   //计算属性 默认 getter 只支持单向绑定 
     sumScore1: function(){
      //在控制台输入vm.sumScore1 不会被重新调用,说明计算属性有缓存
       console.info('sumScore1被调用') 
       return (this.mathScore - 0) + (this.englishScore -0) 
     },
     //指定 getter/setter 双向绑定 
     sumScore2 : { 
       get: function() {
        console.info('sumScore2被调用') 
        return (this.mathScore-0) + (this.englishScore-0) 
       }, 
       set: function(newValue) {//value为更新后的值 
       // 被调用则更新了sumScore2,然后将数学和英语更新为平均分
        var avgScore = newValue / 2 
        this.mathScore = avgScore 
        this.englishScore = avgScore 
       } 
      } 
     } 
   }) 
  </script> 
</body> 
监听器watch

当属性数据发生变化时,对应属性的回调函数会自动调用, 在函数内部进行计算 通过 watch 选项 或者 vm 实例的 $watch() 来监听指定的属性

需求:

  1. 通过 watch 选项 监听数学分数, 当数学更新后回调函数中重新计算总分sumScore3
  2. 通过 vm.$watch() 选项 监听英语分数, 当英语更新后回调函数中重新计算总分sumScore3

注意: 在data 选择中添加一个 sumScore3 属性

<body>
 <div id="app">
   数学:<input type="text" v-model="mathScore" ><br> 
   英语:<input type="text" v-model="englishScore"><br>
   总分(方法-单向):<input type="text" v-model="sumScore()"><br>
   总分(计算属性-单向):<input type="text" v-model="sumScore1"><br>  
   总分(计算属性-双向):<input type="text" v-model="sumScore2"><br> 
   总分(监听器):<input type="text" v-model="sumScore3"><br> 
 </div>
  <script src="./node_modules/vue/dist/vue.js"></script> 
  <script type="text/javascript"> 
     var vm = new Vue({
      el: '#app',
      data: {
          mathScore: 80,
           englishScore: 90,
            sumScore3: 170 
          },
      methods: { //不要少了s 
         sumScore: function () { 
         //在控制台输入 vm.sumScore() 每次都会被调用
           console.log('sumScore被调用')
         // `this` 指向当前 vm 实例, 减 0 是为了字符串转为数字运算 
           return (this.mathScore - 0) + (this.englishScore -0) 
         } 
       },
       // 计算属性
      computed: { 
      // 默认 getter 只支持单向绑定 
      sumScore1 : function () { 
      //在控制台输入 vm.sumScore1 不会被重新调用 ,说明计算属性有缓存
        console.log('sumScore1被调用')
        return (this.mathScore - 0) + (this.englishScore -0) 
      },
      //指定 getter/setter 双向绑定 
      sumScore2 : { 
        get: function () {
             console.log('sumScore2被调用') 
             return (this.mathScore-0) + (this.englishScore-0) 
            }, 
        set: function (newValue) {//value为更新后的值 
        // 被调用则更新了sumScore2,然后将数学和英语更新为平均分 
             var avgScore = newValue / 2 
             this.mathScore = avgScore 
             this.englishScore = avgScore 
           }
         } 
      },
      //监听器方式1:watch选项 
      watch : { 
      //当数学修改后,更新总分sumScore3
        mathScore : function (newValue, oldValue) { 
        //newValue 就是新输入的数学得分 
        this.sumScore3 = (newValue-0) + (this.englishScore-0)
      } 
    }
  })
  //监听器方式2:通过vm对象调用 
  //第1个参数为监听的属性名,第2个回调函数 
  vm.$watch('englishScore', function (newValue) { 
  //newValue 就是新输入的英语得分 
    this.sumScore3 = (newValue-0) + (this.mathScore-0) 
 }) 
 </script> 
</body>             
Class与Style绑定v-bind

通过 class 列表和 style 指定样式是数据绑定的一个常见需求。它们都是元素的属性,都用 v-bind 处理,其中表达 式结果的类型可以是:字符串、对象或数组。

语法格式 v-bind:class='表达式':class='表达式'

class 的表达式可以为:

  • 字符串 :class="activeClass"
  • 对象 :class="{active: isActive, error: hasError}"
  • 数组 :class="['active', 'error']" 注意要加上单引号,不然是获取data中的值

v-bind:style='表达式':style='表达式'

style 的表达式一般为对象
:style="{color: activeColor, fontSize: fontSize + 'px'}" ==注意:对象中的value值 activeColor 和 fontSize 是data中的属性==

<body>
 <!-- 第2步:定义样式 -->
  <style>
   .active {
      color: green; }
   .delete {
      background: red; }
   .error { 
      font-size: 30px;
    } 
  </style> 
  <div id="app"> 
   <h2>Class绑定,v-bind:class 或 :class</h2> 
   <!--activeClass会从data中获取值为active,则对应样式为绿色--> 
   <p v-bind:class="activeClass">字符串达式</p> 
  
   <!-- isDelete为 true,渲染delete样式;当 hasError为false,不取 error 样式;--> 
   <p :class="{delete: isDelete, error: hasError}">对象表达式</p> 

 <!--- 渲染 'active', 'error' 样式,注意要加上单引号,不然是获取data中的值 --> 
   <p :class="['active', 'error']">数组表达式</p> 
   
   <h2>Style绑定, v-bind:style 或 :class</h2> 
   <p :style="{color: activeColor, fontSize: fontSize + 'px'}">Style绑定</p> 

 </div> 
 <script src="./node_modules/vue/dist/vue.js"></script> 
 <script type="text/javascript"> 
   new Vue({
    el: '#app',
    data: { 
      activeClass: 'active',
      isDelete: true,
      hasError: false,
      //演示 Style绑定 
      activeColor: 'red', 
      fontSize: 20 
     } 
   })
 </script> 
</body>
条件渲染v-if

条件指令 v-if 是否渲染当前元素 v-else v-else-if v-showv-if 类似,只是元素始终会被渲染并保留在 DOM 中,只是简单切换元素的 CSS 属性 display 来显示或隐藏

<body>
 <style>
   .box {
     width: 200px; 
     height: 200px;
     background: red;
   }
 </style>
 <div id="app">
  <h2>v-if 条件渲染</h2> 
  <input v-model="seen" type="checkbox" >勾选后显示红色小块 
  <!-- v-if 为 true则显示渲染当前元素, -->
   <div v-if="seen" class="box" ></div> 
   <p v-else="seen">红块已隐藏</p> 

   <h2>v-show 条件渲染</h2> 
   <!-- v-show 的元素始终会被渲染并保留在 DOM 中,
   只是简单切换元素的 CSS 属性 display 显示隐藏,而不是重新加载div--> 
   <div v-show="seen" class="box" ></div> 
 </div> 
   <script src="./node_modules/vue/dist/vue.js"></script> 
   <script type="text/javascript">
     var vm = new Vue({
      el: '#app',
      data: {
       seen: false
      } 
    }) 
   </script>
</body>
v-if 与 v-show 比较

什么时候元素被渲染 v-if 如果在初始条件为假,则什么也不做,每当条件为真时,都会重新渲染条件元素 v-show 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换

使用场景选择 v-if 有更高的切换开销, v-show 有更高的初始渲染开销。 因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行后条件很少改变,则使用 v-if 较好。

列表渲染 v-for

列表渲染指令 v-for 迭代数组 语法: v-for="(alias, index) in array" 说明: alias : 数组元素迭代的别名; index : 数组索引值从0开始(可选) 。

<div v-for="item in items" :key="item.id"></div> 
<div v-for="(item, index) in items" :key="item.id"></div> 

items 是源数据数组, item 是数组元素迭代的别名。 ==注意:使用 key 特殊属性, 它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素==

v-for 迭代对象的属性 语法: v-for="(value, key, index) in Object" 说明: value : 每个对象的属性值; key : 属性名(可选); index : 索引值(可选) 。

<div v-for="value in object" ></div> 
<div v-for="(value, key) in object"></div> 
<div v-for="(value, key, index) in object"></div>

注意: 在遍历对象时,是按 Object.keys() 的结果遍历,但不能保证它的结果在不同的 JavaScript 引擎下是顺序一致的。

可用 of 替代 in 作为分隔符

<body>
 <div id="app">
  <h2>1. 迭代数组</h2>
   <ul>
     <!-- e 为当前对象别名,index 数组下标0开始-->
     <li v-for="(e, index) in emps" :key="index">
      编号:{{index+1}},姓名:{{e.name}},工资:{{e.salary}} 
     </li>
   </ul> 
   <br> 
   <h2>2. 迭代对象</h2> 
   <ul>
     <!-- value是属性值,key是属性名,index索引值--> 
     <li v-for="(value, key, index) in emps[0]">
      第{{index+1}}个属性为:{{key}} = {{value}}
     </li>
   </ul> 
 </div>
 <script src="./node_modules/vue/dist/vue.js"></script> 
 <script type="text/javascript">
   var vm = new Vue({
    el: '#app',
    data: {
      emps:[ //数组
        {name: '马云', salary: '20000'}, 
        {name: '马化腾', salary: '18000'}, 
        {name: '刘强东', salary: '13000'}
       ] 
     } 
   }) 
 </script> 
</body>
事件处理 v-on

事件处理方法 完整格式: v-on:事件名="函数名"v-on:事件名="函数名(参数……)" 缩写格式: @事件名="函数名"@事件名="函数名(参数……)" ==注意: @ 后面没有冒号==

event :函数中的默认形参,代表原生 DOM 事件 当调用的函数,有多个参数传入时,需要使用原生DOM事件,则通过 $event 作为实参传入 作用:用于监听 DOM 事件

<body>
 <div id="app">
   <h2>1. 事件处理方法</h2> 
   <button @click="say">Say {{msg}}</button> 
   <button @click="warn('hello', $event)">Warn</button>
 </div> 
 <script src="./node_modules/vue/dist/vue.js"></script> 
 <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
         msg: 'Hello, Vue.js'
       },
      methods: { 
         say: function (event) {
           // `this` 在方法里指向当前 Vue 实例 
           alert(this.msg) 
           // `event` 是原生 DOM 事件 
           alert(event.target.innerHTML)
         },
         //多个参数如果需要使用原生事件,将 $event 作为实参传入 
         warn: function (msg, event) { 
           alert(msg + "," + event.target.tagName) 
          } 
        } 
      })
 </script> 
</body>
事件修饰符

.stop 阻止单击事件继续传播 event.stopPropagation() .prevent 阻止事件默认行为 event.preventDefault() .once 点击事件将只会触发一次

<body>
 <div id="app">
  <h2>1. 事件处理方法</h2>
  <button @click="say">Say {{msg}}</button>
  <button @click="warn('hello', $event)">Warn</button> 
  <br>
 
  <h2>2. 事件修饰符</h2> 
  <!--单击事件继续传播--> 
  <div @click="todo"> 
    <!--点击后会调用doThis再调用todo--> 
    <button @click="doThis">单击事件会继续传播</button> 
  </div> 
  <br/> 
  <!-- 阻止单击事件继续传播,--> 
  <div @click="todo"> 
    <!--点击后只调用doThis--> 
    <button @click.stop="doThis">阻止单击事件会继续传播</button> 
  </div> 
  
  <!-- 阻止事件默认行为 --> 
  <a href="http://www.baidu.com" @click.prevent="doStop">百度</a>
  
  <!-- 点击事件将只会触发一次 --> 
  <button @click.once="doOnly">点击事件将只会触发一次: {{num}}</button> 
</div> 
<script src="./node_modules/vue/dist/vue.js"></script> 
<script type="text/javascript"> 
   var vm = new Vue({
      el: '#app',
      data: {
        msg: 'Hello, Vue.js',
        num: 1 
      },
      methods: {
        say: function (event) {
           // `this` 在方法里指向当前 Vue 实例 
           alert(this.msg) 
           // `event` 是原生 DOM 事件 
           alert(event.target.innerHTML) 
        },
        //多个参数如果需要使用原生事件,将 $event 作为实参传入 
        warn: function (msg, event) {
           alert(msg + "," + event.target.tagName)
        },
        todo: function () {
           alert("todo...."); 
        },
        doThis: function () {
           alert("doThis....");
        },
        doStop: function () {
           alert("href默认跳转被阻止....")
        },
        doOnly: function() {
           this.num++ 
        } 
      } 
    }) 
 </script> 
</body> 
按键修饰符

格式: v-on:keyup.按键名@keyup.按键名 常用按键名: .enter .tab .delete (捕获“删除”和“退格”键) .esc .space .up .down .left .right

<body>
    <div id="app">
        <h3>1. 事件处理方法 v-on 或 @</h3>
        <button v-on:click="say">Say {{msg}}</button>
        <!-- $event代表的是原生 的Dom事件 -->
        <button @click="warn('hello', $event)">Warn</button>


        <h3>2. 事件修饰符</h3>
        <!-- 2.1 防止单击事件继续传播 -->
        <div @click="todo">
            <button @click="doThis">单击事件会继续传播</button>
        </div>
        <br>
        <div @click="todo">
            <!-- .stop作用:是阻止事件的传播 -->
            <!--点击后只调用doThis-->
            <button @click.stop="doThis">阻止单击事件会继续传播</button>
        </div>
        <br>

        <!-- 2.2 阻止事件的默认行为 -->
        <a href="https://cn.vuejs.org/" @click.prevent="doStop">vue官方文档</a>

        <!-- 2.3 点击事件只会触发一次 -->
        <button @click.once="doOnly">点击事件只会触发一次:{{num}}</button>

        <br>

        <h3>3. 按键修饰符或按键码</h3>
        <input type="text" @keyup.enter="keyEnter"><!--进入输入框按回车时调用keyEnter-->
        <input type="text" @keyup.space="keySpace"><!--进入输入框按回车时调用keySpace-->

        <input type="text" @keyup.13="keyCode">
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'Hello word!!',
                num: 0
            },
            methods: { //定义事件处理函数
                say: function (event) {
                    // event代表的是Dom原生事件, Vue.js它会自动 的将它传入进来,
                    // `this` 在方法里指向当前 Vue 实例
                    alert(this.msg)
                    alert(event.target.innerHTML)
                },
                warn: function (name, event) {
                    //如果说函数有多个参数,而双需要使用原生事件,则需要使用 $event 作为 参数传入
                    alert(name + ',' + event.target.tagName)
                },
                doThis: function () {
                    alert('doThis....')
                },
                todo: function () {
                    alert('todo....')
                },
                doStop: function () {
                    alert('doStop...href默认行为已经被阻止')
                },
                doOnly: function () {
                    this.num ++ 
                },
                keyEnter: function () {
                    alert('当前按的是回车键')
                },
                keySpace: function() {
                    alert('当前按的是空格键')
                },
                keyCode: function () {
                    alert('按的是13')
                }
            },
        })
    
    </script>
</body>
表单数据双向绑定v-model
  • 单向绑定:数据变,视图变;视图变(浏览器控制台上更新html),数据不变;上面的都是单向绑定
  • 双向绑定:数据变,视图变;视图变(在输入框更新),数据变;

基础用法 v-model 指令用于表单数据双向绑定,针对以下类型: text 文本 textarea 多行文本 radio 单选按钮 checkbox 复选框 select 下拉框

<body>
  <div id="demo">
        <!-- @submit.prevent 阻止事件的默认行为,当前阻止的是action行为 -->
    <form action="#" @submit.prevent="submitForm">
        姓名(文本):<input type="text" v-model="name">
        <br><br>

        性别(单选按钮):
            <input name="sex" type="radio" value="1" v-model="sex"/><input name="sex" type="radio" value="0" v-model="sex"/><br><br>

        技能(多选框):
            <input type="checkbox" name="skills" value="java" v-model="skills">Java开发
            <input type="checkbox" name="skills" value="vue" v-model="skills">Vue.js开发
            <input type="checkbox" name="skills" value="python" v-model="skills">Python开发
        <br><br>

        城市(下拉框):
        <select name="citys" v-model="city">
            <option v-for="c in citys" :value="c.code">
                {{c.name}}
            </option>
        </select>
        <br><br>

        说明(多行文本):<textarea cols="30" rows="5" v-model="desc"></textarea>
        <br><br>
        <button type="submit" >提交</button>
    </form>
</div>

<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#demo',
        data: {
            name: '',
            sex: '1',   //默认选中的是 男
            skills: ['vue', 'python'], //默认选中 Vue.js开发 、Python开发
            citys: [//初始化下拉框
                {code: 'bj', name: '北京'},
                {code: 'sh', name: '上海'},
                {code: 'gz', name: '广州'}
            ],
            city: 'sh', // 默认选中的城市:上海
            desc: ''
        },
        methods: {
            submitForm: function () { //处理提交表单
                //发送ajax异步处理
                alert(this.name + ', ' + this.sex + ', ' + this.skills +  ', ' + this.city + ', ' + this.desc)
            }
        }
    })
  </script>
</body>
过渡&动画效果

什么是过渡&动画 元素在显示和隐藏时,实现过滤或者动画的效果。

常用的过渡和动画都是使用 CSS 来实现的

  • 在 CSS 中操作 trasition (过滤 )或 animation (动画)达到不同效果
  • 为目标元素添加一个父元素 , 让父元素通过自动应用 class 类名来达到效果

过渡与动画时,会为对应元素动态添加的相关 class 类名:

  1. xxx-enter :定义显示前的效果。
  2. xxx-enter-active :定义显示过程的效果。
  3. xxx-enter-to : 定义显示后的效果。
  4. xxx-leave : 定义隐藏前的效果。
  5. xxx-leave-active :定义隐藏过程的效果。
  6. xxx-leave-to :定义隐藏后的效果。
过滤效果案例

1.为目标元素添加父元素 <transition name="xxx"> 2.定义 class 过渡样式

  • 指定过渡样式: transition
  • 指定隐藏时的样式: opacity(持续的时间)/其它

3.功能实现 点击按钮后, 显示隐藏文本 效果1:显示和隐藏有渐变效果 效果2:显示和隐藏的有平移效果,并持续时长不同

    <style>
        /* 显示或隐藏的过渡效果 */
        .mxg-enter-active, .mxg-leave-active {
             transition: opacity 1s; /*过渡:渐变效果持续时长1秒 */
        }
        /* 显示前或隐藏后的效果 */
        .mxg-enter, .mxg-leave-to {
             opacity: 0; /* 都是隐藏效果 */
        }

        /* 可以针对显示和隐藏指定不同的效果 */
        /* 显示过渡效果 1秒 */
        .meng-enter-active {
            transition: all 1s; /*all 所有效果,持续1秒*/
        }
        /* 隐藏过渡效果 5秒 */
        .meng-leave-active {
            transition: all 5s; /*all 所有效果,持续5秒*/
        }

        /* 显示前或隐藏后的效果 */
        .meng-enter, .meng-leave-to {
             opacity: 0; /* 都是隐藏效果 */
             transform: translateX(10px); /*水平方向 移动 10px*/
        }
    </style>
</head>
<body>
    <div id="app1">
        <button @click="show = !show">渐变过渡</button>
        <transition name="mxg">
            <p v-show="show" >mengxuegu</p>
        </transition>
    </div>

    <div id="app2">
            <button @click="show = !show">渐变平滑过渡</button>
            <transition name="meng">
                <p v-show="show" >vue</p>
            </transition>
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app1',
            data: {
                show: true
            }
        })

        new Vue({
            el: '#app2',
            data: {
                show: true
            }
        })
    </script>
</body>
动画效果案例

CSS 动画用法同 CSS 过渡,只不过采用 animation 为指定动画效果 功能实现: 点击按钮后, 文本内容有放大缩小效果

==注意:官网上面源码有问题,要在 <p> 元素上增加样式 style="display: inline-block"==

    <style>
        /* 显示过程中的动画效果 */
        .bounce-enter-active {
            animation: bounce-in 1s;
        }
        /* 隐藏过程中的动画效果 */
        .bounce-leave-active {
            animation: bounce-in 1s reverse;
        }

        @keyframes bounce-in {
            0% { /*持续时长百分比,比如针对1s: 0%代表0秒,50%代表0.5*/
                transform: scale(0); /*缩小为0*/
            }

            50% {
                transform: scale(1.5); /*放大1.5倍*/
            }

            100% {
                transform: scale(1); /*原始大小*/
            }
        }
    </style>
</head>

<body>
    <div id="demo">
        <button @click="show = !show">放大缩小动画</button>
        <transition name="bounce">
            <p v-show="show" >vuejs</p>
        </transition>
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#demo',
            data: {
                show: true
            }
        })
    </script>
</body>
自定义指令

自定义指令的作用 除了内置指令外,Vue 也允许注册自定义指令。有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候使用自定义指令更为方便。 自定义指令文档: cn.vuejs.org/v2/guide/cu…

注册与使用自定义指令方式 1.注册全局指令

// 指令名不要带 v- 
Vue.directive('指令名', {
 // el 代表使用了此指令的那个 DOM 元素 
 // binding 可获取使用了此指令的绑定值 等 
  inserted: function (el, binding) {
   // 逻辑代码 
  }
})

2.注册局部指令

directives : {
  '指令名' : { // 指令名不要带 v-
      inserted (el, binding) {
        // 逻辑代码 
      } 
   } 
}

注意:注册时,指令名不要带 v-

3.使用指令: 引用指令时,指令名前面加上 v- 直接在元素上在使用即可 : v-指令名='表达式'

案例演示 需求: 1.实现输出文本内容全部自动转为大写,字体为红色 ( 功能类型于 v-text , 但显示内容为大写) 2. 当页面加载时,该元素将获得焦点 (注意: autofocus 在移动版 Safari 上不工作)

<body>
<div id="app">
    <p v-upper-text="message">xxxxx</p>
    自动获取焦点:<input type="text" v-focus>
</div>
<div id="app2">
    <p v-upper-text="msg">xxxxx</p>
    
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    // 注册全局自定义指令,可以在多个Vue管理的入口下使用该指令
    // 第一个参数为指令名,但是不要有v-开头
    // 注册一个全局 v-upper-text 指令
    Vue.directive('upper-text',{
        //一般对样式 的操作在bind中,bind函数只调用一次 
        //因为是样式,所以不需要元素插入到DOM中,就好像link引入CSS文件时并不关心元素是否加载
        bind: function (el) {
            el.style.color = 'red'
        },
        //一般对js操作在inserted中,inserted也是只调用一次
        // el 代表使用了此指令的那个 DOM 元素
        // binding用于获取使用了当前指令的绑定值(value)、表达式(expression)、指令名(name)等
        inserted: function (el, binding) {
            // 将在 v-upper-text 指令中获取到的值,变成大写输出到标签体中
            el.innerHTML = binding.value.toUpperCase()
        }
    })

    new Vue({
        el: '#app',
        data: {
            message: '渐进式JavaScript 框架 '
        },
        //注册局部自定义指令:只能在当前Vue实例管理的入口 下引用这个指令
        directives: {//注册一个局部指令 v-focus
            'focus': { // 指令名,
                bind: function () {

                },
                //和js行为有关的操作,最好在inserted中执行,和样式相关的操作都可在bind中执行
                // 刷新页面自动获取焦点
                inserted: function (el, binding) {
                    //被 v-focus 作用的那个元素在刷新页面后会自动 获取焦点
                    el.focus()
                }
            }
        }
    })
</script>
</body>
Vue 组件化开发

template:定义组件的视图模板

data :在组件中必须是一个函数

Vue.component('组件名',{

template: '定义组件模板',

data: function(){ //data 选项在组件中必须是一个函数

return {}

}

//其他选项:methods

})

<body>

<div id="app">

<!-- 通过组件名直接使用, 不能使用驼峰形式 -->

<component-a></component-a>

</div>

<script src="node_modules/vue/dist/vue.js" type="text/javascript"></script>

<script type="text/javascript">

Vue.component('component-a', {

// template 选项指定此组件的模板代码

template: '<div><h1>头部组件 - {{ name }}</h1></div>',

// data 必须是函数

data: function () {

return {

name: '全局组件'

}

}

})

new Vue({

el: '#app'

})

</script>

</body>

1. JS 对象来定义组件:

var ComponentA = { data: function(){},

template: '组件模板A'}

var ComponentA = { data: function(){},

template: '组件模板A'}
    

2. 在Vue实例中的 components 选项中引用组件:

new Vue({

el: '#app',

data: {},

components: { // 组件选项

'component-a': ComponentA // key:组件名,value: 引用的组件对象

'component-b': ComponentB

}

})


组件是可复用的 Vue 实例,不需要手动实例化

与 new Vue 接收相同的选项,例如 data 、 computed 、 watch 、 methods 等

组件的 data 选项必须是一个函数

<body>

<div id="app">

<!-- 通过组件名直接使用, 不能使用驼峰形式 -->

<component-b ></component-b>

</div>

<script src="node_modules/vue/dist/vue.js" type="text/javascript"></script>

<script type="text/javascript">

// 定义局部组件对象

var ComponentB = {

template: '<div> 这是:

{{ name }}</div>',

data: function () {

return {

name: '局部组件'

}

}

}

new Vue({

el: '#app',

components: { // 局部组件

'component-b': ComponentB

}

})

</script>

</body>


页面引入组件 js 文件后, 进行使用

Header.js 文件内容

Vue.component('app-header',{

// template 选项指定此组件的模板代码

template: '<div class="header"><h1>头部组件</h1></div>'

})

Main.js 文件内容

Vue.component('app-main',{

// template 选项指定此组件的模板代码

template: '<div class="main"><ul><li>客户管理</li><li>帐单管理</li><li>供应商管理</li></ul><h3></h3>

</div>'

})

Footer.js 文件内容

Vue.component('app-footer',{

// template 选项指定此组件的模板代码

template: '<div class="footer"><h1>底部组件</h1></div>'

})

<body>

<div id="app">

<!-- 通过组件名直接使用 -->

<app-header></app-header>

<app-main></app-main>

<app-footer></app-footer>