zoukankan      html  css  js  c++  java
  • Vue入门---安装及常用指令介绍

    1、安装

    1. BootCDN----官网https://www.bootcdn.cn/
      <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
      //或者
      <script src="https://unpkg.com/vue/dist/vue.js"></script>
    2. npm
      npm i vue --save-dev
    3. bower
      bower i vue --save-dev

    2、数据绑定

    • 语法:采用了 “Mustache” 语法(标签) ----- 即 “文本插值” ----- {{ }}(双大括号)

    3、指令

    • 定义:v-*,其值限定为绑定表达式
    • 作用:当表达式值变化的时候,可以将变化反应到DOM上
    • 内部指令:
      • v-if:根据表达式的值在DOM中生成或移除一个元素(false:不渲染对应元素;true:渲染元素,将对应元素的克隆插入DOM中)----- 真正的 “条件渲染”
        • 当为true时:
          <template>
              <div class="text">
                  <p v-if="isSee">{{text}}</p>
              </div>
          </template>
          <script>
          export default {
              name : "test",
              data(){
                  return{
                      text : "你可以看到我吗?",
                      isSee : true,
          
                  }
              },
          
          }
          </script>
          <style lang="scss" scoped>
          
          </style>
          View Code

          结果为:

                                   

        • 当为false时:
          <template>
              <div class="text">
                  <p v-if="isSee">{{text}}</p>
              </div>
          </template>
          <script>
          export default {
              name : "test",
              data(){
                  return{
                      text : "你可以看到我吗?",
                      isSee : false,
          
                  }
              },
          
          }
          </script>
          <style lang="scss" scoped>
          
          </style>
          View Code

          结果为:

                               

      • v-show:根据表达式的值显示或者隐藏HTML元素(false:元素隐藏,内联样式出现 style="dispaly:none" )
        • 当为true时:
          <template>
              <div class="text">
                  <p v-show="isSee">{{text}}</p>
              </div>
          </template>
          <script>
          export default {
              name : "test",
              data(){
                  return{
                      text : "这次是隐藏还是显示?",
                      isSee : true,
          
                  }
              },
          
          }
          </script>
          View Code

          结果为:

        • 当为false时:
          <template>
              <div class="text">
                  <p v-show="isSee">{{text}}</p>
              </div>
          </template>
          <script>
          export default {
              name : "test",
              data(){
                  return{
                      text : "这次是隐藏还是显示?",
                      isSee : false,
          
                  }
              },
          
          }
          </script>
          View Code

          结果为:

                                   

        • v-if与v-show的区别:
          • v-if是惰性的,如果初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块(局部编译,编译会被缓存起来);

                                         相比之下v-show 就简单得多——不管初始条件是什么,元素始终被编译并保留,只是简单地基于 CSS 进行切换;

                                         总结:一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好

            • v-if支持<template>语法,可以切换多个元素,并且不会被渲染到DOM结构上;而v-show不支持<template>语法;
        • v-else:必须跟着v-if或者v-show,或者不会被识别
          <template>
              <div class="text">
                  <p v-if="age > 18">成年了</p>
                  <p v-else>未成年</p>
              </div>
          </template>
          <script>
          export default {
              name : "test",
              data(){
                  return{
                      age : 10
          
                  }
              },
          
          }
          </script>
          View Code

          结果为:未成年

        • v-model:用来在input、select、checkbox等表单控件上创建 “双向数据绑定”(例如element-ui中的表单数据绑定)
          • 修饰符
            • number:用户输入的转换为Number类型,如果原值为NaN就返回原值
            • lazy:失去焦点时数据才改变,相当于input的change事件(点击回车)
            • trim:去掉前后的空格
            • debounce:设置一个最小的延时,是更新发生在延时之后(防止input每次输入数据都发送AJAX请求)单位ms(只存在于Vue1.x中,其他版本已经移除)
        • v-for:基于源数据重复渲染元素
        • 遍历数组:item  in/of items 的形式
          <template>
              <div class="text">
                  <ul>
                    <li v-for="(tap,tapIndex) of taps" :key="tapIndex">{{tapIndex}}---{{tap}}</li>
                  </ul>
              </div>
          </template>
          <script>
          export default {
              name : "test",
              data(){
                  return{
                    taps : ["西红柿","冬瓜","茄子"]
                  }
              },
          
          }
          </script>
          View Code

          结果为:

                                           

          • 遍历对象  (Object.keys()的结果进行遍历)
            <template>
              <div class="text">
                <ul>
                  <li v-for="(value,key,index) of Person" :key="index">{{index}}---{{key}}---{{value}}</li>
                </ul>
              </div>
            </template>
            <script>
            export default {
              name: "test",
              data() {
                return {
                  Person: {
                    name: "Jane Doe",
                    age: "22",
                    sex: ""
                  }
                };
              },
              methods: {}
            };
            </script>
            View Code

            结果为:

                                               

        • v-text(相当于插值表达式)
          <template>
            <div class="text">
              <p v-text="text"></p>
              <p>{{text}}</p>
            </div>
          </template>
          <script>
          export default {
            name: "test",
            data() {
              return {
               text : "插值表达式"
              };
            },
            methods: {}
          };
          </script>
          View Code

          结果为:

                                    

        • v-html(渲染html标签)Vue1.x版本的{{{ html标签表达式}}}写法已经被移除
          <template>
            <div class="text">
              <p>我是原来的p标签</p>
              <!-- <div>{{{text}}}</div> -->
              <div v-html="text"></div>
            </div>
          </template>
          <script>
          export default {
            name: "test",
            data() {
              return {
               text : "<p>我是新来的p标签</p>"
              };
            },
            methods: {}
          };
          </script>
          View Code

          结果为:

                                   

        • v-bind(可以简写为 “:”)绑定表达式到标签的属性上,常绑定属性有class、style、src等
          • 绑定class支持变量
            <template>
              <div id="example">
                <p :class="classA ? 'ok' : 'not'">绑定表达式</p>
              </div>
            </template>
            <script>
            export default {
              name: "example",
              data() {
                return {
                 classA : true
                };
              },
              methods: {}
            };
            </script>
            View Code

            结果为:      

                                             

          • 绑定class支持对象
            <template>
              <div id="example">
                <p  :class="{'classA' : data.isA , 'classB' : data.isB }">绑定对象</p>
              </div>
            </template>
            <script>
            export default {
              name: "example",
              data() {
                return {
                 data : {
                   classDedault : 'classD',
                   isA : true,
                   isB : true
                 }
                };
              },
              methods: {}
            };
            </script>
            View Code

            结果为:

                                            

            • 当然,绑定class可以与普通的class特性共存,也可以直接绑定一个对象;
            • 也可以绑定一个计算属性:
              <template>
                <div id="example">
                  <p class="classA"  :class="classOther">过滤器:{{ time | timeFormatter}}</p>
                </div>
              </template>
              <script>
              export default {
                name: "example",
                data() {
                  return {
                   time :  new Date().getTime(),
                   className : {
                     'classB' : 20,
                     'classC' : 3 
                   }
                  };
                },
                computed: {
                  classOther : {
                    get : function(){
                      return {
                        'classB' : this.className.classB > 20 ? true : false,
                        'classC' : this.className.classC < 4  ? true : false
                      }
                    }
                  }
                },
                methods: {}
              };
              </script>
              View Code

          • 绑定class支持数组
            <template>
              <div id="example">
                <p  :class="[data.classA,data.classB]">绑定对象</p>
              </div>
            </template>
            <script>
            export default {
              name: "example",
              data() {
                return {
                 data : {
                  classA : 'class-a',
                  classB : 'class-b'
                 }
                };
              },
              methods: {}
            };
            </script>
            View Code

            结果为:

                                             

          • 绑定内联样式style:跟class一样,对象、数组、计算属性都支持,但是采用的是 “ 驼峰式命名 ”
        • v-on:(监听DOM事件)可以简写为 “ @ ”
          • 内联处理器中的方法:
            <template>
              <div id="example">
                <p
                  @click="test('你传事件$event了吗',$event)"
                  style="200px;height:200px;background:red"
                >v-on的内联传事件及参数的方法</p>
              </div>
            </template>
            <script>
            export default {
              name: "example",
              data() {
                return {
                  test(message, event) {
                    if (event) {
                      console.log(event)
                      event.preventDefault()
                    } else {
                      console.log(message);
                    }
                  }
                };
              },
              methods: {}
            };
            </script>
            View Code

            $event是指原生的DOM事件,默认可以传递;

                                             结果为:点击发生

                                         

          • 事件修饰符
            • .stop(阻止单击事件继续传播,即停止冒泡)
            • .prevent(阻止元素的默认行为,相当于e.preventDefault() )
            • .capture(添加事件监听器时使用事件捕获模式)
            • .self(事件只在该元素本身(而非子元素)触发时执行函数)
            • @keyup.enter || @keyup.enter.native(@keyup.13一样)点击回车时进行调用 ----- native后缀可以在父组件在子组件上绑定一个原生的事件,从而转化为一个普通的HTML标签(.native在普通标签上不起作用)
            • @keyup.esc(回撤)@kuyup.delete(删除或者退格等)
        • v-ref:(建立索引,用this.$refs.someRef访问元素  元素用v-ref="some-ref"标记) 
        • v-el:(获取当前元素的内容)Vue2.x已经废除
          <template>
            <div id="example">
              <p v-el:some-data>我的内容是:你</p>
            </div>
          </template>
          <script>
          export default {
            name: "example",
            data() {
              return {
                
              };
            },
            methods: {},
            mounted(){
              console.log(this.$els.someData.textContent)//我的内容是:你
            }
          };
          </script>
          View Code
        • v-once:数据只能绑定一次,后续数据的变化不在关心(vue2.x新增的指令)
        • v-pre:(显示原始的Mustache标签)
          <template>
            <div id="example">
              <p v-pre>{{number}}</p>
            </div>
          </template>
          <script>
          export default {
            name: "example",
            data() {
              return {
                number : "2222"
              };
            },
            methods: {},
           
          };
          </script>
          View Code

          结果为:

                                   

        • v-cloak:(元素在vue没有加载完的时候就有这个属性,当vue加载完成后这个属性就消失了-----防止在渲染页面时,用户首先看到Mustache标签)
          <style>
          p[v-cloak]{visibility:hidden}//display:none
          </style>
          
          <p  v-cloak>{{msg}}</p>
    • 自定义指令
      • 格式:Vue.directive(id,definition)      注册全局自定义指令
      • 提供的钩子函数
        • bind/unbind-----只执行一次,指令第一次被绑定(解绑)时调用
        • inserted-----被绑定的元素插入父元素时调用
        • update-----在bind之后立即以初始值为参数第一次调用,之后绑定值发生变化调用,参数为新值与旧值update(newValue,oldValue)
        • componentUpdated-----所在组件以及他的子组件全部更新后调用

            (注意:除了update和componentUpdated之外,每个钩子函数都有el、binding、vnode三个参数,而oldValue只有在update和componentUpdated中有效,并且除了el,其他两者都只有只读)

      • 指令实例属性(即钩子函数的参数)——只读,不可修改
        • el——指令绑定的DOM元素
        • binding包括以下属性
          • name——指令的名字,不包括前缀
          • value——新值
          • oldValue——旧值
          • expression——指令的表达式,不包括指令和过滤器   v-load="1 + 1"  结果为1+1
          • arg——指令的参数   v-load:foo    结果为foo
          • modifiers——一个对象,包含指令的修饰符   v-load.literal  结果为 { literal : true }
          • vm——拥有该指令的上下文ViewModel(废除)
          • descriptor——一个对象,包含指令的解析结果(废除)
        • 注意:
        • 使用步骤
          • 建立一个js文件,此处命名为module.js   不支持    箭头函数
            import Vue from 'vue'
            Vue.directive('load', {
                bind(el, binding) {//准备工作
                    if (binding.value) {
                        console.log(el)
                        console.log("name---" + binding.name)
                        console.log("value---" + binding.value)
                        console.log("oldValue---" + binding.oldValue)
                        console.log("expression---" + binding.expression)
                        console.log("arg---" + binding.arg)
                        let div = document.createElement("div");
                        div.className = "loading-parent";
                        div.innerHTML = `
                      <div class="loading-spinner"><i class='el-icon-loading'></i></div>
                    `;
                        el.appendChild(div);
                    }
                },
                update(el, binding) {//值更新时的工作
                    if (binding.value) {
                        console.log(el)
                        console.log("name---" + binding.name)
                        console.log("value---" + binding.value)
                        console.log("oldValue---" + binding.oldValue)
                        console.log("expression---" + binding.expression)
                        console.log("arg---" + binding.arg)
                        let div = document.createElement("div");
                        div.className = "loading-parent";
                        div.innerHTML = `
                    <div class="loading-spinner"><i class='el-icon-loading'></i></div>
                  `;
                        el.appendChild(div);
                        el.load = div;
                    } else {
                        el.load && el.load.parentNode && el.load.parentNode.removeChild(el.load);
                    }
                },
                unbind: function () {//清理工作
            
                }
            })
            View Code

            结果为:

                                              

            • 我们可以看到代码重复率太高,因此规定了简写方式,只有bind和update时,可以简写为
              import Vue from 'vue'
              Vue.directive('load', function (el, binding) {//值更新时的工作
                  if (binding.value) {// 1
                      let div = document.createElement("div");
                      div.className = "loading-parent";
                      div.innerHTML = `
                      <div class="loading-spinner"><i class='el-icon-loading'></i></div>
                    `;
                      el.appendChild(div);
                      el.load = div;
                  } else {
                      el.load && el.load.parentNode && el.load.parentNode.removeChild(el.load);
                  }
              }
              )
              View Code
          • app..js文件中引入    import module from './module.js'
          • 使用
            <template>
              <div id="example" @click="up" style="100px;height:100px;background:pink">
                <div id="demo" v-load="msg"></div>
              </div>
            </template>
            <script>
            export default {
              name: "example",
              data() {
                return {
                  msg: 1
                };
              },
              methods: {
                up() {
                  this.msg += 1;
                }
              },
              mounted() {}
            };
            </script>
            View Code

            结果为:首次执行bind函数,每次点击执行update

                                              

                                              点击时,值变化

                                               

      • 局部定义指令(例子:实现图片的一定div内的拖拽功能)
        • html
          <div class="previewImg">
               <img
                      :src="alImgUrl"
                       class="currentImg"
                       :id="inner.id"
                       v-drag
                       style="cursor:pointer"
                       :draggable="false"//拖拽必须加
                 />
          </div>
                                  
        • css ----- 必须设置定位
          .previewImg {
                position: relative;
                .currentImg {
                     position: absolute;
                     left: 150px;
                     top: 0;
                      450px;
                     height: 636px;
                     margin-left: 50px;
                     -moz-user-select: none; /*火狐*/
                     -webkit-user-select: none; /*webkit浏览器*/
                     -ms-user-select: none; /*IE10*/
                     -khtml-user-select: none; /*早期浏览器*/
                     user-select: none;
                  }
          }
          View Code
        • js
          directives: {
              drag(el, binding) {
                el.onmousedown = function(e) {
                  //获取鼠标点击处分别与div左边和上边的距离:鼠标位置-div位置
                  var divx = e.clientX - document.getElementsByClassName("currentImg")[0].offsetLeft;
                  var divy = e.clientY - document.getElementsByClassName("currentImg")[0].offsetTop;
                  //包含在onmousedown里,表示点击后才移动,为防止鼠标移出div,使用document.onmousemove
                  document.onmousemove = function(e) {
                    //获取移动后div的位置:鼠标位置-divx/divy
                    var l = e.clientX - divx;
                    var t = e.clientY - divy;
                    document.getElementsByClassName("currentImg")[0].style.left = l + "px";
                    document.getElementsByClassName("currentImg")[0].style.top = t + "px";
                  };
                  document.onmouseup = function(e) {
                    document.onmousemove = null;
                    document.onmouseup = null;
                  };
                };
              }
            },
      • 对象字面量(指令传入多个值)
        • 定义
          import Vue from 'vue'
          Vue.directive('load', function (el, binding) {//值更新时的工作
              if (binding.value) {// 1
                  console.log(binding.value)
                  let div = document.createElement("div");
                  div.className = "loading-parent";
                  div.style.color = binding.value.color;
                  div.style.fontSize = binding.value.fontSize
                  div.innerHTML = `
                  <div class="loading-spinner"><i class='el-icon-loading'></i></div>
                `;
                  el.appendChild(div);
                  el.load = div;
              } else {
                  el.load && el.load.parentNode && el.load.parentNode.removeChild(el.load);
              }
          }
          )
          View Code
        • 使用
          <template>
            <div id="example" @click="up" style="100px;height:100px;background:pink">
              <div id="demo" v-load="{msg : msg,color:'#f00',fontSize:'30px'}"></div>
            </div>
          </template>
          <script>
          export default {
            name: "example",
            data() {
              return {
                msg: 1
              };
            },
            methods: {
              up() {
                this.msg += 1;
              }
            },
            mounted() {}
          };
          </script>
          View Code

          结果为:

                                   

                                  

      • 字面修饰符(值按照普通字符串传递给update,update只调用一次)
        <template>
          <div id="example" @click="up" style="100px;height:100px;background:pink">
            <div id="demo" v-load.literal="msg "></div>
          </div>
        </template>
        <script>
        export default {
          name: "example",
          data() {
            return {
              msg: 1
            };
          },
          methods: {
            up() {
              this.msg += 1;
            }
          },
          mounted() {}
        };
        </script>
        View Code

        结果为:

        console.log(binding.value)
        console.log(binding.modifiers)

                       

      • 元素指令(作为一个标签出现,不接受参数与表达式)
        • 特点:终结性(只有该元素指令本身可以操作该元素及其子元素)
      •  高级选项
        • params:(自定义属性)
          <p v-finish="msg" name="wxh">1111111111</p>
          import Vue from 'vue'
          Vue.directive("finish", function (el, binding) {
              if(binding.value){
                  binding.value = 2;
                  console.log(el.getAttribute("name"));
                  console.log(binding.value);
              }
          })
          View Code

          结果为:

                                   

        • deep
        • twoWay
        • acceptStatement
        • Terminal
        • priority

    4、常见问题解析

    • v-on可以绑定多个方法吗?(如果绑定多个,只会执行第一个,其他的自动忽略)
    • 一个Vue实例可以绑定多个element元素吗?
    • 在Vue中,如何让v-for循环出来的列表的click事件只对当前元素有效 https://www.cnblogs.com/tangwanzun/p/7828317.html
  • 相关阅读:
    当blogger遭遇bXbm42e8
    按时间顺序来,对我影响较大的格言应当首推在高中毕业时霄美人送我的那一句话,它指引着我如何去面对很多难...
    遇见一孙子
    回草儿:呵呵~~这个……随缘。
    学Linux下的编程,make非学好不可啊……
    呵呵,你的口才不错啊!军师,我发现你挺会说话。
    字符串处理的一个简单题
    以Python为基础的REST(JSON为交换数据)接口的测试框架设计(一)
    人生的战略总结最近三年选择的得失
    淘宝开放API初探
  • 原文地址:https://www.cnblogs.com/wxh0929/p/11162017.html
Copyright © 2011-2022 走看看