(day65、66)Vue基础、指令、实例成员、JS函数this补充、冒泡排序

一、Vue基础

(一)什么是Vue

  1. 可以独立完成前后端分离式web项目的渐进式JavaScript框架

(二)为什么学习Vue

  1. 三大主流框架:Angular、React、Vue
  2. 先进的前端设计模式:MVVM
  3. 可以完全脱离服务器端,以前端代码复用的方式渲染整个页面:组件化开发
  4. 特点:单页面web应用、数据驱动思想、数据的双向绑定、虚拟DOM、组件化开发

(三)如何使用Vue

  1. Vue官网下载vue.js文件
  2. 通过script标签引入
  3. 在Vue实例中通过el进行挂载

二、Vue指令

(一)文本指令

  1. 插值表达式:{{ }},基于html的模板语法
  2. v-next:替换标签内的内容,不会解析html代码
  3. v-html:替换标签的内容,会解析html代码
  4. v-once:被控制的标签只能被赋值一次
<div id="app">
    <!--插值表达式-->
    <p>{{ msg }}</p>
    
    <!--v-next-->
    <p v-next="msg"></p>
    
    <!--v-html-->
    <p v-html="msg"></p>
    
    <!--v-once-->
    <p v-once>{{ msg }}</p>
</div>
<script>
    new Vue({
        el:"#app",
        data:{},
    })
</script>

(二)事件指令v-on

  1. 语法:v-on:事件名='方法变量'
  2. 简写:@事件名='方法变量'
  3. 方法变量不加括号,默认传入事件对象($event)
  4. 方法变量添加括号,代表自定义传参,系统不再传入事件对象,但是可以手动传入
 <div id="app">
        <p v-on:click="f1">{{ msg }}</p>
        <p @click="f1">{{ msg }}</p>
        <p @mouseover="f2" @mouseout="f3" @mouseup="f5" @mousemove="f6" @contextmenu="f7">{{ action }}</p>
        <hr>

        <!-- 事件变量,不添加(),默认会传事件对象: $event -->
        <!-- 事件变量,添加(),代表要自定义传参,系统不再传入事件对象,但是可以手动传入事件对象 -->
        <p @click="f8($event, '第一个')">{{ info }}</p>
        <p @click="f8($event, '第二个')">{{ info }}</p>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: '点击切换',
            action: '鼠标事件',
            info: '确定点击者'
        },
        methods: {
            f1 () {
                this.msg = '点击了'
            },
            f2 () {
                this.action = '悬浮';
                console.log('悬浮')
            },
            f3 () {
                this.action = '离开'
            },
            f4 () {
                this.action = '按下'
            },
            f5 () {
                this.action = '抬起'
            },
            f6 () {
                this.action = '移动';
                console.log('移动')
            },
            f7 () {
                this.action = '右键';
            },
            f8 (ev, argv) {
                console.log(ev, argv);
                this.info = argv + '点击了';
            }
        }
    })
</script>

(三)属性指令v-bind

  1. 语法:v-bind:属性名='变量'
  2. 简写::属性名='变量'
  • class属性绑定
    1. 直接绑定
    2. []:绑定多个类名
    3. '':引号内的内容为常量
    4. {}:类名状态,控制类名是否生效
  • style属性绑定
    1. 直接绑定:<p :style="myStyle">样式属性</p>
    2. 定制化绑定:`<p :style="{width: w,height: h, backgroundColor: bgc}">样式属性</p>
  • Vue中使用html中css样式中的background-color要变形成驼峰体backgroundColor
<!--绑定全局自定义属性-->
<P v-bind:abc="abc"></P>
<!--直接以原来字符串形式绑定属性,即为一个常量-->
<p v-bind:title=" 'abc' "></p>

<!--单类名绑定-->
<p :class = "c1"></p>
<!--多类名绑定-->
<p :class = "[c2,c3]"></p>
<!--类名状态绑定 var指代可以为一个变量,可以在Vue实例中实时控制其类是否生效-->
<p :class = "{c4:true|false|var}"></p>

<!--样式绑定-->
<div :style:"div_style"></div>
<div :style:"{width:w, height:h, backgroudColor:bc}"></div>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el:'#app',
        c1:'p1',
        c2:'p2',
        c3:'p3',
        
        div_style:{
            width:"100px",
            height:"100px",
            backgroundColor:"red"
        }
        
        w:"100px",
        h:"100px",
        bc:"red"
        
    })
</script>

(四)表单指令v-model

  1. 语法:v-model="变量",变量值与表单标签的value相关
  2. v-model可以实现数据的双向绑定,绑定的变量值可以影响到表单标签内的值,通过表单标签内的值也会影响绑定的变量值
  3. 单选框时,以name进行分组,绑定的变量存储的是单选框的value值
  4. 单一复选框时,绑定的变量存储的是true|false,或者自定义替换的值
  5. 多复选框,绑定的变量是以数组存储多复选框的内选中的value值
<div id="app">
    <!-- v-model针对于表单元素 -->
    <form action="" method="get">
        <!-- 1、双向绑定:服务于文本输入框 -->
        <!-- v-model存储的值为输入框的value值 -->
        <div>
            <input type="text" name="usr" v-model="in_val">
            <input type="password" name="ps" v-model="in_val" >
            <textarea name="info" v-model="in_val"></textarea>
        </div>

        <!-- 2、单选框 -->
        <div>
            <!-- 单选框是以name进行分组,同组中只能发生单选 -->
            <!-- v-model存储的值为单选框的value值 -->
            男:<input type="radio" name="sex" value="男" v-model="ra_val">
            女:<input type="radio" name="sex" value="女" v-model="ra_val">
            {{ ra_val }}
        </div>

        <!-- 3、单一复选框 -->
        <!-- v-model存储的值为true|false -->
        <!-- 或者为自定义替换的值 -->
        <div>
            <input type="checkbox" v-model='sin_val' true-value="选中" false-value="未选中" />
            {{ sin_val }}
        </div>

        <!-- 4、多复选框 -->
        <!-- v-model存储的值为存储值多复选框value的数组 -->
        <div>
            <input type="checkbox" value="喜好男的" name="cless" v-model='more_val' />
            <input type="checkbox" value="喜好女的" name="cless" v-model='more_val' />
            <input type="checkbox" value="不挑" name="cless" v-model='more_val' />
            {{ more_val }}
        </div>
    </form>
</div>

<script type="text/javascript">
    new Vue({
        el: '#app',
        data: {
            in_val: '',
            // 默认值可以决定单选框默认选项
            ra_val: '男',
            // 默认值为true,单一复选框为选中,反之false为不选中
            sin_val: '',
            // 数组中存在的值对应的复选框默认为选中状态
            more_val: ['喜好女的','不挑']
        }
    })
</script>

(五)条件指令v-if

  1. v-show="布尔变量":布尔变量为false时,隐藏该标签,隐藏方式为通过style="display:none"实现,较少使用

  2. v-if="布尔变量":布尔变量为false时,隐藏该标签,隐藏方式为直接不渲染,从数据安全方面,推荐使用

    • v-if="布尔变量"
    • v-else-if="布尔变量"
    • v-else
<div id="app" v-cloak>
    <!--条件指令:
        v-show="布尔变量"   隐藏时,采用display:none进行渲染
        v-if="布尔变量"     隐藏时,不再页面中渲染(保证不渲染的数据泄露)
        -----------------------------
        v-if | v-else-if | v-else
    -->
    <div class="box r" v-show="is_show"></div>
    <div class="box b" v-if="is_show"></div>
    <div class="wrap">
        <button @click="page='r_page'" :class="{active: page==='r_page'}">红</button>
        <button @click="page='b_page'" :class="{active: page==='b_page'}">蓝</button>
        <button @click="page='g_page'" :class="{active: page==='g_page'}">绿</button>
        
        <div class="box r" v-if="page === 'r_page'"></div>
        <div class="box b" v-else-if="page === 'b_page'">11</div>
        <div class="box g" v-else></div>
    </div>
</div>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            is_show: false,
            page: 'r_page'
        }
    })
</script>
</html>

(六)循环指令v-for

(1)用法

  1. 字符串和列表:v-for="(v,i) in str|arr",v为值,i为索引
  2. 字典:v-for="(v,k,i) in dic",v为值,k为键,i为索引
<div id="app">
    <h1>{{ msg }}</h1>
    <!-- n为遍历的元素值 -->
    <ul>
        <li v-for="n in list">{{ n }}</li>
    </ul>
    
    <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 -->
    <ul>
        <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li>
    </ul>

    <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 -->
    <ul>
        <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li>
    </ul>

    <!-- 遍历的嵌套 -->
    <div v-for="(person, index) in persons" :key="index" style="height: 21px;">
        <div v-for="(v, k) in person" :key="k" style="float: left;">{{ k }} : {{ v }}&nbsp;&nbsp;&nbsp;</div>
    </div>
</div>
<script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
            msg: "列表渲染",
            list: [1, 2, 3, 4, 5],
            dic: {
                name: 'zero',
                age: 88888,
                gender: 'god'
            },
            persons: [
                {name: "zero", age: 8},
                {name: "egon", age: 78},
                {name: "liuXX", age: 77},
                {name: "yXX", age: 38}
            ]
        }
    })
</script>

(2)基于循环指令的todolist案例

  • 前端数据库
    1. localStorage:永久存储
    2. sessionSrotage:临时存储(所属页面标签关闭后清空)
    3. 数组等类型传输交互要先序列化成JSON
    4. 清空数据库:localStorage.clear();
    5. 可以把localStorage和sessionStorage当做字典使用
<div id="app">
    <input type="text" v-model="comment">
    <button type="button" @click="send_msg">留言</button>
    <ul>
        <li v-for="(msg, i) in msgs" @click="delete_msg(i)">{{ msg }}</li>
    </ul>
</div>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            comment: '',
            msgs: localStorage.msgs ? JSON.parse(localStorage.msgs) : [],

        },
        methods: {
            send_msg() {
                // 将comment添加到msgs数组中:unshift push 首尾增 | shift pop 首尾删
                // this.msgs.push(this.comment);

                // 数组操作最全方法:splice(begin_index, count, ...args)
                // this.msgs.splice(0, 2);

                if (!this.comment) {
                    alert('请输入内容');
                    return false;
                }
                this.msgs.push(this.comment);
                this.comment = '';

                localStorage.msgs = JSON.stringify(this.msgs);
            },
            delete_msg(index) {
                this.msgs.splice(index, 1);
                localStorage.msgs = JSON.stringify(this.msgs);
            }
        }
    })
    
     // 前台数据库
    // localStorage: 永久存储
    // sessionStorage:临时存储(所属页面标签被关闭后,清空)

    // 存
    // localStorage.n1 = 10;
    // sessionStorage.n2 = 20;

    // 取
    // console.log(localStorage.n1);
    // console.log(sessionStorage.n2);

    // 数组等类型需要先序列化成JSON
    // localStorage.arr = JSON.stringify([1, 2, 3]);
    // console.log(JSON.parse(localStorage.arr));

    // 清空数据库
    // localStorage.clear();
</script>

(七)斗篷指令v-cloak

  1. vue引入放在下方时,会因为没有vue环境造成加载时的一瞬间闪烁
  2. 可以把vue引入放在head中解决,但是在网络较差时会有加载不了的问题
  3. 通过添加v-cloak指令,并在style中添加[v-cloak]:{dispaly:none},米面闪烁
<style type="text/css">
    [v-cloak] { display: none; }
</style>

<div id="app" v-cloak>
    {{ msg }}
</div>

<script src="js/vue.min.js"></script>
<script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
            msg: "message"
        }
    })
</script>
<!-- 避免页面闪烁-->

三、Vue实例成员

  1. 在Vue实例外部或者其他实例中,可以定义一个变量接受该实例
  2. Vue实例中的methods中,this指代vue实例本身
  3. html中-相连的参数或者变量在Vue中要转换成驼峰体,比如background-color要转换成backgroundColor,反之亦然

(一)el:实例

  1. 挂载点:Vue实例和页面标签建立关联
  2. 挂载点采用css3选择器语法,但是只能匹配到第一次检索的结果,因此通常挂载点都采用id选择器(唯一性)
  3. html和body不能作为挂载点
<div id="app">
    代码
</div>

<script>
    new Vue({
        el:'#app'
    })
    // 实例与页面挂载点一一对应 
    // 一个页面中可以出现多个实例对应多个挂载点
    // 实例只操作挂载点内部内容
</script>

(二)data:数据

  1. 插件表达式:一种文本指令,支持html模板语法为{{ 变量名 }}
  2. data为插件表达式中的变量提供数据
  3. data中的数据可以通过Vue实例直接或者间接访问
<div id="app">
    {{ msg }}
</div>
<script>
    var app = new Vue({
        el:"#app",
        data:{
          msg:"数据"  
        },
    })
    // 在Vue实例外部或者其他实例中,可以定义一个变量接受该实例
    console.log(app.$data.msg)
    console.log(app.msg)
</script>

(三)methods:方法

  1. 基于v-on:事件绑定指令
  2. methods为事件提供方法(逻辑处理)
  3. 方法中this指代Vue实例,相当于python中函数的self
<div id="app">
    <p v-on:click='pClick'>测试</p>
</div>
<script>
    var app = new Vue({
        el:'#app',
        methods:{
            pClick () {
                // 点击测试
            }
        }
    })
</script>

(四)computed:计算

  1. 应用于一个变量值依赖多个变量值,比如简单计算器功能(实时输出两个值的和)
  2. 绑定方法中出现的所有变量都会被监听,只要发生变化就会重新出发一次该方法
  3. 方法属性必须要渲染才能生效,渲染的值即为其返回值
  4. computed中声明的参数名,data中不能重复声明
<div id="app">
    <input type='text' v-model="a"> <!--v-model为表单指令,相当于value-->
    <input type='text' v-model="b">
    <div>{{ c }}</div>
</div>
<script>
    new Vue({
        el:"#app",
        data:{
            a:'',
            b:'',
        },
        computed:{
            c:function(){
                return this.a + this .b
            }
        }
    })
</script>

(五)watch:监听

  1. 用于解决多个变量值依赖于一个变量值,比如获取姓名的姓和名
  2. 监听的属性需要在data中声明,监听方法不需要返回值
  3. 监听的方法名就是监听的属性名,该属性值发生改变时就会回调监听方法
  4. 监听方法有两个回调参数:当前值和上一次值
<div id="app">
    <input type="text" v-model='fullname'>
    <div>
        {{ a }}
        {{ b }}
    </div>
</div>
<script>
    new Vue({
        el:"#app",
        data:{
            fullname:'',
            surname:'',
            name:"",
        },
        watch:{
            fullname:(n,o){ // n是监听的属性当前值,o是其上一次的值
                this.surname = this.fullname[0];
                this.name = this.fullname[1];
            }
        }
    })
</script>

(六)delemiters:分割符

  1. 可以修改插值表达式符号,避免和Django框架中的{{ }}模板语法冲突
  2. delimiters的值为一个列表:['[{','}]'],即修改为[{ }]
<div id="#app">
    ${ msg }
</div>
<script>
    new Vue({
        el:"#app",
        data:{
            msg:"message"
        },
        delimiters:['${','}']
    })
</script>

(七)filters:过滤器

  1. 可以对多个值进行过滤,会将值本身和括号内的值一起当做参数传给过滤器方法
  2. 过滤的结果可以再进行过滤(过滤的串联)
<div id="app">
    <!--
    总结:
    1、在filters成员中定义过滤器方法
    2、可以对多个值进行过滤,过滤时还可以额外传入辅助参数
    3、过滤的结果可以再进行下一次过滤(过滤的串联)
    -->
    <p>{{ num | f1 }}</p>
    <p>{{ a, b | f2(30, 40) | f3 }}</p>
</div>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            num: 10,
            a: 10,
            b: 20,
        },
        filters: {
            // 传入所有要过滤的条件,返回值就是过滤的结果
            f1 (num) {
                console.log(num);
                return num * 10;
            },
            f2 (a, b, c, d) {
                console.log(a, b, c, d);
                return a + b + c + d;
            },
            f3 (num) {
                return num * num;
            }
        }
    })
</script>                                   

四、JS函数补充

(一)构造函数和自定义对象

  1. JS中函数名大写约定俗成为构造函数,等同于python中的类,可以定义自己的属性和方法,并且可以通过new实例化出来一个函数对象
  2. 自定义对象也可以当做一个对象,可以定义自己的属性和方法
  3. 构造函数中的方法和funtion中的this都是指代其实例化出来的对象
  4. 自定义对象中的方法和funtion中的this都是指代对象本身
// 1. 构造函数 == 类
function F2(name) {
    this.name = name;
    this.eat = function (food) {
        console.log(this.name + '在' + food);
    }
}
let ff1 = new F2("Bob");
console.log(ff1.name);

let ff2 = new F2("Tom");
console.log(ff2.name);

ff1.eat('饺子');
ff2.eat('sao子面');

// 2. 自定义对象
let obj = {
    name: 'Jerry',
    eat: function (food) {
        console.log(this.name + '在' + food)
    },
    // eat(food) {  // 方法的语法
    //     console.log(this.name + '在' + food)
    // }
};
console.log(obj.name);
obj.eat('hotdog');

(二)变量声明

  1. 不加声明词:全局变量
  2. const:常量,不能重复定义,具备块级作用域
  3. let:在哪里声明就是什么变量,不能重复定义,具备块级作用域
  4. var:全局变量
for (let i = 0; i < 5; i++) {
    console.log(i);
}
console.log(i); // undefined
// 使用var和不声明时,此时i为5

(三)箭头函数

  1. 箭头函数可以省略function
  2. 箭头函数没有函数体,只有返回值时,可以省略{}
  3. 箭头函数参数只有一个,可以省略()
// 匿名函数
let f2 = function () {
    console.log('f2 run');
};
f2();

// 1. 省略function
let f3 = () => {
    console.log('f3 run');
};
f3();

// 2. 如果箭头函数没有函数体,只有返回值
let f4 = (n1, n2) =>  n1 + n2;
let res = f4(10, 25);
console.log(res);

// 3. 如果箭头函数参数列表只有一个,可以省略()
let f5 = num => num * 10;
res = f5(10);
console.log(res);

(四)箭头函数、function和方法的区别

  1. function和方法中的this指代调用者
  2. 箭头函数中的this指代调用者的上一层
  • 解决

    可以通过声明_this变量提前接收原先指代自定义对象的this

// 自定义对象
let obj = {
    name: 'Jerry',
    // 1. function中的this指代obj
    eat: function (food) {
        console.log(this)
        console.log(this.name + '在吃' + food)
    },
    // 2. 箭头函数中的this指代obj的上一层:window事件
    eat: food => {
        console.log(this);
        console.log(this.name + '在' + food)
    },
    // 3. 方法中的this指代obj
    eat(food) {  // 方法的语法
        console.log(this);
        console.log(this.name + '在' + food)
    }
};
obj.eat('food');

// Vue实例
new Vue({
        data: {
            res: ''
        },
        methods: {
            fn () {
                // axios插件
                let _this = this;
                this.$axios({
                    url: '',
                    method: 'get',
                    data: {

                    },
                }).then(function (response) {
                    _this.res = response.data;  // 如果是this,指代的是调用者$axios
                })
            },
            
            fn1 () {
                // axios插件
                this.$axios({
                    url: '',
                    method: 'get',
                    data: {

                    },
                }).then(response => {
                    this.res = response.data; // 指代调用者$axios的上一层vue
                })
            }
        }
    })

五、冒泡排序

  1. 逐个比较,根据大小关系交换位置,
  • 公式
// 按照分数进行排名
    for (let i=0; i<可迭代对象.length-1; i++) {
        for (let j=0; j<可迭代对象.length-1-i; j++) {
            // 处理条件即可
            if ( a>b ) {  // 排序方式
                // 交叉赋值,互换位置
                a,b = b,a
            }
        }
    }
  • 实例
// 对数组排序
let arr = [3, 2, 5, 4, 1];

for (let i = 0; i < arr.length - 1; i++) {  // 外层循环控制趟数
        for (let j = 0; j < arr.length - 1 - i; j++) {  // 内存循环控制比较次数
            if (arr[j] > arr[j + 1]) {
                let temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }

// 对字典排序

stus = [
        {
            name: 'Bob',
            grade: 98
        },
        {
            name: 'Tom',
            grade: 87
        },
        {
            name: 'Jerry',
            grade: 92
        },
    ];

// 按照分数进行排名
    for (let i=0; i<stus.length-1; i++) {
        for (let j=0; j<stus.length-1-i; j++) {
            // 处理条件即可
            if (stus[j].grade > stus[j + 1].grade) {
                let temp = stus[j];
                stus[j] = stus[j + 1];
                stus[j + 1] = temp;
            }
        }
    }

猜你喜欢

转载自www.cnblogs.com/wick2019/p/12079941.html
今日推荐