zoukankan      html  css  js  c++  java
  • Vue框架基础

    Vue框架基础

    vue导入

    <script src="js/vue.js"></script>

    vue挂载点

    <div id='app'></div>
    <script>
    	new Vue (){
        	el:'#app',
    	}    
    </script>
    // el 为挂载点,采用css3选择器与页面标签进行绑定,决定该vue对象控制的页面范围
        // 挂载点只检索也i按中第一个匹配到的结果,所以挂载点一般都采用id选择器
        // html与body标签不可以作为挂载点
    

    vue变量

    ​ 类似于Django中的模板语法

    <div id="app">
        <p>{{ msg }}</p>
    	<p>{{ info }}</p>
    	<h3>{{ msg }}</h3>
    </div>
    <script>
        new Vue (){
        	el:'#app',
            data:{
                msg:'此处不留爷',
                info:'自有留爷处'
            }
    	}
    	console.log(app.$el);
    	console.log(app.$data);
    </script>
    
    // 实例成员中的data是为vue页面模板提供数据变量的
    // 访问实例成员可以用 vue实例.$成员名
    

    vue事件

    实例1:给P1标签添加点击事件,记录点击次数

    实例2:给P2标签添加鼠标悬停、移除鼠标、点击等事件

    <div id="app">
        <p class="p1" v-on:click="fn">这是一个段落,被点击了{{ count }}下</p>
        <p class="p2" @mouseover="over" @mouseout="out" @click="hit">点我:{{ action }}</p>
    </div>
    <script>
        let app = new Vue({
            el:'#app',
            data:{
                count:0,
                action:'别点我'
            },
            methods:{
                func(){
                    this.count++;
                    console.log(this.count);
                },
                over(){
                    this.action = '你被盯上了'
                },
                out(){
                  this.action = '你安全了'
                },
                hit(){
                  this.action = '你真的点我了,你完了'
                }
            }
        });
    </script>
    
    // methods就是为vue实例提供事件函数的
    // this代表当前该vue实例对象
    // 绑定事件用 v-on:事件名="触发函数名",也可使用简写:@事件名="触发函数名"
    

    vue文本指令

    <!--v-text:将所有内容做文本渲染 -->
    <p v-text="msg + '拼接内容'"></p>
    <!--v-html:可以解析html语法标签的文本 -->
    <p v-html="'<b>' + msg + '</b>'"></p>
    <p v-html="`<b>${msg}</b>`"></p>
    

    vue过滤器

    <div id="app">
        // 默认将msg作为参数传给ff过滤器
        <p>{{ msg|ff }}</p>
    	// 过滤器可以嵌套,(num|f1)|f2,在num基础上先用f1过滤器,再用f2过滤器
        <p>{{ num|f1|f2 }}</p>
    	// 过滤器括号内可以传参,过滤器方法接受所有传入的参数,按传入的位置进行接收
        <p>{{ msg,num|f3(1,2) }}</p>
    </div>
    <script>
         new Vue({
            el: '#app',
            data: {
                msg: '你不是真正的快乐',
                num: 1
            },
            // 过滤器使用vue实例成员filters来指定过滤器函数
            filters:{
                ff(x,y){
                    console.log(x);
                    console.log(y);
                    return `<b>${x}</b>`;
                },
                f1(x){
                  return x + 10
                },
                f2(x){
                    return x*5
                },
                f3(x,y,p,q){
                    console.log(x);
                    console.log(y);
                    console.log(p);
                    console.log(q);
                },
            },
        })
    

    vue事件指令

    <p @click="f1">被点击了{{ count }}下</p>
    // 当事件函数没有传参数,默认传入事件对象
    <div class="box" @click="f2(10, $event)"></div>
    // 事件函数一旦添加传参(),系统就不再传递任何参数,需要事件对象时,可以手动传入 $event
    
    methods: {
        f1(ev, b) {
            this.count ++;
            console.log(ev); // MouseEvent
            console.log(b); // undefined
        },
        f2(num, ev) {
            console.log(num); // 10
            console.log(ev); // MouseEvent
        }
    },
    

    vue属性指令

    <!--1.下方的class、id、title、abc等是div标签的属性,属性指令就是控制它们的-->
    <div class="b1" id="b1" v-bind:title="title" :abc="xyz"></div>
    <!--2.属性指令:v-bind:属性名="变量",简写方式 :属性名="变量" -->
    <!--只要是属性指令,属性值就为一个变量,需要在data成员中初始化 -->
    
    <!--class可以写两份,一份写死,一份有vue控制-->
    <div class="box1" :class="c2"></div>
    
    <!--{}控制类名,key为类名,key对应的值为bool类型,决定该类名是否起作用-->
    <div :class="{box2:true, circle:cable}"></div>
    
    <!--[]控制多个类名-->
    <div :class="[c3, c4]"></div>
    

    作业

    ​ 有 红、黄、蓝 三个按钮,以及一个200x200矩形框box,点击不同的按钮,box的颜色会被切换为指定的颜色

    <style>
        .box {
             200px;
            height: 200px;
            background-color: red;
        }
    </style>
    <body>
        <div id="app">
            <p>
                <button @click="fn('red')">红</button>
                <button @click="fn('yellow')">黄</button>
                <button @click="fn('blue')">蓝</button>
            </p>
            <!-- :属性指令 -->
            <div class="box" :style="{backgroundColor: color}"></div>
        </div>
    </body>
    
    <script>
        new Vue({
            el: '#app',
            data: {
                color: 'red'
            },
            methods: {
                fn(color) {
                    this.color = color;
                }
            }
        })
    </script>
    
    

    ​ 有一个200x200矩形框wrap,点击wrap本身,记录点击次数,如果是1次wrap为pink色,2次wrap为green色,3次wrap为cyan色,4次重新回到pink色,依次类推

    <style>
        .wrap {
            200px;
            height:200px;
            background-color:red;
        }
    </style>
    <div id="app">
    	<div class="wrap" :style="{backgroundColor: color}" @click="changeColor">	 </div>
    </div>
    
    
    new Vue({
        el:'#app',
        data:{
            color:'black',
            count:0,
            colorArr:['cyan', 'pink', 'green'] // 保存颜色的映射关系
        },
        methods:{
        	changeColor(){
        		let n = this.count++;
        		this.color = this.colorArr[n % this.colorArr.length];
    		}
    	}
    })
    
    

    ​ 图形初始左红右绿,点击一下后变成上红下绿,再点击变成右红左绿,再点击变成下红上绿,依次类推

    <style>
        .box {
             200px;
            height: 200px;
            border: 1px solid black;
            border-radius: 50%;
            overflow: hidden;
            position: relative;
        }
        .b1 { background-color: red; position: absolute; }
        .b2 { background-color: green; position: absolute; }
        .l {
             100px;
            height: 200px;
            left: 0;
        }
        .r {
             100px;
            height: 200px;
            right: 0;
        }
        .t {
             200px;
            height: 100px;
            top: 0;
        }
        .b {
             200px;
            height: 100px;
            bottom: 0;
        }
    </style>
    
    <div id="app">
        <div class="box" @click="clickAction">
            <div class="b1" :class="c1"></div>
            <div class="b2" :class="c2"></div>
        </div>
    </div>
    
    
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                count: 1,
                c1: 'l',
                c2: 'r',
                c1Arr: ['l', 't', 'r', 'b'],
                c2Arr: ['r', 'b', 'l', 't']
            },
            methods: {
                clickAction() {
                    let n = this.count ++;
                    this.c1 = this.c1Arr[n % 4];
                    this.c2 = this.c2Arr[n % 4];
                }
            }
        });
    	// 利用定时器自动旋转图像
        setInterval(function () {
            app.clickAction();
        }, 500)
    </script>
    
    

    vue表单指令

    <div id="app">
        <!--普通表单元素:用v-model直接绑定变量控制value的值 -->
        <input type="text" v-model="v1">
        <input type="text" v-model="v1">
        <span>{{ v1 }}</span>
    
        <br>
        <!--单一复选框:v2的值为true时选中,为false时不选中-->
        <input type="checkbox" v-model="v2">
    
        <br>
        <!--多个复选框:给定v3为初始选中的列表,列表内放选中的value属性值。-->
        唱: <input type="checkbox" name="hobby" value="sing" v-model="v3">
        跳: <input type="checkbox" name="hobby" value="dance" v-model="v3">
        rap: <input type="checkbox" name="hobby" value="rap" v-model="v3">
    
        <br>
        <!--单选框:给定v4为指定默认选中的单选框value的属性值-->
        男:<input type="radio" value="male" v-model="v4">
        女:<input type="radio" value="famale" v-model="v4">
    </div>
    <script>
        new Vue({
            el: '#app',
            data:{
                v1:123,
                v2:false,
                v3:['sing','rap'],
                v4:'male'
            }
        })
    </script>
    
    

    vue条件指令

    <div id="app">
        <!-- v-if: 值为false时,在页面上不渲染,并且隐藏标签中的信息-->
        <p v-if="false">if</p>
        <!-- v-show: 值为false时,在页面上是用display:none 渲染隐藏的,但是仍然存在当前页面的结构中 -->
        <p v-show="false">show</p>
    
        <!--上分支成立时,所有的下分支都会被屏蔽,v-else只有在上分支全部为假时才会显示,所以v-else不需要条件-->
        <p v-if="1">if</p>
        <p v-else-if="0">elif</p>
        <p v-else-if="0">elif</p>
        <p v-else>else</p>
    </div>
    
    

    vue条件指令实例

    <style>
        .box {
             200px;
            height: 200px;
        }
        .r {background-color: red}
        .g {background-color: green}
        .b {background-color: black}
        .action{background-color: pink}
    </style>
    <div id="app">
        <!-- 给定button的单击事件并传入参数,并且给button绑定{}属性指令:判断当前c变量的值来确定选中按钮的高亮-->
        <button @click="change('red')" :class="{ action:c === 'red' }">红</button>
        <button @click="change('green')" :class="{ action:c === 'green' }">绿</button>
        <button @click="change('black')" :class="{ action:c === 'black' }">黑</button>
        <br>
        <!-- 利用v-if家族来判断变量c的值来确定是否显示该标签 -->
        <div class="box r" v-if="c === 'red'"></div>
        <div class="box g" v-else-if="c === 'green'"></div>
        <div class="box b" v-else></div>
    </div>
    
    <script>
        new Vue({
            el: '#app',
            data:{
                // localStorage是浏览器永久的数据库,可以将c变量存储在其中记录最后一次点击状态。
                // 判断localStorage中是否有变量c,有的话则使用里面的c,没有就用默认值red
                c: localStorage.c ? localStorage.c : 'red',
            },
            methods:{
                change(color){
                    this.c = color;
                    // 将最后一次的点击状态保存在localStorage中,方便下一次打开时找到变量c的值
                    localStorage.c = color;
                }
            }
        })
    </script>
    
    

    vue循环指令

    <div id="app">
        <!--循环指令:v-for="成员 in 容器"-->
    
        <!--循环数组:数组里可以是任意数据类型的数据-->
        <p v-for="v in lis">{{ v }}</p>
    
        <!--循环的成员可以为两个参数,第一个为value值,第二个为index索引-->
        <p v-for="(v,i) in lis">{{ i }}:{{ v }}</p>
    
        <!--实例:在每两个循环成员之间加一个|,不包括首尾-->
        <p>
            <span v-for="(v,i) in lis">
                <span v-if="i != 0"> | </span>
                {{ v }}
            </span>
        </p>
    
        <!--循环对象时:只接收一个参数只循环对象的值-->
        <p v-for="u in user">
            {{ u }}
        </p>
    
        <!--循环对象时:接收两个参数循环对象的值和键-->
        <p v-for="(u,k) in user">
            {{ k }}:{{ u }}
        </p>
    
        <!--循环对象时:接收三个参数循环对象的值、键和索引-->
        <p v-for="(u,k,i) in user">
            {{ i }}--{{ k }}:{{ u }}
        </p>
    
        <!--循环遍历列表套对象,显示出每个对象的键与值,并且在每两个对象之间添加分割线-->
        <div v-for="(stu,i) in students">
            <hr v-if="i != 0">
            <p v-for="(v,k) in stu">
                {{ k }}:{{ v }}
            </p>
        </div>
    </div>
    
    <script>
        new Vue({
            el: '#app',
            data:{
                lis:['西游记','水浒传','红楼梦','三国演义',[1,2,3],{'name':'wang'}],
                user:{'name':'wang','age':18,'gender':'male'},
                students: [
                    {
                        name: "Bob",
                        age: 18
                    },
                    {
                        name: "Tom",
                        age: 17
                    },
                    {
                        name: "Jerry",
                        age: 19
                    }
                ]
            },
        })
    </script>
    
    

    vue循环指令实例

    实现input框输入内容点击按钮同步到下方的评论内容中,并添加删除按钮删除评论。

    <div id="main">
        <input type="text" v-model="msg">
        <button @click="send">留言</button>
        <ul>
            <li v-for="(v,i) in comments" >
                <button @click="deletes(i)">删除</button>{{ v }}  
            </li>
        </ul>
    </div>
    
    <script>
        new Vue({
            el:'#main',
            data:{
                msg:'',
                comments:[]
            },
            methods:{
                send(){
                    if (this.msg) {
                        this.comments.push(this.msg);
                        this.msg = '';
                    }
                },
                deletes(i){
                    // splice() 三个参数:开始索引、操作长度、操作的结果的集合
                    // 比如最后一个参数不行就是删除,全为0就是删除首个
                    this.comments.splice(i,1);
                }
            }
        })
    </script>
    
    

    vue分隔符成员

    用来修改插值表达式的符号

    new Vue({
        el: '#app',
        data: {
            num: 100
        },
        delimiters: ['{[', ']}'],
    })
    
    

    vue计算属性成员

    <!--实现两个input框中的数据的和实时更新-->
    <div id="app">
        <input type="text" v-model="v1">
        +
        <input type="text" v-model="v2">
        =
        <label>{{ res }}</label>
    </div>
    
    <script>
        new Vue({
            el: '#app',
            data:{
                v1:'',
                v2:'',
            },
            // computed中定义的是方法属性,data中定义的也是属性,所以不需要重复定义属性,可以省略data里的
            // 方法属性的值来源于绑定的方法的返回值,类似于python中的property装饰器,将方法封装成数据属性
            // 方法属性必须在页面中渲染后,绑定的方法才会被调用
            // 方法中出现的所有变量都会被监听,任何变量发生值更新都会调用一次绑定方法,重新更新方法属性的值
            // 方法属性值不能手动设置,必须通过绑定的方法进行设置
            // js属于弱类型语言,将字符串转换为整型可以在字符串前加'+'即可,前提是该字符串可以转换为整型
            computed:{
                res(){
                    if (this.v1 && this.v2){
                        return +this.v1 + +this.v2
                    }else{
                        return '结果'
                    }
                    // return this.v1 && this.v2 ? +this.v1 + +this.v2 : '结果';
                }
            }
        })
    </script>
    
    

    vue属性的监听

    <div id="app">
        <p>
            姓名:<input type="text" v-model="full_name">
        </p>
        姓:<span>{{ first_name }}</span>
        名:<span>{{ last_name }}</span>
    </div>
    <script>
        new Vue({
            el: '#app',
            data:{
              full_name:'',
              first_name:'',
              last_name:'',
            },
            watch:{
                // watch中给已有的属性设置监听方法
                // 监听的属性值一旦发生改变,就会调用该监听方法,进行逻辑处理
                // 监听方法不需要返回值,return只有主动结束该方法的作用
                full_name(){
                    if (this.full_name.length == 2){
                        this.first_name = this.full_name.split('')[0];
                        this.last_name = this.full_name.split('')[1];
                    }
                }
            }
        })
    </script>
    
    

    vue组件

    组件:由html/css/js三部分组成的独立单位,可以类似于变量,重复使用

    ​ 组件其实就是vue实例(对象),一个组件就是一个vue实例

    ​ new Vue() 产生的也是实例(对象),所以也是组件,我们称之为 根组件

    ​ 一个页面建议只出现一个根组件

    ​ 组件的html页面结构由template实例成员提供

    ​ template提供的html结构是用来构建虚拟DOM的

    ​ 真实的DOM最终会被虚拟DOM替换

    ​ 根组件一般不提供template,就由挂载点el来提供构建虚拟DOM的页面结构

    ​ 根组件如果提供了template,还需要设置挂载点作为替换占位

    ​ template模板有且只有一个根标签

    let c1 = '';
    new Vue({
        el: '#app',
        data: {
            msg: '12345',
            c1: 'red'
        },
        template: `
            <div id="app">
            <p :style="{color: c1}">{{ msg }}</p>
            <p @click="clickAction">{{ msg }}</p>
            </div>
    		`,
        methods: {
            clickAction() {
                console.log(this.msg)
            }
        }
    })
    
    

    子组件:

    // 定义组件:组件就是一个普通对象,内部采用vue语法结构,被vue注册解释后,就会成为vue组件
    let tag = {
        template: `
    	<p>我是自定义的子组件</p>
    	`
    };
    // 注册组件:子组件必须在Vue实例成员components里注册了之后才可以使用。
    new Vue({
        el:'#app',
        components:{
            // 简写 tag,
            tag:tag,
        }
    })
    // 全局组件:不需要注册就可以直接使用
    Vue.component('mytag',{
        template:
        `<h1>我是全局组件</h1>`,
    });
    // 使用组件
    <div id="app">
        <tag></tag>
    	<mytag></mytag>
    </div>
    
    

    子组件的实际应用

    在子组件中渲染好一小块页面,并且在重复使用组件中可以实现记录点击次数功能。

    css
    <style>
        .wrap {
             calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
             200px;
            height: 260px;
            /*border: 1px solid black;*/
            background-color: rgba(10, 200, 30, 0.5);
            border-radius: 10px;
            float: left;
            margin: 10px;
        }
        .box img {
             100%;
            /*height: 200px;*/
            border-radius: 50%;
        }
        .box p {
            text-align: center;
        }
    </style>
    
    <div id="app">
        <div class="wrap">
            <tag></tag>
            <tag></tag>
            <tag></tag>
            <tag></tag>
        </div>
    </div>
    
    <script>
        let titleTag = {
            template: `
            <p>
                <b>
                    这是一种纯二哈
                </b>
            </p>
            `,
        };
    
        let tag = {
            template: `
            <div class="box">
                <img src="img/001.jpg" alt="">
                <title-tag />
                <p @click="fn">
                    锤它:<b>{{ num }}下</b>
                </p>
            </div>
            `,
            // 能被复用的组件(除了根组件),数据都要做局部化处理,
            // 因为复用组件后,组件的数据是相互独立的
            // data的值为绑定的方法的返回值,返回值是存放数据的字典
            data () {
                return {
                    num: 0
                }
            },
            methods: {
                fn() {
                    this.num ++
                }
            },
            components: {
                // 注册用到的titleTag子组件
                titleTag,
            }
        };
    	new Vue({
    		el: '#app',
            components: {
                // 注册tag子组件
    		    tag,
            }
    	});
    </script>
    
    

    vue组件传参-父传子

    基于上面的子组件实例,自定义一个数组,数组里存放多个对象,由对象的title和图片地址,自定义组件,将数组中的对象渲染到页面中,有几个对象就渲染几个。

    <div id="app">
        <div class="wrap">
            绑定dog属性指令,将循环的dog对象传到子组件中,子组件就能拿到当前的dog对象了
            <tag v-for="dog in dogs" :dog="dog"></tag>
        </div>
    </div>
    
    <script>
        let dogs = [
            {title: '二哈1号', img: 'img/1.jpg',},
            {title: '二哈2号', img: 'img/2.jpg',},
            {title: '二哈3号', img: 'img/3.jpg',},
            {title: '二哈4号', img: 'img/4.jpg',},
            {title: '二哈1号', img: 'img/1.jpg',},
            {title: '二哈2号', img: 'img/2.jpg',},
            {title: '二哈3号', img: 'img/3.jpg',},
            {title: '二哈4号', img: 'img/4.jpg',},
        ];
        let tag = {
            // 在子组件中,可以通过设置的自定义属性指令dog拿到外部给其传的值,props里面放一个数组,可以接收多个值。
            props:['dog'],
            template: `
            <div class="box">
                <img :src="dog.img">
                <p>
                <b>{{ dog.title }}</b>
                </p>
                <p @click="fn">
                    攻击:<b>{{ num }}</b>
                </p>
            </div>
            `,
            data() {
                return {
                    num: 0
                }
            },
            methods: {
                fn() {
                    this.num++
                }
            },
        };
        new Vue({
            el: '#app',
            data:{
              // 声明dogs数组变量
              dogs,
            },
            components: {
                // 注册tag子组件
                tag,
            }
        });
    </script>
    
    

    localStorage存数组

    ​ localStorage直接将数组存储进去读出来的是字符串,逗号分隔符就会影响取值,所以,是不能直接存储数组和对象的,需要利用JSON序列化为json数据才能存储,取数据也需要先反序列化才能转化为数组或对象。

    <script>
        localStorage.arr = JSON.stringify([1, 2, 3]);
        let res = JSON.parse(localStorage.arr);
        console.log(res, res[2]);
    </script>
    
    

    vue组件传参-子传父

    <style>
        ul {
            list-style: none;
        }
        .d-btn {
            font-size: 12px;
             15px;
            display: inline-block;
        }
        .d-btn:hover {
            color: red;
            cursor: pointer;
        }
    </style>
    <div id="app">
        <input type="text" v-model="msg">
        <button @click="send_comment">留言</button>
        <ul>
            <tag v-for="(v, i) in comments" :msg="v" :index="i" @f1="deleteMsg"/>
        </ul>
    </div>
    
    <script>
        let tag = {
            props: ['msg', 'index'],
            template: `
            <li>
                <i class="d-btn" @click="fn">x</i>
                <b>{{ msg }}</b>
            </li>
            `,
            methods: {
                fn () {
                    // 点击子级,要告诉父级删除第几条数据,因为comments在父级中
                    // 需要通知父级
                    this.$emit('f1', this.index);
                }
            }
        };
        new Vue({
            el: '#app',
            data: {
                msg: '',
                comments: localStorage.comments ? JSON.parse(localStorage.comments) : [],
            },
            components: {
                tag,
            },
            methods: {
                send_comment() {
                    if (this.msg) {
                        this.comments.push(this.msg);
                        this.msg = '';
                        localStorage.comments = JSON.stringify(this.comments);
                    }
                },
                deleteMsg(index) {
                    this.comments.splice(index, 1);
                    localStorage.comments = JSON.stringify(this.comments);
                }
            }
        })
    </script>
    
    
  • 相关阅读:
    TweenMax 前台脚本库
    如何使用CSS Sprites技术进行图片合并
    QQ群开放接口
    使用 Hexo 生成一套静态博客网页
    把表插入数据库
    WCF
    SOA
    登录验证
    登录菜单权限验证
    GetJsonByDataTable
  • 原文地址:https://www.cnblogs.com/dadazunzhe/p/11862770.html
Copyright © 2011-2022 走看看