• vue的基础介绍及指令


      vue是采用自底向上增量开发设计的一套构建用户界面的渐进式框架,它不仅易上手且方便。

      vue的安装有三种方式,官网直接进行下载;使用在线的CND(https://unpkg.com/vue@2.6.11/dist/vue.js);使用npm install vue 命令进行下载。获取后直接在script标签中引入就可。

      对于vue最简单的应用将其当成是一个模板引擎,采用模板语法把数据渲染进DOM.如下:

        <div id="app">
            {{message}}
        </div>

      每个vue.js应用都是通过构造函数Vue创建一个Vue的根实例来进行的,常使用vm(vue model)这个变量名表示实例。在实例vue时,要传入一个选项对象,它可以包含数据,模板,元素,方法,生命周期等等。下面为Vue()构造函数传入了一个对象,对象中包含了el和data这两个参数。el参数,用于提供一个在页面上已存在的DOM元素作为Vue实例挂载目标。而data则表示Vue实例的数据对象。

    let vm = new Vue({
      //选项 el:
    "#app", data:{ message:'davina' } })

      一、vue模板的内容

      对于{{}}它主要的作用是进行数据绑定,最常见的是使用Mustache语法({{}}语法)的文本插值。上文中的message相当于一个变量或者是占位符,最终它会表示为真正的文本内容。Mustache标签将会被数据对象上(data中的message)的值进行替代。当massage上的内容发生改变时,插值处的内容也会进行更新。

      表达式插值。下面的这些表达式会在所属的vue实例的数据作用域下作为js被解析。每个绑定只能包含单个表达式,需要注意的是不能是语句,它包括定义变量,定义函数,赋值等待。

        {{number +1}}
        {{value?'yes':'no'}}
        {{ 对象 }}
        {{ 数组 }}
        {{函数的返回值}}

    示例:

        <div id="app">
            {{msg}}<br>
            {{[1,2,3].map((item)=>{return item*2})}}<br>
            {{arr}}<br>
            {{obj}}
        </div>
    <!-- 导入vue.js -->
    <script src="./vue.js"></script>
    <script>
        // vm是vue的实例
        let vm = new Vue({
            el: '#app',//指定vue替换元素
            data: {
                msg: 'test',
                obj: { age: 20 },
                arr: [1, 2, { name: "ph" }],
            }
        });
    </script>

      二、指令

      在模板的元素中,那个v-xxx行内属性就是Vue的指令,它有常用即有指令和自定义指令。

      1、即有指令(13)

      v-model="xxx": 一般用于表单元素上,创建双向数据绑定。input框内容改变 ,所有用到这个变量的地方都会自动进行更新。像下面的例子中,在input框中输入其它的内容,上面msg的内容也会被修改。

        <div id="app">
            <!-- textarea -->
            <textarea v-model='text'></textarea><br>
            <!-- select -->
            <h2>{{selectValue}}</h2>
            <!-- 多个选择都是数组 -->
            <select v-model='selectValue' multiple>
                <option value="" disabled>请选择</option>
                <option v-for='i of selectOptions' :value="i.id">{{i.value}}</option>
            </select><br>
            <!-- radio 分组互斥-->
            <input type="radio" value="" v-model="radioValue">
            <input type="radio" value="" v-model="radioValue"><br>
            <!-- checkbox 默认值是不选择 true false -->
            爱好:{{checkValue}}
            <input type="checkbox" value="吃饭" v-model="checkValue">
            <input type="checkbox" value="睡觉" v-model="checkValue">
            <input type="checkbox" value="打豆豆" v-model="checkValue"><br>
            <!-- 修饰符 -->
            <!-- trim是前去除前后的空格,但中间的不能去,number限制只能输入数字 -->
            <input type="text" v-model.trim="text">
            <input type="text" v-model.number="text">
        </div>
        <script src="./vue.min.js"></script>
        <script>
            let vm = new Vue({
                el: '#app',
                data: {
                    text: 'davina',
                    selectValue: [],
                    selectOptions: [
                        { value: 'js', id: 1 },
                        { value: 'react', id: 2 },
                        { value: 'vue', id: 3 }
                    ],
                    radioValue: '',
                    checkValue: ['吃饭', '睡觉', '打豆豆'],
                }
            })
        </script> 

      v-text="xxx": 这个不太常用。主要用于更新textContent,可以等价于js中的text属性

      v-html=“xxx”: 双大括号的方式会将数据解析为纯文本,而不是html。如果是真正的要输出html标签要用到这个v-html指令,它等价于js中的innerHTML。

       <div id="app">     
        <h4 v-text="str"></h4>
        <!-- <h4>{{str}}</h4> -->
        <h4 v-html="str"></h4>
        </div>
    <script>
        let vm = new Vue({
            el:'#app',
            data:{
                str:'<i>test</i>'
            }
        });
    </script> 

      v-if="xxx": Vue会根据表达式的值真假条件来渲染元素,它可以实现条件渲染,用来控制元素或者组件是否进行加载,它有比较大的切换开销;

      v-else: 搭配v-if来进行使用的,它必须紧跟在v-if/v-else-if后面,不然是不起作用的;

      v-else-if: 它充当v-if中的else-if块,可以链式使用多次

       <div id="app">     
        <h2 >{{msg}}</h2>
        <input type="text" v-if="msg.length < 10 " v-model="msg">
        <h2 v-else>内容太长,不再显示</h2>
        </div>
    <script>
        let vm = new Vue({
            el:'#app',
            data:{
                msg:'msg'
            }
        });
    </script>       

      v-show="xxx": 用来控制元素或者组件是否显示,和v-if不同的是如果v-if的值是false那么这个元素将销毁,不在DOM中,但v-show的元素会始终被渲染保存在DOM中,它只是简单的切换了css中的display属性,有比较大的初始化加载开销。

      v-for="xxx": 用来循环展示标签的,可以循环数组,数字,字符串,对象(基本上都是数组);需要注意的是v-for和v-if同时使用时,for的优先级高(不建议一起使用),还用一般要带一个:key,对于vue来说是元素的一个身份证明,有利于Vue中的DOM DIFF计算。j理想的key是数据的唯一ID,如果没我们可以用索引,但这时有可能会导致元素不更新复用了老的元素。有以下两种形式。

    <div v-for="item of items"></div> //使用of 
    <div v-for="(item,index) in items"></div> //使用in index表示当前项的索引  item 数组中的每一项
        <div id="app">
            <h3 v-for="(index,item) in ary" :key="index">{{item}}:{{index}}</h3>
        </div>
    <script>
        let vm = new Vue({
            el: '#app',
            data: {
                ary: [1, 2, 3, 4]
    
            }
        });
    </script>

      v-bind="xxx": 用来动态绑定一个或者多个特性,处理行内属性。没有参数时,可以绑定到一个包含键值对的对象。可以简写用冒号(:)来表示。常用于绑定style,class所以Vue对其进行了专门的强化:class="{类名1:值,类名2:值,......}",:style="{属性名:属性值,......}"。

        <style>
            .box {
                color: lightblue
            }
        </style>
        <div id="app">
            <a :href="url" :class="cln">click me</a>
        </div>
    <script>
        let vm = new Vue({
            el: '#app',
            data: {
                url: 'https://www.baidu.com/img/flexible/logo/pc/result@2.png',
                cln: 'box'
            }
        });
    </script>

      v-cloak: 保持在元素上直到关联实例结束时进行编译。Vue专门用来提供解决小胡子显示问题的,它需要配合css来使用,当vue编译完成后,会把这个属性删掉,这时css属性就不起作用了。

      <style>
           [v-cloak]{
               opacity: 0;
           }
       </style>
       <div id="app" v-cloak>     
            <h5>{{msg}}</h5>
        </div>
    <script>
        let vm = new Vue({
            el:'#app',
            data:{
                msg:'message'
            }
        });
    </script> 

      v-once: v-once关联的实例,只能编译一次。实例及所有的了节点将被视为静态内容进行跳过,可以用于优化更新性能。

       <div id="app" v-once>     
        <h5>{{msg}}</h5>
        <p>{{ary}}</p>
        </div>
    <script>
        let vm = new Vue({
            el:'#app',
            data:{
                msg:'message',
                ary:[1,2,3]
            }
        });
    </script> 

      v-pre: 有这个指令的标签及其后代元素,vue都不在编译,主要用来跳过这个元素和它的子元素编译过程,用来提升编译效率的。 

       <div id="app">     
        <ul v-pre>
            <!-- 里面的内容不用vue来操作,可以提升效率 -->
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
        </div>
    <script>
        let vm = new Vue({
            el:'#app'
        });
    </script>    

       v-on: 专门用来绑定事件的指令,可以简写成@。

    <div id="app">
            <h2>{{count}}</h2>
            <button @click="add"> + </button>
            <button @click="minus"> - </button><br>
             <!-- 在函数名后面加上()不是为了执行,而是为了传参 -->
            <button @click="add(10,$event)"> +10 </button>
            <button @click="minus(-10)"> -10 </button><br>
            <!-- 
            @click='fn'                         这种情况默认把事件对象传过去
            @click="fn()"                       一个参数都没有那就是把函数执行
            @click="fn(10,20,...)"              这种情况 写什么参数就传递什么参数
            @click="fn(10,$event,20,$event)"    这种情况是即需要事件对象(编写$event),也需要自己传递的参数 
            -->
    </div>
    <script src="./vue.js"></script>
    <script>
        let vm = new Vue({
            el: '#app',
            data: { count: 0 },
            methods: {
                //这里放的是各种函数,函数当前实例都是this
                //这里的属性会被挂载到实例上,所以与data中的属性名不能重复
                add(n) {
                    typeof n == "object" ? this.count++ : this.count += n;
                },
                minus(n) {
                    typeof n == 'object' ? this.count-- : this.count -= n;
                }
            }
        });
    </script>

      还有事件修饰符:.stop:阻止事件继续传播 / .prevent:事件不再重载页面 / .capture: 使用事件捕获模式 / .self:只当在event.target是当前元素时触发 / .once:事件将只会触发一次 / .passive:告诉浏览器不想阻止事件的默认行为

      需要强调一点的是,使用修饰符顺序很关键,相应的代码会以同样的顺序产生。在大部分事件中,先执行绑定的函数,再执行默认的函数,默认的函数也有执行的顺序。但在onscroll,touchmove这类高频触发的事件是先执行默认函数函数,再执行绑定函数。

    <body>
        <div id="app">
            <h2>{{count}}</h2>
            <div class="outer" @click.once='add'>
                outer
                <div class="inner" @click.stop="stop">
                    inner
                    <div class="center">
                        center
                    </div>
                </div>
            </div>
             <!-- 当然还有按钮修饰符 -->
             <input type="text"  @keydown.enter="enter">
        </div>
    </body>
    </html>
    <script src="./vue.js"></script>
    <script>
        let vm = new Vue({
            el: '#app',
            data: { count: 0 },
            methods: {
                add(n) {
                    typeof n == "object" ? this.count++ : this.count += n;
                },
                minus(n) {
                    typeof n == 'object' ? this.count-- : this.count -= n;
                },
                prevent(e) {
                    // e.preventDefault();
                },
                stop(e) { e.stopPropagation() },
                enter(e) { console.log(e) }
            }
        });
    </script>

      2、自定义指令

      Vue除了提供默认的内置指令以外,还可以让开发者根据实际情况来自定义指令。通过它我们可以DOM元素进行更多的底层操作。它存在着全局注册和局部注册两种方式。

      通过Vue.directive(id,[definintion])方式来进行注册,第一个参数为自定义指令的名称,第二个参数可以是对象数据也可以是一个函数。需要注意的一点是指令名称不需要加v-,默认是自动加上的,但在使用时要加上v-前缀。

    <body>
        <div id="app">
            <h3 v-col='"lightblue"'>{{msg}}</h3>
            <h5 v-col>{{msg}}</h5>
        </div>
    </body>
    <script>
        Vue.directive('col', function (el, obj) {
            //对函数中的this为window 不在是当前的实例了
            console.log(this);
            //el 使用这个指令的那个元素标签 
            //obj中有一个value值,它对应的是指令后面跟的值。如果没有则不存在
            console.log(el, obj);
            el.style.color = obj.value || 'lightpink';
        })
        let vm = new Vue({
            el: '#app',
            data: {
                msg: "自定义指令之全局注册"
            }
        });
    </script>

      局部注册我们可以通过在Vue实例中添加directives对象数据来进行注册。在工作中如果有多个自己定义的指令,一般会单独新建一个文件,用import或者script进行引入。先执行局部再用全局指令。

    <body>
        <div id="app">     
            <h5 v-col>{{msg}}</h5>
        </div>
    </body>
    <script>
        let vm = new Vue({
            el: '#app',
            data: {
                msg: "自定义指令之全局注册"
            },
            directives: {
                col(el, obj) {
                    el.style.color = 'lightskyblue'
                }
            }
        });
    </script>

      一个指令定义对象可以提供如下几个钩子函数,一般用的比较多的时insert,bind和unbind。

        bind: 只调用一次,指令第一次绑定到元素时进行调用;

        unbind: 只调用一次,指令与元素解绑时调用;

        insert: 被绑定元素插入父节点时调用;

        update: 所在组件的VNode更新时调用,但也可能是发生在其子元素的VNode更新之前;

        componentUpdated: 所在组件的VNode及其子元素的VNode全部更新时调用

        它们中的每一个都以el,binding,VNode参数:

        el: 指令所绑定的DOM元素,可以直接用来操作DOM

        binding: 一个对象。包含了以下属性name,value,oldValue,expression,arg,modifiers.

        VNode:Vue编译生成的虚拟节点

        oldVnode: 上一个虚拟节点,用来区分传递的旧值和新值,仅在update和componentUpdated钩子中可用。

      下面这个例子可用于多个权限的设置,需要注意的是inserted函数的使用。

    <body>
        <div id="app">
            <h3 v-premission='"张三"'>{{msg}}</h3>
        </div>
    </body>
    <script>
        let ary = ["张三", "赵二", "王五", "李六"];
        Vue.directive('premission', {
            //inserted是钩子函数它是固定的
            inserted(el, { value }) {
                //这个函数执行的时候 代表 编译好的元素已经插入到了父结点中
                let bol = ary.indexOf(value) == -1 ? false : true;
                if (!bol) {
                    el.parentNode.removeChild(el);
                }
            }
        })
        let vm = new Vue({
            el: '#app',
            data: {
                msg: "权限"
            }
        });
       <div id="box">
            <input type="text" v-focus.color='color'>
        </div>
        <script>
            // 需求:让输入框自动获取焦点
            //全局指令:所以组件,实例都可以使用
            Vue.directive('focus', {
                //指令元素插入到页面时执行
                inserted(el, obj, vnode) {
                    el.focus();
                    //el 当前指令元素 obj 绑定属性 vnode虚拟节点 contex上下文,当前指令所在的上下文
                    // console.log(el, obj, vnode);
                    obj.modifiers.color ? el.style.background = obj.value : lightblue;
                },
                //绑定时执行
                // bind(el, obj, vnode) {
                //     Vue.nextTick(() => {
                //         el.focus();
                //     })
                // }
                //指令销毁时会触发这个函数
                // unbind(){}
            })
            let vm = new Vue({
                el: '#box',
                data: {
                    color: 'lightgreen',
                }
            })
        </script>
        <style>.content {height:30px; 120px;background-color: lightblue}</style>
        <div id="app">
    //弹层功能 <div v-click-outside> <button>click </button> <input type="text"> <div class="content" v-if="isShow">xxxx年xx月xx日 </div> </div> </div> <script> //判断是否存在当前的dom中 let vm = new Vue({ el: '#app', directives: { clickOutside: { bind(el, bindings, vnode) { el.fn = (e) => { if (el.contains(e.target)) { vnode.context['focus']() } else { vnode.context['blur']() } } document.addEventListener('click', el.fn) }, unbind(el) { document.removeEventListener('click', el.fn) } } }, data: { isShow: false }, methods: { blur() { this.isShow = false; }, focus() { this.isShow = true; } } }); </script>

       

      

        

     

     

  • 相关阅读:
    8.2.8 A Simple Game
    8.2.7 Be the Winner
    8.2.6 John
    8.2.5 kiki's game
    8.2.2 Good Luck in CET-4 Everybody!
    8.2.4 悼念512汶川大地震遇难同胞——选拔志愿者
    8.1.8 Team Queue
    8.2.1 Brave Game
    8.1.7 愚人节的礼物
    8.1.6 Windows Message Queue
  • 原文地址:https://www.cnblogs.com/davina123/p/13321279.html
Copyright © 2020-2023  润新知