zoukankan      html  css  js  c++  java
  • day65——day69

    DAY65

    课堂笔记

    在day65代码文件夹下—》新建js文件,然后导入在官网下载好的Vue.js文件
    
    
    ​```python
    """
    1、http与https
    http vs tcp:应用层,传输层,http协议传输层采用的是tcp
    http特点:无状态,无连接,先客户端发出请求,服务器端一定做出响应
    https:在http协议之上增加ssl安全认证
    
    2、前端布局
    流式布局
    响应式布局
    盒模型布局
    浮动布局
    定位布局
    
    3、ORM
    """
    ​```
    
    
    
    ## 课程安排
    
    ​```python
    """
    Vue:
    	基础:指令、实例成员、组件(组件间传参)
    	项目:基于组件开发、插件(vue-router、vuex、axios、vue-cookies、jq+bs、element-ui)
    
    DRF:
    	全称:django-restframework:完成前后台 分离式 django项目
    	知识点:
    		请求、响应、渲染、解析、异常
    		序列化组件、三大认证、视图家族(CBV)
    		分页、筛选、搜索、排序
    
    Luffy:
    	目的:了解前后台分离项目,了解公司开发项目的模式
    	知识点:git、多方式登录、第三方短信认证、支付宝、上线
    """
    ​```
    
    
    
    
    
    ## Vue
    
    ​```python
    """
    前台框架:angular、react、vue
    	vue:有前两大框架优点,摈弃缺点;没有前两个框架健全 
    	vue优点:中文API、单页面应用、组件化开发、数据双向绑定、虚拟DOM、数据驱动思想(相比DOM驱动)
    
    """
    ​```
    
    
    
    
    
    ## 知识总结
    
    ​```python
    """
    1、vue框架的优势
    
    2、vue如何在页面中引入
    	1)通过script标签引入vue.js环境
    	2)创建vue实例
    	3)通过el进行挂载
    	
    3、插值表达式
    	{{ 变量以及变量的简单运算 }}
    	
    4、文本指令
    	{{ }} | v-text | v-html | v-once
    	
    5、方法指令
    	v-on:事件="变量" | @事件="变量" | @事件="变量()" | @事件="变量($event, ...)"
    	
    6、属性指令
    	v-bind:属性="变量"  |  :属性="变量"
    	
    	:title="t1"
    	:class="c1"  |  :class="[c1, c2]"  |   :class="{c1: true}"
    	:style="s1"  |  :style="{color: c1, fontSize: f1}"
    		s1是字典变量,c1和f1变量分别控制字体颜色和大小
    	
    7、js补充
    	function可以作为类,内部会有this
    	箭头函数内部没有this
    	{}里面出现的函数称之为方法: 方法名(){}
    """
    ​```
    

    1、vue实例

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>Vue实例</title>
        <style>
            body {
                user-select: none;
            }
        </style>
    </head>
    <body>
        <section>
            <div id="d1">
                {{ msg }}
                <p v-on:click="pClick" v-bind:style="pStyle">{{ info }}</p>
            </div>
            <hr>
            <div class="d2">
                {{ }}
            </div>
            <hr>
            <div class="d2">
                {{ }}
            </div>
        </section>
    </body>
    <script src="js/vue.js"></script>
    <script>
        `
        console.log(Vue);
        let app = new Vue({
            el: '#d1',  // 挂载点:vue实例与页面标签建立关联
        });
    
        new Vue({
            el: '.d2',  // 挂载点采用的是css3选择器语法,但是只能匹配第一次检索到的结果
        });
        `;
        // 总结:
        // 1、通常挂载点都采用id选择器(唯一性)
        // 2、html与body标签不能作为挂载点(组件知识点解释)
    
        // new Vue({
        //     el: 'body'
        // })
        let app = new Vue({
            el: 'section',
            data: {  // data为挂载点内部提供数据
                msg: 'message',
                info: '信息',
                pStyle: {
                    color: 'yellowgreen'
                }
            },
            methods: {
                pClick: function () {
                    if (app.pStyle.color !== 'yellowgreen') {
                        app.pStyle.color = 'yellowgreen'
                    } else {
                        app.pStyle.color = 'red'
                    }
                    console.log(app.msg);
                    console.log(app.pClick);
                    console.log(this.msg);
                    console.log(this.pClick);
                }
            }
        });
    
        // 声明的实例是否用一个变量接收
        // 1、在实例内部不需要,用this就代表当前vue实例本身
        // 2、在实例外部或其他实例内部需要,定义一个变量接收new Vue()产生的实例
        console.log(app.msg)
    
    </script>
    </html>
    

    2、插值表达式

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <p>{{ msg }}</p>
            <p>{{ num * 10 }}</p>
            <p>{{ msg + num }}</p>
            <p>{{ msg[1] }}</p>
            <p>{{ msg.split('') }}</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'msg',
                num: 10
            }
        })
    </script>
    </html>
    

    3、文本指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <!--
                文本指令:
                1、{{ }}
                2、v-text:不能解析html语法的文本,会原样输出
                3、v-html:能解析html语法的文本
                4、v-once:处理的标签的内容只能被解析一次
            -->
            <p>{{ msg.split('') }}</p>
            <p v-text="msg.split('')">12345</p>
            <p v-text="info"></p>
            <p v-html="info"></p>
    
            <hr>
            <p v-on:click="pClick" v-once>{{ msg + info }}</p>
            <p>{{ msg }}</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'message',
                info: '<i>info</i>'
            },
            methods: {
                pClick: function () {
                    this.msg = '信息'
                }
            }
        })
    </script>
    </html>
    

    4、面向对象js

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>面向对象js</title>
    </head>
    <body>
        <h1>面向对象js</h1>
    </body>
    <script>
        // undefined、null、string、number、boolean、object(Array)、function
        // var、let、const、不写
    
        // object(Array)、function
    
        function f1() {
            console.log('f1 run')
        }
        f1();
    
    
        // 构造函数 == 类
        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子面');
    
    
        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');
    </script>
    </html>
    

    5、js函数补充

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>函数补充</title>
    </head>
    <body>
        <h1>函数补充</h1>
    </body>
    <script>
        // ES5 ES6
    
    
    
        function f() {
            d = 40; // 全局变量
        }
        f();
    
    
        console.log(d);
    
        const c = 30;  // 常量
        console.log(c);
    
    
        if (1) {
            var a = 10;
            let b = 20;  // let、const定义的变量不能重复定义,且具备块级作用域
        }
        console.log(a);
        // console.log(b);
    
        for (let i = 0; i < 5; i++) {
            console.log(i);
        }
        // console.log(i);
        // console.log(i);
        // console.log(i);
    
    
        function f1() {
            console.log('f1 run');
        }
        let f2 = function () {
            console.log('f2 run');
        };
        f2();
    
        let f3 = () => {
            console.log('f3 run');
        };
        f3();
    
        // 如果箭头函数没有函数体,只有返回值
        let f4 = (n1, n2) =>  n1 + n2;
        let res = f4(10, 25);
        console.log(res);
    
        // 如果箭头函数参数列表只有一个,可以省略()
        let f5 = num => num * 10;
        res = f5(10);
        console.log(res);
    
    
        // 重点:function、箭头函数、方法都具有本质区别
        let obj = {
            name: 'Jerry',
            // eat: function (food) {
            //     console.log(this);
            //     console.log(this.name + '在吃' + food)
            // },
            // eat: food => {
            //     console.log(this);
            //     console.log(this.name + '在' + food)
            // },
            eat(food) {  // 方法的语法
                console.log(this);
                console.log(this.name + '在' + food)
            }
        };
        obj.eat('food');
    
        new Vue({
            data: {
                res: ''
            },
            methods: {
                fn () {
                    // axios插件
                    let _this = this;
                    this.$axios({
                        url: '',
                        method: 'get',
                        data: {
    
                        },
                    }).then(function (response) {
                        _this.res = response.data;
                    })
                },
                fn1 () {
                    // axios插件
                    this.$axios({
                        url: '',
                        method: 'get',
                        data: {
    
                        },
                    }).then(response => {
                        //this指的是axios插件
                        this.res = response.data;
                    })
                }
            }
        })
    </script>
    </html>
    

    6、事件指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <!--
            事件指令:   v-on:事件名="方法变量"
            简写:  @事件名="方法变量"
            -->
            <p v-on:click="f1">{{ msg }}</p>
            <p @click="f1">{{ msg }}</p>
            <hr>
            <!--mouseover mouseenter  |  mouseout mouseleave-->
            <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>
    </html>
    

    7、属性指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .d1 {
                 200px;
                height: 200px;
                background-color: orange;
            }
            .d2 {
                border-radius: 50%;
            }
            .d3 {
                border-radius: 20%;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <!--属性指令:   v-bind:属性名="变量"
                简写:       :属性名="变量"
            -->
            <p style="color: red" class="dd1" abc="def" title="悬浮提示">红色字体</p>
    
            <!--1、简单使用-->
            <p v-bind:title="pTitle" :abc="def" @click="changeImg">简单使用</p>
            <!--<img :src="img_src" alt="">-->
    
    
            <!--2、class属性绑定-->
            <!--c1变量的值就是类名-->
            <p :class="c1"></p>
    
            <!--多类名可以用[]语法,采用多个变量来控制-->
            <p :class="[c2, c3]"></p>
            <!--选择器位可以设置为变量,也可以设置为常量-->
            <p :class="['d1', c4]"></p>
    
            <!--{类名: 布尔值}控制某类名是否起作用-->
            <!--<p :class="{x1: false}"></p>-->
            <!--多种语法混用-->
            <p :class="['d1', {d2: is_true}]" @click="is_true = !is_true"></p>
    
    
            <!--3、style属性绑定(了解)-->
            <p :style="myStyle">样式属性</p>
            <p :style="{ w,height: h, backgroundColor: bgc}">样式属性</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                pTitle: '简单使用',
                def: '自定义属性',
                img_src: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3819296004,574391848&fm=26&gp=0.jpg',
                c1: 'd1 d2',
                c2: 'd1',
                c3: 'd3',
                c4: 'd3',
                is_true: true,
                myStyle: {
                     '100px',
                    height: '100px',
                    backgroundColor: 'red'
                },
                w: '200px',
                h: '100px',
                bgc: 'green'
            },
            methods: {
                changeImg() {
                    this.img_src = 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1371195756,4187769521&fm=26&gp=0.jpg'
                }
            }
        })
    </script>
    </html>
    
    
    
    
    
    
    
    //今日日考:
    1.简述一下vue框架的优点
    2.vue实例通过什么与页面结构建立关联?有哪些要注意的点
    3.写出文本,属性与事件指令
    

    DAY66

    课堂笔记

    ## 复习
    
    ​```python
    """
    1、vue框架的优势
    	中文API
    	单一面应用 - 提升移动端app运行速度
    	数据的双向绑定 - 变量全局通用
    	数据驱动 - 只用考虑数据,不需要在意DOM结构
    	虚拟DOM - 缓存机制
    
    2、vue如何在页面中引入
    	1)通过script标签引入vue.js环境
    	2)创建vue实例
    	3)通过el进行挂载
    	
    	new Vue({
    		el: '#app',  // css3选择器,唯一,html、body不能作为挂载点,一个页面可以有多个实例对应多个挂载点
    	})
    	
    3、插值表达式
    	{{ 变量以及变量的简单运算 }}
    	{{ ((num * 10) + 'string').split('')[0] }}
    	
    4、文本指令
    	{{ }} | v-text | v-html | v-once
    	
    5、方法指令
    	v-on:事件="变量" | @事件="变量" | @事件="变量()" | @事件="变量($event, ...)"
    	
    	@click='btnClick'
    	btnClick(ev) {}
    	
    	@click='btnClick(1, 2, $event)'
    	btnClick(n1, n2, ev) {}
    	btnClick(...args) {}
    	
    	
    6、属性指令
    	v-bind:属性="变量"  |  :属性="变量"
    	
    	:title="t1"
    	:class="c1"  |  :class="[c1, c2]"  |   :class="{c1: true}"
    	:style="s1"  |  :style="{color: c1, fontSize: f1}"
    		s1是字典变量,c1和f1变量分别控制字体颜色和大小
    
    7、js补充
    	function可以作为类,内部会有this
    	箭头函数内部没有this
    	{}里面出现的函数称之为方法: 方法名(){}
    	
    	function Fn(name){this.name = name}
    	let f1 = new Fn('Bob')
    	
    	let f2 = ()=>{}
    	
    	{
    		f3(){}
    	}
    """
    ​```
    
    
    
    ## 课堂内容
    
    ​```python
    """
    1、表单指令:
    	v-model="变量"   变量与value有关
    	普通:变量就代表value值
    	单选框:变量为多个单选框中的某一个value值
    	单一复选框:变量为布尔,代表是否选中
    	多复选框:变量为数组,存放选中的选项value
    	
    2、条件指令:
    	v-show:  display:none
    	v-if:    不渲染
    	v-if | v-else-if | v-else
    	
    3、循环指令:
    	v-for="(v, i) in str|arr"
    	v-for="(v, k, i) in dic"
    
    4、sessionStorage | localStorage
    
    5、分隔符:delimiters: ['{{', '}}'],
    
    6、过滤器:
    	{{ n1, n2 | f1(30) | f2 }}
    	
    	filters: {
    		f1(n1,n2,n3) {return 过滤结果},
    		f2(f1的res) {return 过滤结果},
    	}
    
    7、计算属性:
    	computed: {
    		result() {
    			// 一个方法属性值依赖于多个变量
    			return this.n1 + this.n2;
    		}
    	}
    
    8、监听属性:
    	watch: {
    		full_name(n, o) {
    			this.first_name = n.split('')[0]
    			this.last_name = n.split('')[1]
    		}
    	}
    	
    9、冒泡排序:
    	for (let i=0; i<arr.length-1; i++) {  // 趟数
            for (let j=0; j<arr.length-1-i; j++) {  // 比较次数
                // 处理条件即可
                if (arr[j]参数 > stus[j + 1]参数) {
                    let temp = stus[j];
                    stus[j] = stus[j + 1];
                    stus[j + 1] = temp;
                }
            }
        }
    
    """
    ​```
    
    
    
    ## A作业(必做)
    
    ​```python
    """
    1、按照上方 知识点总结 模块,总结今天所学知识点;
    2、先有一下成绩单数据
    scores = [
    	{ name: 'Bob', math: 97, chinese: 89, english: 67 },
    	{ name: 'Tom', math: 67, chinese: 52, english: 98 },
    	{ name: 'Jerry', math: 72, chinese: 87, english: 89 },
    	{ name: 'Ben', math: 92, chinese: 87, english: 59 },
    	{ name: 'Chan', math: 47, chinese: 85, english: 92 },
    ]
    用table表格标签渲染以上数据,表格第一列是学生总分排名,最后一列是学生总分;
    
    3、还是采用上方相同的数据,采用相同的渲染规则,只渲染所有科目都及格了的学生。
    """
    ​```
    
    
    
    ## B作业(选做)
    
    ​```python
    """
    1、还是采用上方相同的数据,添加筛选规则:
    	i)有三个按钮:语文、数学、外语,点击谁谁高亮,且当前筛选规则采用哪门学科
    	ii)两个输入框,【】~【】,前面天最小分数,后面填最大分数,全部设置完毕后,表格的数据会被更新只渲染满足所有条件的结果
    	举例:点击语文,输入【86】~【87】,那就只会渲染Jerry和Ben两条数据
    """
    ​```
    
    
    
    
    

    1、表单指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>表单指令</title>
    </head>
    <body>
    <div id="app">
        <!--表单指令:  v-model="变量"   变量值与表单标签的value相关
            v-model可以实现数据的双向绑定:v-model绑定的变量值可以影响表单标签的值,反过来单标签的值也可以影响变量的值
        -->
        <form action="">
            <!--重点-->
            <input type="text" name="usr" id="usr" placeholder="请输入账号" v-model="v1">
            <input type="text" v-model="v1">
            {{ v1 }}
    
            <hr>
    
            <!--1.单选框-->
            男:<input type="radio" name="sex" value="male" v-model="v2">
            女:<input type="radio" name="sex" value="female" v-model="v2">
            {{ v2 }}
    
            <hr>
            
            <!--2.单一复选框-->
            卖身契:同意 <input type="checkbox" name="agree" v-model="v3">
            {{ v3 }}
    
            <hr>
    
            <!--3.多复选框-->
            爱好:<br>
            男:<input type="checkbox" name="hobbies" value="male" v-model="v4">
            女:<input type="checkbox" name="hobbies" value="female" v-model="v4">
            哇塞:<input type="checkbox" name="hobbies" value="other" v-model="v4">
            {{ v4 }}
            <hr>
    
            <button type="submit">提交</button>
        </form>
    </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                v1: '123',
                v2: 'male',
                v3: false,
                v4: ['male', 'female']
            }
        })
    </script>
    </html>
    

    2、条件指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            [v-cloak] { display: none; }
    
            .box {
                 200px;
                height: 200px;
            }
            .r {background-color: red}
            .b {background-color: blue}
            .g {background-color: green}
    
            .active {
                background-color: deeppink;
            }
        </style>
    
    </head>
    <body>
        <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>
            <hr>
    
            <div class="wrap">
                <div>
                    <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>
                <div class="box r" v-if="page === 'r_page'"></div>
                <div class="box b" v-else-if="page === 'b_page'"></div>
                <div class="box g" v-else></div>
            </div>
    
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                is_show: false,
                page: 'r_page'
            }
        })
    </script>
    </html>
    
    
    
    
    <!--今日日考:
    1.条件质量一共有哪些?有两个相似功能的指令区别在哪?
    2.循环指令怎么处理字符串,数组和对象
    3.简述计算属性和监听属性
    4.简述过滤器-->
    

    3、循环指令

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>循环指令</title>
    </head>
    <body>
        <div id="app">
            <!--循环指令:
                v-for="ele in string|array|obj"
            -->
            <span>{{ info }}</span>
            <hr>
            <i v-for="c in info">{{ c }} </i>
            <hr>
            <i v-for="(c, i) in info">{{i}}:{{c}}<br></i>
            <hr>
    
            <div v-for="e in stus">{{ e }}</div>
            <hr>
            <div v-for="(e, i) in stus">{{ i }}:{{ e }}</div>
            <hr>
    
            <div v-for="v in people">{{ v }}</div>
            <hr>
            <div v-for="(v, k, i) in people">{{ i }} - {{ k }}:{{ v }}</div>
            <hr>
    
            <div v-for="tea in teas">
                <span v-for="(v, k, i) in tea"><span v-if="i !== 0"> | </span>{{ k }}:{{ v }}</span>
            </div>
    
            <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                info: 'good good study',
                stus: ['Bob', 'Tom', 'Jerry'],
                people: {
                    name: '猴子',
                    age: 36.7,
                    sex: '女',
                },
                teas: [
                    {
                        name: 'jason',
                        age: 73,
                        sex: '男',
                    },
                    {
                        name: 'egon',
                        age: 74,
                        sex: '男',
                    },
                    {
                        name: 'owen',
                        age: 17.5,
                        sex: '男',
                    }
                ]
            }
        })
    </script>
    </html>
    

    4、循环指令案例

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>todo list 案例</title>
        <style>
            li:hover {
                color: red;
                cursor: pointer;
            }
        </style>
    </head>
    <body>
        <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>
    </body>
    <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);
                }
            }
        })
    </script>
    <script>
        // 前台数据库
        // 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>
    </html>
    

    5、分隔符(了解)

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            {{ msg }}
            [{ msg }]
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'message'
            },
            delimiters: ['[{', '}]'],  // 修改插值表达式符号
        })
    </script>
    </html>
    

    6、过滤器

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>过滤器</title>
    </head>
    <body>
        <div id="app">
            <!--
            总结:
            1、在filters成员中定义过滤器方法
            2、可以对多个值进行过滤,过滤时还可以额外传入辅助参数
            3、过滤的结果可以再进行下一次过滤(过滤的串联)
            -->
            <p>{{ num | f1 }}</p>
            <p>{{ a, b | f2(30, 40) | f3 }}</p>
        </div>
    </body>
    <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>
    </html>
    

    7、计算属性

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <input type="number" min="0" max="100" v-model="n1">
            +
            <input type="number" min="0" max="100" v-model="n2">
            =
            <button>{{ result }}</button>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                n1: '',
                n2: '',
                // result: 0,
            },
            /**
             * 总结:
             * 1、computed计算属性可以声明 方法属性(方法属性一定不能在data中重复声明)
             * 2、方法属性 必须在页面中渲染,才会启用绑定的方法,方法属性的值就是绑定方法的返回值
             * 3、绑定的方法中出现的所有变量都会被监听,任何一个变化发生值更新都会重新出发绑定方法,从而更新方法属性的值
             *
             * 一般用来解决的问题:一个变量值依赖于多个变量
             */
            computed: {
                result () {
                    console.log('被调用了');
                    n1 = +this.n1;
                    n2 = +this.n2;
                    return n1 + n2;
                }
            }
        })
    </script>
    </html>
    

    8、监听属性

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <p>姓名:<input type="text" v-model="full_name"></p>
            <p>姓:{{ first_name }}</p>
            <p>名:{{ last_name }}</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                full_name: '',
                first_name: '未知',
                last_name: '未知',
            },
            watch: {
                // n是监听的属性当前值,o是其上一次的值,监听的属性值每次更新都会回调监听方法
    
                /**
                 * 总结:
                 * 1、监听的属性需要在data中声明,监听方法不需要返回值
                 * 2、监听的方法名就是监听的属性名,该属性值发生更新时就会回调监听方法
                 * 3、监听方法有两个回调参数:当前值,上一次值
                 *
                 * 解决的问题:多个变量值依赖于一个变量值
                 */
                full_name(n, o) {
                    name_arr = n.split('');
                    this.first_name = name_arr[0];
                    this.last_name = name_arr[1];
                },
            }
        })
    </script>
    </html>
    

    9、冒泡排序

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
    
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
    
            }
        })
    </script>
    <script>
    
        let arr = [3, 2, 5, 4, 1];
        console.log(arr);
    
        // 冒泡排序
        // 3, 2, 5, 4, 1
    
        // 2, 3, 4, 1, 5
        // 2, 3, 1, 4
        // 2, 1, 3
        // 1, 2
        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;
                }
            }
        }
        console.log(arr);
    
    
        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;
                }
            }
        }
    
        console.log(stus);
    
    
    
    </script>
    </html>
    

    模板

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
    
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
    
            }
        })
    </script>
    </html>
    

    作业1

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .box {
                 200px;
                height: 200px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div>
                <!--需求:当前点击者高亮-->
                <button @click="changeColor('red')">红</button>
                <button @click="changeColor('yellow')">黄</button>
                <button @click="changeColor('blue')">蓝</button>
            </div>
            <div class="box" :style="{backgroundColor: bgColor}"></div>
            <!--(div>button*3)+.box-->
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                bgColor: 'black'
            },
            methods: {
                changeColor(color) {
                    this.bgColor = color;
                }
            }
        })
    </script>
    </html>
    

    作业2

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .wrap {
                 200px;
                height: 200px;
                /*background-color: black;*/
                color: white;
                font: bold 50px/200px 'STSong';
                text-align: center;
                user-select: none;
                cursor: pointer;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="wrap" @click="actionFn" :style="{backgroundColor: bgColor}">{{ count }}</div>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                count: 0,
                bgColor: 'black',
                colorArr: ['cyan', 'pink', 'green']
            },
            methods: {
                actionFn() {
                    this.count ++;
                    this.bgColor = this.colorArr[this.count % 3]
                }
            }
        })
    </script>
    </html>
    

    作业3

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .wrap {
                border: 3px solid black;
                 200px;
                height: 200px;
                border-radius: 50%;
                overflow: hidden;
                margin: 50px auto 0;
                position: relative;
            }
            .red, .green {
                 100px;
                height: 200px;
                position: absolute;
            }
            .red { background-color: red; }
            .green { background-color: green; }
    
            .l {
                 100px;
                height: 200px;
                left: 0;
            }
            .t {
                 200px;
                height: 100px;
                top: 0;
            }
            .r {
                 100px;
                height: 200px;
                right: 0;
            }
            .b {
                 200px;
                height: 100px;
                bottom: 0;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div class="wrap" @click="actionFn">
                <div class="red" :class="red_class"></div>
                <div class="green" :class="green_class"></div>
            </div>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                count: 0,
                red_class: 'l',
                green_class: 'r',
                red_arr: ['l', 't', 'r', 'b'],
                green_arr: ['r', 'b', 'l', 't'],
            },
            methods: {
                actionFn() {
                    this.count ++;
                    this.red_class = this.red_arr[this.count % 4];
                    this.green_class = this.green_arr[this.count % 4];
                }
            }
        })
    </script>
    </html>
    

    DAY67

    课堂笔记

    ## 课堂内容
    
    ​```python
    """
    1、表单指令:
    	v-model="变量"   变量与value有关
    	普通:变量就代表value值
    	单选框:变量为多个单选框中的某一个value值
    	单一复选框:变量为布尔,代表是否选中
    	多复选框:变量为数组,存放选中的选项value
    	
    	
    2、条件指令:
    	v-show:  display:none
    	v-if:    不渲染
    	v-if | v-else-if | v-else
    	前者条件成立,就不管之后分支,当所有条件都不成功,才执行v-else分支
    	
    3、循环指令:
    	v-for="(v, i) in str|arr"   
    	v-for="(v, k, i) in dic"
    	v:值 k:键 i:索引
    
    4、sessionStorage | localStorage
    	sessionStorage:生命周期同所属标签(标签关闭被销毁)
    	localStorage:永久保存
    	localStorage.key = value
    	localStorage.clear()
    
    5、分隔符:delimiters: ['[{', '}]'],
    
    6、过滤器:
    	{{ n1, n2 | f1(30) | f2 }}
    	
    	filters: {
    		f1(n1,n2,n3) {return 过滤结果},
    		f2(f1的res) {return 过滤结果},
    	}
    
    7、计算属性:
    	result必须渲染;绑定的方法内部出现的变量更新方法被调用;方法返回值是result的值;result不能在data中重复定义
    	computed: {
    		result() {
    			// 一个方法属性值依赖于多个变量
    			return this.n1 + this.n2;
    		}
    	}
    
    8、监听属性:
    	监听属性属性更新方法被调用;方法参数为被监听属性当前值,上一次值;多个变量依赖一个变量
    	watch: {
    		full_name(n, o) {
    			this.first_name = n.split('')[0]
    			this.last_name = n.split('')[1]
    		}
    	}
    	
    9、冒泡排序:
    	for (let i=0; i<arr.length-1; i++) {  // 趟数
            for (let j=0; j<arr.length-1-i; j++) {  // 比较次数
                // 处理条件即可
                if (arr[j]参数 > stus[j + 1]参数) {
                    let temp = stus[j];
                    stus[j] = stus[j + 1];
                    stus[j + 1] = temp;
                }
            }
        }
    """
    ​```
    
    
    
    ## Vue基础知识
    
    ​```python
    """
    组件:
    	组件概念:vue实例就是组件
    	根组件、局部组件、全局组件
    	组件传参:
    		父传子:自定义组件属性
    		子传父:自定义组件事件
    	
    实例成员:
    	el、data、methods、computed、watch、filters、delimiters、props、template、components
    
    指令:
    	{{}}、v-text、v-html、v-once、v-on、v-model、v-bind、v-if、v-show、v-else-if、v-else、v-for、v-cloak
    """
    ​```
    
    
    
    ## Vue项目环境
    
    ​```python
    """
    vue ~~ Django
    
    node ~~ Python
    
    npm ~~ pip
    """
    ​```
    
    
    
    
    
    ## A作业(必做)
    
    ​```python
    """
    1、按照上方 知识点总结 模块,总结今天所学知识点;
    2、有以下广告数据(实际数据命名可以略做调整)
    ad_data = {
    	tv: [
    		{img: 'img/tv/001.png', title: 'tv1'},
    		{img: 'img/tv/002.png', title: 'tv2'},
    		{img: 'img/tv/003.png', title: 'tv3'},
    		{img: 'img/tv/004.png', title: 'tv4'},
    	],
    	phone: [
    		{img: 'img/phone/001.png', title: 'phone1'},
    		{img: 'img/phone/002.png', title: 'phone2'},
    		{img: 'img/phone/003.png', title: 'phone3'},
    		{img: 'img/phone/004.png', title: 'phone4'},
    	]
    }
    
    i) 有两个大标题,电视和手机,点击对应的标题,渲染对应的数据
    ii) 一个字典作为一个显示单位,定义一个子组件进行渲染(涉及父子组件传参)
    
    3、在第2题基础上,页面最下方有一个 h2 标签,用来渲染用户当前选择的广告(点击哪个广告就是选中哪个广告)
    i)当没有点击任何广告,h2 标签显示:未选中任何广告
    ii)当点击其中一个广告,如tv1,h2 标签显示:tv1被选中
    """
    ​```
    
    
    
    ## B作业(选做)
    
    ​```python
    """
    1、给自己电脑中配置好vue环境,创建一个vue项目,可以参考课件中的 vue项目创建.md
    
    2、预习视频, 尝试在项目基础上完成A作业(利用vue文件,创建视图组件,页面小组件,组件的导入、渲染以及传参)
    """
    ​```
    

    vue创建项目

    ## Vue项目环境搭建
    
    ​```python
    """
    node ~~ python:node是用c++编写用来运行js代码的
    npm(cnpm) ~~ pip:npm是一个终端应用商城,可以换国内源cnpm
    vue ~~ django:vue是用来搭建vue前端项目的
    
    1) 安装node
    官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/
    
    2) 换源安装cnpm
    >: npm install -g cnpm --registry=https://registry.npm.taobao.org
    
    3) 安装vue项目脚手架
    >: cnpm install -g @vue/cli
    
    注:2或3终端安装失败时,可以清空 npm缓存 再重复执行失败的步骤
    npm cache clean --force
    """
    
    ​```
    
    ## Vue项目创建
    
    ​```
    1) 进入存放项目的目录
    >: cd ***
    
    2) 创建项目
    >: vue create 项目名
    
    3) 项目初始化
    ​```
    
    ![](img/vue项目创建.png)
    
    
    
    
    
    ## pycharm配置并启动vue项目
    
    ​```
    1) 用pycharm打开vue项目
    2) 添加配置npm启动
    ​```
    
    ![](img/配置vue启动.png)
    
    
    
    
    
    ## vue项目目录结构分析
    
    ​```
    ├── v-proj
    |	├── node_modules  	// 当前项目所有依赖,一般不可以移植给其他电脑环境
    |	├── public			
    |	|	├── favicon.ico	// 标签图标
    |	|	└── index.html	// 当前项目唯一的页面
    |	├── src
    |	|	├── assets		// 静态资源img、css、js
    |	|	├── components	// 小组件
    |	|	├── views		// 页面组件
    |	|	├── App.vue		// 根组件
    |	|	├── main.js		// 全局脚本文件(项目的入口)
    |	|	├── router
    |	|	|	└── index.js// 路由脚本文件(配置路由 url链接 与 页面组件的映射关系)
    |	|	└── store	
    |	|	|	└── index.js// 仓库脚本文件(vuex插件的配置文件,数据仓库)
    |	├── README.md
    └	└── package.json等配置文件
    ​```
    
    
    
    ## vue组件(.vue文件)
    
    ​```python
    # 1) template:有且只有一个根标签
    # 2) script:必须将组件对象导出 export default {}
    # 3) style: style标签明确scoped属性,代表该样式只在组件内部起作用(样式的组件化)
    ​```
    
    ​```vue
    <template>
        <div class="test">
            
        </div>
    </template>
    
    <script>
        export default {
            name: "Test"
        }
    </script>
    
    <style scoped>
    
    </style>
    ​```
    
    
    
    
    
    ## 全局脚本文件main.js(项目入口)
    
    ​```js
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false
    
    new Vue({
        router,
        store,
        render: h => h(App)
    }).$mount('#app')
    
    ​```
    ##### 改写
    
    ​```js
    import Vue from 'vue'  // 加载vue环境
    import App from './App.vue'  // 加载根组件
    import router from './router'  // 加载路由环境
    import store from './store'  // 加载数据仓库环境
    
    Vue.config.productionTip = false
    new Vue({
        el: '#app',
        router,
        store,
        render: function (readFn) {
            return readFn(App);
        },
    });
    
    ​```
    

    1、组件

    ## 复习
    
    ​```python
    """
    1、vue框架的优势
    	中文API
    	单一面应用 - 提升移动端app运行速度
    	数据的双向绑定 - 变量全局通用
    	数据驱动 - 只用考虑数据,不需要在意DOM结构
    	虚拟DOM - 缓存机制
    
    2、vue如何在页面中引入
    	1)通过script标签引入vue.js环境
    	2)创建vue实例
    	3)通过el进行挂载
    	
    	new Vue({
    		el: '#app',  // css3选择器,唯一,html、body不能作为挂载点,一个页面可以有多个实例对应多个挂载点
    	})
    	
    3、插值表达式
    	{{ 变量以及变量的简单运算 }}
    	{{ ((num * 10) + 'string').split('')[0] }}
    	
    4、文本指令
    	{{ }} | v-text | v-html | v-once
    	
    5、方法指令
    	v-on:事件="变量" | @事件="变量" | @事件="变量()" | @事件="变量($event, ...)"
    	
    	@click='btnClick'
    	btnClick(ev) {}
    	
    	@click='btnClick(1, 2, $event)'
    	btnClick(n1, n2, ev) {}
    	btnClick(...args) {}
    	
    	
    6、属性指令
    	v-bind:属性="变量"  |  :属性="变量"
    	
    	:title="t1"
    	:class="c1"  |  :class="[c1, c2]"  |   :class="{c1: true}"
    	:style="s1"  |  :style="{color: c1, fontSize: f1}"
    		s1是字典变量,c1和f1变量分别控制字体颜色和大小
    
    7、js补充
    	function可以作为类,内部会有this
    	箭头函数内部没有this
    	{}里面出现的函数称之为方法: 方法名(){}
    	
    	function Fn(name){this.name = name}
    	let f1 = new Fn('Bob')
    	
    	let f2 = ()=>{}
    	
    	{
    		f3(){}
    	}
    """
    ​```
    
    
    
    ## 课堂内容
    
    ​```python
    """
    1、表单指令:
    	v-model="变量"   变量与value有关
    	普通:变量就代表value值
    	单选框:变量为多个单选框中的某一个value值
    	单一复选框:变量为布尔,代表是否选中
    	多复选框:变量为数组,存放选中的选项value
    	
    2、条件指令:
    	v-show:  display:none
    	v-if:    不渲染
    	v-if | v-else-if | v-else
    	
    3、循环指令:
    	v-for="(v, i) in str|arr"
    	v-for="(v, k, i) in dic"
    
    4、sessionStorage | localStorage
    
    5、分隔符:delimiters: ['{{', '}}'],
    
    6、过滤器:
    	{{ n1, n2 | f1(30) | f2 }}
    	
    	filters: {
    		f1(n1,n2,n3) {return 过滤结果},
    		f2(f1的res) {return 过滤结果},
    	}
    
    7、计算属性:
    	computed: {
    		result() {
    			// 一个方法属性值依赖于多个变量
    			return this.n1 + this.n2;
    		}
    	}
    
    8、监听属性:
    	watch: {
    		full_name(n, o) {
    			this.first_name = n.split('')[0]
    			this.last_name = n.split('')[1]
    		}
    	}
    	
    9、冒泡排序:
    	for (let i=0; i<arr.length-1; i++) {  // 趟数
            for (let j=0; j<arr.length-1-i; j++) {  // 比较次数
                // 处理条件即可
                if (arr[j]参数 > stus[j + 1]参数) {
                    let temp = stus[j];
                    stus[j] = stus[j + 1];
                    stus[j + 1] = temp;
                }
            }
        }
    
    """
    ​```
    
    
    
    ## A作业(必做)
    
    ​```python
    """
    1、按照上方 知识点总结 模块,总结今天所学知识点;
    2、先有一下成绩单数据
    scores = [
    	{ name: 'Bob', math: 97, chinese: 89, english: 67 },
    	{ name: 'Tom', math: 67, chinese: 52, english: 98 },
    	{ name: 'Jerry', math: 72, chinese: 87, english: 89 },
    	{ name: 'Ben', math: 92, chinese: 87, english: 59 },
    	{ name: 'Chan', math: 47, chinese: 85, english: 92 },
    ]
    用table表格标签渲染以上数据,表格第一列是学生总分排名,最后一列是学生总分;
    
    3、还是采用上方相同的数据,采用相同的渲染规则,只渲染所有科目都及格了的学生。
    """
    ​```
    
    
    
    ## B作业(选做)
    
    ​```python
    """
    1、还是采用上方相同的数据,添加筛选规则:
    	i)有三个按钮:语文、数学、外语,点击谁谁高亮,且当前筛选规则采用哪门学科
    	ii)两个输入框,【】~【】,前面天最小分数,后面填最大分数,全部设置完毕后,表格的数据会被更新只渲染满足所有条件的结果
    	举例:点击语文,输入【86】~【87】,那就只会渲染Jerry和Ben两条数据
    """
    ​```
    

    2、子组件

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>子组件</title>
        <style>
            body, h2 {
                margin: 0;
            }
    
            .wrap {
                 880px;
                margin: 0 auto;
            }
            .wrap:after {
                content: '';
                display: block;
                clear: both;
            }
            .box {
                 200px;
                border-radius: 10px;
                overflow: hidden;
                background-color: #eee;
                float: left;
                margin: 10px;
            }
    
            .box img {
                 100%;
            }
    
            .box h2 {
                text-align: center;
                font-weight: normal;
                font-size: 20px;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <div class="wrap">
            <local-tag></local-tag>
            <local-tag></local-tag>
            <local-tag></local-tag>
            <local-tag></local-tag>
    
            <global-tag></global-tag>
            <global-tag></global-tag>
            <global-tag></global-tag>
            <global-tag></global-tag>
        </div>
    </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
    
        // 声明局部组件:局部组件要在其父组件中注册才能使用
        // 1、声明组件  2、注册组件  3、渲染组件  => 全局组件不需要注册
        let localTag = {
            template: `
            <div class="box" @click="fn">
                <img src="img/phone/001.jpg" alt="">
                <h2>美女</h2>
            </div>
            `,
            methods: {
                fn() {
                    console.log(this)
                }
            }
        };
    
    
        Vue.component('global-tag', {
            template: `
            <div class="box" @click="fn">
                <img src="img/phone/002.jpg" alt="">
                <h2>大长腿</h2>
            </div>
            `,
            methods: {
                fn() {
                    console.log(this)
                }
            }
        });
    
    
        new Vue({
            el: '#app',
            data: {},
            components: {  // 注册组件
                localTag,
            }
        })
    </script>
    </html>
    

    3、组件化

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>组件化</title>
        <style>
            body, h2 {
                margin: 0;
            }
    
            .wrap {
                 880px;
                margin: 0 auto;
            }
    
            .wrap:after {
                content: '';
                display: block;
                clear: both;
            }
    
            .box {
                 200px;
                border-radius: 10px;
                overflow: hidden;
                background-color: #eee;
                float: left;
                margin: 10px;
            }
    
            .box img {
                 100%;
            }
    
            .box h2 {
                text-align: center;
                font-weight: normal;
                font-size: 20px;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <div class="wrap">
            <local-tag></local-tag>
            <local-tag></local-tag>
            <local-tag></local-tag>
            <local-tag></local-tag>
        </div>
    </div>
    
    </body>
    <script src="js/vue.js"></script>
    <script>
        let localTag = {
            template: `
            <div class="box" @click="fn">
                <img src="img/phone/001.jpg" alt="">
                <h2>捶了美女{{ count }}下</h2>
            </div>
            `,
            data() {  // 局部或全局取件,一个组件可能会被复用多次,每个组件都应该有自己独立的变量名称空间
                return {
                    count: 0,
                }
            }, // 数据需要组件化,作为方法的返回值(方法执行后会产生一个局部作用域)
            methods: {
                fn() {
                    console.log(this);
                    this.count++;
                }
            }
        };
    
        new Vue({
            el: '#app',
            data: {},
            components: {
                localTag,
            }
        });
    
        `
        class A:
            name = 'Owen'
            def __init__(self, name):
                self.name = name
    
        a1 = A('1')
        a2 = A('2')
        a1.name
        a2.name
        `;
    </script>
    </html>
    

    4、组件传参—父传子

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>父传子</title>
        <style>
            body, h2 {
                margin: 0;
            }
    
            .wrap {
                 880px;
                margin: 0 auto;
            }
    
            .wrap:after {
                content: '';
                display: block;
                clear: both;
            }
    
            .box {
                 200px;
                border-radius: 10px;
                overflow: hidden;
                background-color: #eee;
                float: left;
                margin: 10px;
            }
    
            .box img {
                 200px;
                height: 240px;
            }
    
            .box h2 {
                text-align: center;
                font-weight: normal;
                font-size: 20px;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <div class="wrap">
            <local-tag v-for="dog in dogs" :dog="dog" def="12345" :xyz="dog.name"></local-tag>
        </div>
    </div>
    
    </body>
    <script src="js/vue.js"></script>
    <script>
        let dogs = [
            {
                name: '二哈1号',
                img: 'img/100.jpg',
            },
            {
                name: '二哈2号',
                img: 'img/200.jpg',
            },
            {
                name: '二哈3号',
                img: 'img/300.jpg',
            },
            {
                name: '二哈4号',
                img: 'img/400.jpg',
            },
            {
                name: '二哈1号',
                img: 'img/100.jpg',
            },
            {
                name: '二哈2号',
                img: 'img/200.jpg',
            },
            {
                name: '二哈3号',
                img: 'img/300.jpg',
            },
            {
                name: '二哈4号',
                img: 'img/400.jpg',
            }
        ];
    
    
        // 1)子组件可以通过props自定义组件属性(采用反射机制,需要填写字符串,但是使用时可以直接作为变量)
        // 2)子组件会在父组件中渲染,渲染时,将父组件的变量绑定给子组件的自定义属性,将可以将变量值传递给子组件
        let localTag = {
            props: ['dog', 'def', 'xyz'],
    
            template: `
            <div class="box" @click="fn">
                <img :src="dog.img" alt="">
                <h2>捶{{ dog.name }}{{ count}}下</h2>
                <!--<h3>{{ abc }}</h3>-->
                <!--<h3>{{ def }}</h3>-->
                <!--<h3>{{ xyz }}</h3>-->
            </div>
            `,
            data() {
                return {
                    count: 0,
                }
            },
            methods: {
                fn() {
                    console.log(this.dog);
                    this.count++;
                }
            }
        };
    
        new Vue({
            el: '#app',
            data: {
                dogs,
            },
            components: {
                localTag,
            }
        });
    
    </script>
    </html>
    

    5、组件传参—子传父

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>子传父</title>
    </head>
    <body>
        <div id="app">
            <h1>{{ h1 }}</h1>
            <h3>{{ h3 }}</h3>
    
    
            <!--自定义组件标签的事件
                自定义事件是属于子组件的,子组件在父组件中渲染并绑定事件方法,所以事件方法由父组件来实现
                子组件如何触发自定义事件:this.$emit('自定义事件名', 触发事件回调的参数们)
    
                子组件触发自定义事件,携带出子组件的内容,在父组件中实现自定义事件的方法,拿到子组件传递给父组件的消息
            -->
            <tag @action="actionFn"></tag>
            <hr>
            <tag2 @h1a="aFn1" @h3a="aFn3"></tag2>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        let tag = {
            template: `
            <div>
                <input type="text" v-model="t1">
                <input type="text" v-model="t2">
                <button @click="changeTitle">修改标题</button>
            </div>
            `,
            data() {
                return {
                    t1: '',
                    t2: '',
                }
            },
            methods: {
                changeTitle() {
                    if (this.t1 && this.t2) {
                        // console.log(this.t1, this.t2);
                        this.$emit('action', this.t1, this.t2);
                        this.t1 = '';
                        this.t2 = '';
                    }
                }
            }
        };
    
    
        let tag2 = {
            template: `
            <div>
                主标题内容:<input type="text" v-model="t1" @input="t1Fn">
                子标题内容:<input type="text" v-model="t2">
            </div>
            `,
            data() {
                return {
                    t1: '',
                    t2: '',
                }
            },
            methods: {
                t1Fn() {
                    this.$emit('h1a', this.t1);
                }
            },
            watch: {
                t2 () {
                    this.$emit('h3a', this.t2);
                }
            }
        };
    
        new Vue({
            el: '#app',
            data: {
                h1: '主标题',
                h3: '子标题'
            },
            components: {
                tag,
                tag2,
            },
            methods: {
                actionFn(a, b, c) {
                    // console.log('触发了', a, b, c);
                    this.h1 = a;
                    this.h3 = b;
                },
                aFn1(a) {
                    if (!a) {
                        this.h1 = '主标题';
                        return;
                    }
                    this.h1 = a;
                },
                aFn3(a) {
                    if (!a) {
                        this.h3 = '子标题';
                        return;
                    }
                    this.h3 = a;
                },
            }
        })
    </script>
    </html>
    

    作业1

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>1</title>
    </head>
    <body>
        <div id="app">
            <table border="1" style="margin: auto" rules="all">
                <tr>
                    <th>排名</th>
                    <th>姓名</th>
                    <th>数学</th>
                    <th>语文</th>
                    <th>英语</th>
                    <th>总分</th>
                </tr>
                <!--有几个人,就循环渲染几行-->
                <tr v-for="(score, i) in scores">
                    <td>{{ i + 1 }}</td>
                    <td v-for="v in score">{{v}}</td>
                </tr>
            </table>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        `
        let scores = null;
        $.ajax({
            url:'',
            success(response) {
                scores = response.data
            }
        });
        `;
        // 模拟当前页面加载成功,从后台获取操作的数据
        let scores = [
            { name: 'Bob', math: 97, chinese: 89, english: 67 },
            { name: 'Tom', math: 67, chinese: 52, english: 98 },
            { name: 'Jerry', math: 72, chinese: 87, english: 89 },
            { name: 'Ben', math: 92, chinese: 87, english: 59 },
            { name: 'Chan', math: 47, chinese: 85, english: 92 },
        ];
        // 补充:for in遍历的是取值关键 | for of遍历的是值
        // 添加总分
        for (score of scores) {
            score.total = score.math + score.chinese + score.english;
        }
        // console.log(scores);
        // 按照总分排序
        for (let i=0; i<scores.length-1; i++) {
            for (let j=0; j<scores.length-1-i; j++) {
                if (scores[j].total < scores[j+1].total) {
                    let temp = scores[j];
                    scores[j] = scores[j+1];
                    scores[j+1] = temp;
                }
            }
        }
        console.log(scores);
    
        new Vue({
            el: '#app',
            data: {
                // 属性名与值为变量的变量名相同,可以简写省略值
                scores,
            }
        })
    </script>
    </html>
    

    作业2

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>2</title>
    </head>
    <body>
        <div id="app">
            <table border="1" style="margin: auto" rules="all">
                <tr>
                    <th>排名</th>
                    <th>姓名</th>
                    <th>数学</th>
                    <th>语文</th>
                    <th>英语</th>
                    <th>总分</th>
                </tr>
                <!--有几个人,就循环渲染几行-->
                <tr v-for="(score, i) in scores" v-if="score.math>=60&&score.chinese>=60&&score.english>=60">
                    <td>{{ i + 1 }}</td>
                    <td v-for="v in score">{{v}}</td>
                </tr>
            </table>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        `
        let scores = null;
        $.ajax({
            url:'',
            success(response) {
                scores = response.data
            }
        });
        `;
        // 模拟当前页面加载成功,从后台获取操作的数据
        let scores = [
            { name: 'Bob', math: 97, chinese: 89, english: 67 },
            { name: 'Tom', math: 67, chinese: 52, english: 98 },
            { name: 'Jerry', math: 72, chinese: 87, english: 89 },
            { name: 'Ben', math: 92, chinese: 87, english: 59 },
            { name: 'Chan', math: 47, chinese: 85, english: 92 },
        ];
        // 补充:for in遍历的是取值关键 | for of遍历的是值
        // 添加总分
        for (score of scores) {
            score.total = score.math + score.chinese + score.english;
        }
        // console.log(scores);
        // 按照总分排序
        for (let i=0; i<scores.length-1; i++) {
            for (let j=0; j<scores.length-1-i; j++) {
                if (scores[j].total < scores[j+1].total) {
                    let temp = scores[j];
                    scores[j] = scores[j+1];
                    scores[j+1] = temp;
                }
            }
        }
        console.log(scores);
    
        new Vue({
            el: '#app',
            data: {
                // 属性名与值为变量的变量名相同,可以简写省略值
                scores,
            }
        })
    </script>
    </html>
    

    作业3

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>3</title>
        <style>
            .active {
                background-color: pink;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div style=" 400px; margin: 20px auto">
                <button @click="subject = 'math'" :class="{active: subject === 'math'}">数学</button>
                <button @click="subject = 'chinese'" :class="{active: subject === 'chinese'}">语文</button>
                <button @click="subject = 'english'" :class="{active: subject === 'english'}">英语</button>
                <input type="number" min="0" max="100" v-model="min">
                ~
                <input type="number" min="0" max="100" v-model="max">
            </div>
    
            <table width="400" border="1" style="margin: auto" rules="all">
                <tr>
                    <th>排名</th>
                    <th>姓名</th>
                    <th>数学</th>
                    <th>语文</th>
                    <th>英语</th>
                    <th>总分</th>
                </tr>
                <tbody v-if="subject === 'math'">
                    <tr v-for="(score, i) in scores" v-if="score.math>=min && score.math<=max || (!min || !max)">
                        <td>{{ i + 1 }}</td>
                        <td v-for="v in score">{{v}}</td>
                    </tr>
                </tbody>
                <tbody v-else-if="subject === 'chinese'">
                    <tr v-for="(score, i) in scores" v-if="score.chinese>=min && score.chinese<=max || (!min || !max)">
                        <td>{{ i + 1 }}</td>
                        <td v-for="v in score">{{v}}</td>
                    </tr>
                </tbody>
                <tbody v-else-if="subject === 'english'">
                    <tr v-for="(score, i) in scores" v-if="score.english>=min && score.english<=max || (!min || !max)">
                        <td>{{ i + 1 }}</td>
                        <td v-for="v in score">{{v}}</td>
                    </tr>
                </tbody>
                <tbody v-else>
                    <tr v-for="(score, i) in scores">
                        <td>{{ i + 1 }}</td>
                        <td v-for="v in score">{{v}}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        `
        let scores = null;
        $.ajax({
            url:'',
            success(response) {
                scores = response.data
            }
        });
        `;
        // 模拟当前页面加载成功,从后台获取操作的数据
        let scores = [
            { name: 'Bob', math: 97, chinese: 89, english: 67 },
            { name: 'Tom', math: 67, chinese: 52, english: 98 },
            { name: 'Jerry', math: 72, chinese: 87, english: 89 },
            { name: 'Ben', math: 92, chinese: 87, english: 59 },
            { name: 'Chan', math: 47, chinese: 85, english: 92 },
        ];
        // 补充:for in遍历的是取值关键 | for of遍历的是值
        // 添加总分
        for (score of scores) {
            score.total = score.math + score.chinese + score.english;
        }
        // console.log(scores);
        // 按照总分排序
        for (let i=0; i<scores.length-1; i++) {
            for (let j=0; j<scores.length-1-i; j++) {
                if (scores[j].total < scores[j+1].total) {
                    let temp = scores[j];
                    scores[j] = scores[j+1];
                    scores[j+1] = temp;
                }
            }
        }
        console.log(scores);
    
        new Vue({
            el: '#app',
            data: {
                // 属性名与值为变量的变量名相同,可以简写省略值
                scores,
                min: '',
                max: '',
                subject: '',
            }
        })
    </script>
    </html>
    

    DAY68

    课堂笔记

    ## 复习
    
    ​```python
    """
    1、组件:
    	html、css、js的集合体
    	vue实例就代表组件
    	组件用template实例成员管理html结构,有且只有一个根标签
    	子组件可以复用,所以数据要组件化处理,data的值由方法的返回值提供
    
    2、分类:
    	根组件:new Vue({}),顶级组件
    	全局组件: Vue.component('组件名', {}),不用注册可以在任何地方使用
    	局部组件:let 组件名 = {},只有在注册的父组件中才能使用
    	
    3、组件间传参:
    	父传子:自定义属性
    	<tag :info="msg"></tag>
    	
    	let tag = {
    		props: ['info'],
    	}
    	new Vue({
    		data: {msg: 12345}
    		components: {
    			tag,
    		}
    	})
    	
    	子传父:自定义事件
    	<tag @action="fn"></tag>
    	
    	let tag = {
    		data: {msg: 12345},
    		methods: {
    			tag_fn() {
    				this.$emit('action', this.msg)
    			}
    		}
    	}
    	new Vue({
    		components: {
    			tag,
    		},
    		methods: {
    			fn(info) {}
    		}
    	})
    	
    4、vue项目环境
    	官网下载安装node => 将npm换源为cnpm => cnpm install -g @vue/cli
    	
    	=> vue项目创建...
    """
    ​```
    
    
    
    
    
    ## 知识点总结
    
    ​```python
    """
    1、创建项目:vue create 项目名  -  babel、vue-router、vuex
    
    2、项目目录:
    	node_modules依赖(不同电脑依赖需要重新构建)
    	views:页面组件
    	components:小组件
    	router/index.js:路由配置文件 - 路径与页面组件对应关系
    	App.vue:根组件,固定五行话(看代码)
    	main.js:项目总脚本文件 - 配置所有环境,加载根组件
    	
    3、vue请求生命周期:
    	浏览器请求/user => router插件映射User.vue组件 => User.vue组件替换App.vue中的<router-view />占位符
    	注: i) 可以用 <router-link to="/user">用户页</router-link>完成标签跳转
    		ii) this.$router.push('/user')完成逻辑跳转
    		
    4、vue组件的生命周期钩子:组件 创建 到 销毁 中的时间节点回调的方法
    	created(){}  |  mounted(){}
    	
    5、路由跳转
    this.$router.push({name: '路由名', query: {拼接的参数}})
    this.$router.go(number)
    
    6、路由配置
    {
    	path: '/course/detail',
    	name: 'course-detail',
        component: CourseDetail
    }
    {
    	path: '/detail',
        redirect: '/course/detail'
    }
    this.$router.push('/course/detail');  ==  this.$router.push('/detail');
    this.$router.push('/course/detail?pk=1');  => this.$route.query.pk
    
    ​```````````````````````````````````````````````````````````````````````
    {
    	path: '/course/detail/:pk',
    	name: 'course-detail',
        component: CourseDetail
    }
    this.$router.push('/course/detail/10');  => this.$route.params.pk
    
    
    7、js类的原型:类属性
    
    8、配置全局css样式
    import '@/assets/css/global.css'
    require('@/assets/css/global.css');
    
    
    路由知识点概况:
    	1)路由配置:router/index.js
    	2)路由跳转与路由渲染:router-link、router-view、$router.push、$router.go
    	3)路由传参:两种传参
    """
    ​```
    
    
    
    
    
    ## A作业(必做)
    
    ​```python
    """
    1、按照上方 知识点总结 模块,总结今天所学知识点;
    2、
    Home.vue页面组件显示基本信息:欢迎来到汽车系统
    Car.vue页面组件,完成Cars的列表数据渲染
    Nav.vue小组件,完成Home与Car页面的导航跳转
    
    3、
    CarDetail页面组件,完成某一个汽车详细信息的渲染
    (Car页面点击具体的car进入详情页,把点击的car的主键传入到详情页)
    """
    ​```
    
    
    
    ## B作业(选做)
    
    ​```python
    """
    1、预习vue前后台交互插件:axios
    """
    ​```
    

    作业

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>作业</title>
        <style>
            body, h2 {
                margin: 0;
            }
    
            .wrap {
                 880px;
                margin: 0 auto;
            }
    
            .wrap:after {
                content: '';
                display: block;
                clear: both;
            }
    
            .box {
                 200px;
                border-radius: 10px;
                overflow: hidden;
                background-color: #eee;
                float: left;
                margin: 10px;
            }
    
            .box img {
                 100%;
                height: 240px;
            }
    
            .box h2 {
                text-align: center;
                font-weight: normal;
                font-size: 20px;
            }
            .nav, h2 {
                text-align: center;
            }
            .active {
                background-color: pink;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <div class="nav">
            <button @click="page = 'tv'" :class="{active: page === 'tv'}">tv</button>
            <button @click="page = 'phone'" :class="{active: page === 'phone'}">phone</button>
        </div>
        <div class="wrap" v-if="page === 'tv'">
            <tag v-for="tv in ad_data.tv" :ad="tv" :key="tv.title" @action="change_select"></tag>
        </div>
        <!-- v-for指令,需要给循环的标签或组件添加 key 属性,完成缓存的建立 -->
        <div class="wrap" v-else-if="page === 'phone'">
            <tag v-for="phone in ad_data.phone" :ad="phone" :key="phone.title" @action="change_select"></tag>
        </div>
        <h2 class="footer">{{ select_ad }}</h2>
    </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
    
        ad_data = {
            tv: [
                {img: 'img/tv/001.jpg', title: 'tv1'},
                {img: 'img/tv/002.jpg', title: 'tv2'},
                {img: 'img/tv/003.jpg', title: 'tv3'},
                {img: 'img/tv/004.jpg', title: 'tv4'},
            ],
            phone: [
                {img: 'img/phone/100.jpg', title: 'phone1'},
                {img: 'img/phone/200.jpg', title: 'phone2'},
                {img: 'img/phone/300.jpg', title: 'phone3'},
                {img: 'img/phone/400.jpg', title: 'phone4'},
            ]
        };
    
        let tag = {
            props: ['ad'],
            template: `
                <div class="box" @click="send_ad(ad)">
                    <img :src="ad.img" alt="">
                    <h2>{{ ad.title }}</h2>
                </div>
            `,
            methods: {
                send_ad(ad) {
                    this.$emit('action', ad);
                }
            }
        };
    
        new Vue({
            el: '#app',
            data: {
                ad_data,
                page: 'tv',
                select_ad: '未选中'
            },
            components: {
                tag,
            },
            methods: {
                change_select(ad) {
                    // this.select_ad = ad.title + '被选中';
                    this.select_ad = `${ad.title}被选中`;
                }
            }
        })
    </script>
    </html>
    

    js原型补充

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
    
            }
        })
    </script>
    <script>
    
        function A() {}
    
        let a1 = new A();
        let a2 = new A();
    
        // 为A类添加原型 => 类似于类属性
        A.prototype.num = 100;
    
        console.log(a1.num);
        console.log(a2.num);
    
    
        // ES6语法下类
        class B {
            constructor(name) {
                this.name = name;
            }
        }
        let b1 = new B('Tom');
        let b2 = new B('Ben');
        B.prototype.count = 666;
        console.log(b1.count);
        console.log(b2.count);
    
        console.log(b1.name);
        console.log(b2.name);
    
        // 推导
        Vue.prototype.$ajax = 12345;
        // this.$ajax
    
    </script>
    </html>
    

    router——index.js

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    import Course from '../views/Course'
    import CourseDetail from '../views/CourseDetail'
    
    Vue.use(VueRouter);
    
    const routes = [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/home',
            redirect: '/',  // 路由的重定向
        },
        {
            path: '/course',
            name: 'course',
            component: Course
        },
        {
            // 第一种路由传参
            // path: '/course/detail',
    
            // 第二种路由传参
            path: '/course/:pk/detail',
            name: 'course-detail',
            component: CourseDetail
        }
    ];
    
    const router = new VueRouter({
        mode: 'history',
        base: process.env.BASE_URL,
        routes
    });
    
    export default router
    
    

    store——index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
        state: {},
        mutations: {},
        actions: {},
        modules: {}
    })
    
    

    views—main.js

    // import 别名 form '资源'
    
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false;
    
    // 配置全局样式:@就代表src文件夹的绝对路径,官方提倡require加载静态文件
    // import '@/assets/css/global.css'
    require('@/assets/css/global.css');
    
    
    
    // new Vue({
    //     router,
    //     store,
    //     render: h => h(App)
    // }).$mount('#app');
    
    new Vue({
        el: '#app',
        router: router,
        store: store,
        render: function (read_vue_fn) {
            return read_vue_fn(App)
        }
    });
    
    
    // 项目的生命周期:
    /**
     * 1、启动项目,加载主脚本文件 main.js
     *      加载Vue环境,创建根组件完成渲染
     *      加载系统已有的第三方环境:router、store
     *      加载自定义的第三方环境与自己配置的环境:后期项目不断添加
     *
     * 2、router被加载,就会解析router文件夹下的index.js脚本文件,完成 路由-组件 的映射关系
     *
     * 3、新建视图组件.vue(在views文件夹中),在路由中配置(在router的index.js中),设置路由跳转(在导航栏组件中Nav.vue)
     */
    

    views—App.vue

    <template>
        <div id="app">
            <!--页面组件占位符-->
            <router-view></router-view>
        </div>
    </template>
    
    

    components——Nav.vue

    <template>
        <div class="nav">
            <div class="content">
                <ul>
                    <li class="logo">
                        <img src="@/assets/img/logo.svg" alt="" @click="goHome">
                    </li>
                    <li class="route">
                        <router-link to="/">主页</router-link>
                    </li>
                    <li class="route">
                        <!--<router-link to="/course">课程页</router-link>-->
                        <router-link :to="{name: 'course'}">课程页</router-link>
                    </li>
                </ul>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "Nav",
            methods: {
                goHome() {
                    // console.log('去向主页');
                    // console.log(this.$router);  // 控制路由跳转
                    // console.log(this.$route);  // 控制路由数据
    
                    if (this.$route.path !== '/') {
                        // this.$router.push('/');  // 往下再跳转一页
    
                        this.$router.push({
                            name: 'home'
                        });
    
                        // this.$router.go(2);  // go是历史记录前进后退,正为前进,负为后退,数字为步数
                    }
                }
            }
        }
    </script>
    
    <style scoped>
        .nav {
             100%;
            height: 60px;
            background-color: #eee;
        }
        .content {
             1200px;
            margin: 0 auto;
            /*background-color: red;*/
            height: 60px;
        }
        .content ul li {
            float: left;
        }
        .logo {
            padding-top: 10px;
            padding-right: 50px;
            cursor: pointer;
        }
    
        .route {
            padding: 15px 10px 0;
        }
        .route a {
            padding-bottom: 5px;
            border-bottom: 3px solid transparent;
        }
        .route a.router-link-exact-active {
            color: orange;
            border-bottom-color: orange;
        }
    </style>
    

    components——CourseTag.vue

    <template>
        <div class="course-tag">
            <img :src="course.img" alt="" @click="goDetail(course.id)">
    
            <!--第一种路由传参-->
            <!--<router-link :to="`/course/detail?pk=${course.id}`">{{ course.title }}</router-link>-->
    
            <!--<router-link :to="{-->
                <!--name: 'course-detail',-->
                <!--query: {pk: course.id}-->
            <!--}">{{ course.title }}-->
            <!--</router-link>-->
    
            <!--第二种路由传参-->
            <router-link :to="`/course/${course.id}/detail`">{{ course.title }}</router-link>
    
    
        </div>
    </template>
    
    <script>
        export default {
            name: "CourseTag",
            props: ['course'],
            methods: {
                goDetail(pk) {
                    // this.$router.push(`/course/detail?pk=${pk}`);
                    this.$router.push({
                        name: 'course-detail',
                        query: {pk: pk}
                    });
                }
            }
        }
    </script>
    
    <style scoped>
        .course-tag {
             200px;
            border-radius: 10px;
            overflow: hidden;
            background-color: #eee;
            float: left;
            margin: 10px;
        }
    
        .course-tag img {
             100%;
            height: 240px;
        }
    
        .course-tag a {
            text-align: center;
            font-weight: normal;
            font-size: 20px;
            display: block;
        }
    </style>
    

    DAY69

    课堂笔记

    ## 复习
    
    ​```python
    """
    1、环境
    node:官网下载安装包,傻瓜式安装 - https://nodejs.org/zh-cn/ => 附带按照了npm
    cnpm:npm install -g cnpm --registry=https://registry.npm.taobao.org
    vue/cli:cnpm install -g @vue/cli
    
    2、项目创建
    cd 存放项目的目录
    vue create 项目名 => 需要安装的组件babel、vue-router、vuex
    
    3、配置项目启动
    pycharm打开项目,配置npm启动
    
    4、main.js完成vue环境的加载、完成根组件的渲染、加载vue-router、vuex等环境、加载自定义环境
    
    5、vue-router配置路由:
    	<router-link to=""></router-link> | this.$router.push() 完成跳转
    	<router-view /> 完成页面组件的占位
    	在router/index.js中 完成路由配置 路径-视图组件 映射关系
    	两种路由传参
    	配置				跳转				获取
    	path:'/user'  	 to="/user?pk=1"   $route.query.pk
    	path:'/user/:pk' to="/user/1"	   $route.params.pk
    	
    	:to="{name: 'user'}"
    	
    6、组件生命周期钩子:组件从创建到销毁的整个生命周期中特殊时间节点回调的方法
    	created(){完成后台数据的请求}
    	mounted(){完成极其耗时的后台数据请求}
    	
    7、js原型
    Vue.prototype.count = 100
    所有Vue实例都可以访问count
    """
    ​```
    
    
    
    ## vue的ajax插件:axios
    
    ​```python
    """
    1)安装插件(一定要在项目目录下):
    	>: cnpm install axios
    	
    2)在main.js中配置:
    	import axios from 'axios'
    	Vue.prototype.$axios = axios;
    	
    
    3)在任何一个组件的逻辑中发送ajax请求:
        this.$axios({
            url: 'http://127.0.0.1:8000/cars/',
            method: 'get',
        }).then(response => {
            console.log(response);
            // this.cars = response.data;
        }).catch(error => {  // 网络状态码为4xx、5xx
            console.log(error);
        });
    	
    """
    ​```
    
    
    
    ## CORS跨域问题(同源策略)
    
    ​```python
    """
    同源:http协议相同、ip服务器地址相同、app应用端口相同
    跨域:协议、ip地址、应用端口有一个不同,就是跨域
    
    Django默认是同源策略,存在跨越问题。
    Django的解决方案:
    
    1)Django按照cors模块:
    	>: pip install django-cors-headers
    	
    2)在settings注册模块,配置中间件:
        INSTALLED_APPS = [
            ...
            'corsheaders'
        ]
        MIDDLEWARE = [
            ...
            'corsheaders.middleware.CorsMiddleware'
        ]
    
    3)在settings开启允许跨越:
    	CORS_ORIGIN_ALLOW_ALL = True
    """
    ​```
    
    
    
    ## Vue配置ElementUI
    
    ​```python
    """
    1)安装插件(一定要在项目目录下):
    	>: cnpm install element-ui
    	
    2)在main.js中配置:
    	import ElementUI from 'element-ui';
    	import 'element-ui/lib/theme-chalk/index.css';
    	Vue.use(ElementUI);
    	
    
    3)使用:
    	灵魂:复制粘贴
    	
    """
    ​```
    
    
    
    ## Vue配置jq+bs:见其课件
    
    
    
    
    
    ## A作业(必做)
    
    ​```python
    """
    1、整理今天所学知识点
    
    2、将vue知识点系统回顾一下:vue指令、vue成员、vue生命周期钩子、vue项目的请求生命周期、vue文件组件(结构、语法、导入、页面与小组件)、父子组件间的传参(Cars页面渲染多个Car组件)、路由(占位、跳转、传参)、配置各种第三方插件(element、jq+bs、axios)
    
    3、完成基础前后台分类的数据展示类网站
    	封装导航栏Nav小组件,完成各页面的跳转,在需要导航栏的页面中渲染Nav小组件
    	在主页Home组件中,写一个轮播图(bs和element都要提供),完成后台数据的轮播展示
    	将汽车主页数据渲染以及详情页数据渲染的数据,都放在后台(用mysql数据库存储),完成后台数据的渲染,前台父子组件以及组件间的传参
    """
    ​```
    
    
    
    ## B作业(选做)
    
    ​```python
    """
    1、尝试将bbs重构为前后台分类项目
    2、好好预习drf视频(重中之重重)
    """
    ​```
    

    Vue配置bs环境

    ## 安装插件
    
    #### jQuery
    
    ​```
    >: cnpm install jquery
    ​```
    
    #### vue/cli 3 配置jQuery:在vue.config.js中配置(没有,手动项目根目录下新建)
    
    ​```js
    const webpack = require("webpack");
    
    module.exports = {
        configureWebpack: {
            plugins: [
                new webpack.ProvidePlugin({
                    $: "jquery",
                    jQuery: "jquery",
                    "window.jQuery": "jquery",
                    Popper: ["popper.js", "default"]
                })
            ]
     		}
    };
    ​```
    
    #### BootStrap
    
    ​```
    >: cnpm install bootstrap@3
    ​```
    
    #### vue/cli 3 配置BootStrap:在main.js中配置
    
    ​```js
    import "bootstrap"
    import "bootstrap/dist/css/bootstrap.css"
    ​```
    

    前后端分离跨域交互

    ## 分离的前后台交互
    
    
    
    ### 后台处理跨域
    
    ##### 安装插件
    
    ​```
    >: pip install django-cors-headers
    
    插件参考地址:https://github.com/ottoyiu/django-cors-headers/
    ​```
    
    ##### 项目配置:dev.py
    
    ​```python
    # 注册app
    INSTALLED_APPS = [
    	...
    	'corsheaders'
    ]
    
    # 添加中间件
    MIDDLEWARE = [
    	...
    	'corsheaders.middleware.CorsMiddleware'
    ]
    
    # 允许跨域源
    CORS_ORIGIN_ALLOW_ALL = True
    ​```
    

    main.js

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    Vue.config.productionTip = false;
    
    // 全局css
    require('@/assets/css/global.css');
    
    // 全局js
    import settings from '@/assets/js/settings'
    Vue.prototype.$settings = settings;
    
    // 配置axios
    import axios from 'axios'
    Vue.prototype.$axios = axios;
    
    // 配置element-ui
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI);
    
    // 配置bootstrap,前提要配置jQuery
    import "bootstrap"
    import "bootstrap/dist/css/bootstrap.css"
    
    new Vue({
        router,
        store,
        render: h => h(App)
    }).$mount('#app');
    
    

    vue.config.js

    const webpack = require("webpack");
    
    module.exports = {
        configureWebpack: {
            plugins: [
                new webpack.ProvidePlugin({
                    $: "jquery",
                    jQuery: "jquery",
                    "window.jQuery": "jquery",
                    "window.$": "jquery",
                    Popper: ["popper.js", "default"]
                })
            ]
        }
    };
    

    App.vue

    <template>
        <div id="app">
            <router-view/>
        </div>
    </template>
    //固定五句话
    

    Car.vue

    <template>
        <div class="car">
            <Nav />
            <div class="wrap">
                <CarTag v-for="car in cars" :car="car" />
            </div>
        </div>
    </template>
    
    <script>
        import Nav from '@/components/Nav'
        import CarTag from '@/components/CarTag'
    
        export default {
            name: "Car",
            components: {
                Nav,
                CarTag,
            },
            data() {
                return {
                    cars: []
                }
            },
            created() {
                // 完成ajax请求后台,获得数据库中的数据
                this.$axios({
                    url: this.$settings.base_url + '/cars/',
                    method: 'post',
                    params: {  // url拼接参数:任何请求都可以携带
                        a: 1,
                        b: 2,
                        c: 3
                    },
                    data: {  // 数据包参数:get请求是无法携带的
                        x: 10,
                        y: 20,
                    }
                }).then(response => {
                    // console.log('正常', response);
                    this.cars = response.data;
                }).catch(error => {  // 网络状态码为4xx、5xx
                    console.log('异常', error.response);
                });
            }
        }
    </script>
    
    <style scoped>
        .wrap {
             1100px;
            /*background-color: green;*/
            margin: 10px auto 0;
        }
        .wrap:after {
            display: block;
            content: '';
            clear: both;
        }
    </style>
    

    CarDetail.vue

    <template>
        <div class="car-detail">
            <div v-if="car.msg">
                <h1>{{ car.msg }}</h1>
            </div>
            <div v-else-if="car.id">
                <img :src="car.img" alt="">
                <h2>{{ car.title }}</h2>
                <h3>${{ car.price }}w</h3>
                <h3>{{ car.info }}</h3>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "CarDetail",
            data() {
                return {
                    car: {}
                }
            },
            created() {
                // 拿到路由传递来的car主键
                let pk = this.$route.query.pk || this.$route.params.pk;
                // 主键不存在,就直接结束方法
                if (!pk) return false;
                // 主键存在才请求后台
                this.$axios({
                    url: this.$settings.base_url + `/car/${pk}/`,
                }).then(response => {
                    this.car = response.data
                }).catch(error => {
                    console.log(error.response)
                })
            }
        }
    </script>
    
    <style scoped>
        .car-detail {
            /* vw:屏幕宽度  vh:屏幕高度*/
            /* 100vw;*/
            /*height: 100vh;*/
            /*background-color: orange;*/
        }
    </style>
    

    Element.vue

    <template>
        <div class="element">
            <h1>element-ui组件</h1>
            <hr>
    
            <el-row type="flex" :gutter="20" justify="center">
                <el-col :span="6">
                    <div class="grid-content bg-purple"></div>
                </el-col>
                <!--<el-col :span="8">-->
                <!--<div class="grid-content bg-purple-light"></div>-->
                <!--</el-col>-->
                <el-col :span="6" :offset="8">
                    <div class="grid-content bg-purple"></div>
                </el-col>
            </el-row>
    
            <hr>
    
            <el-container>
                <el-aside width="200px">Aside</el-aside>
                <el-container>
                    <el-header>Header</el-header>
                    <el-main>Main</el-main>
                    <el-footer>Footer</el-footer>
                </el-container>
            </el-container>
    
            <hr>
    
            <i class="icon el-icon-platform-eleme"></i>
    
            <hr>
    
            <el-row>
                <el-button @click="fn" round>圆角按钮</el-button>
                <el-button type="primary" round>主要按钮</el-button>
                <el-button type="success" round>成功按钮</el-button>
                <el-button type="info" round>信息按钮</el-button>
                <el-button type="warning" round>警告按钮</el-button>
                <el-button type="danger" round>危险按钮</el-button>
            </el-row>
    
            <hr>
    
            <el-carousel indicator-position="outside">
                <el-carousel-item v-for="item in 4" :key="item">
                    <h3>{{ item }}</h3>
                </el-carousel-item>
            </el-carousel>
    
            <hr>
            <h2>bootstrap环境</h2>
            <i class="btn btn-primary">按钮</i>
    
            <div class="dropup">
                <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown"
                        aria-haspopup="true" aria-expanded="false">
                    Dropup
                    <span class="caret"></span>
                </button>
                <ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
                    <li><a href="#">Action</a></li>
                    <li><a href="#">Another action</a></li>
                    <li><a href="#">Something else here</a></li>
                    <li role="separator" class="divider"></li>
                    <li><a href="#">Separated link</a></li>
                </ul>
            </div>
    
            <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        </div>
    </template>
    
    <script>
        export default {
            name: "Element",
            methods: {
                fn() {
                    /*
                    this.$message({
                        message: '弹出框',
                        type: 'warning',
                        duration: 1000,
                        showClose: true,
                        onClose: () => {
                            this.$message('弹出框关闭了')
                        }
                    })
                    */
                    this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                        center: true
                    }).then(() => {
                        this.$message({
                            type: 'success',
                            message: '删除成功!'
                        });
                    }).catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消删除'
                        });
                    });
    
                }
            }
        }
    </script>
    
    <style scoped>
        .el-carousel__item h3 {
            color: #475669;
            font-size: 18px;
            opacity: 0.75;
            line-height: 300px;
            margin: 0;
        }
    
        .el-carousel__item:nth-child(2n) {
            background-color: #99a9bf;
        }
    
        .el-carousel__item:nth-child(2n+1) {
            background-color: #d3dce6;
        }
    
        .icon {
            font-size: 100px;
            color: orange;
        }
    
        .grid-content {
            height: 60px;
        }
    
        .bg-purple-dark {
            background: #99a9bf;
        }
    
        .bg-purple {
            background: #d3dce6;
        }
    
        .bg-purple-light {
            background: #e5e9f2;
        }
    
        .el-header, .el-footer {
            background-color: #B3C0D1;
            color: #333;
            text-align: center;
            line-height: 60px;
        }
    
        .el-aside {
            background-color: #D3DCE6;
            color: #333;
            text-align: center;
            line-height: 200px;
        }
    
        .el-main {
            background-color: #E9EEF3;
            color: #333;
            text-align: center;
            line-height: 160px;
        }
    
        body > .el-container {
            margin-bottom: 40px;
        }
    
        .el-container:nth-child(5) .el-aside,
        .el-container:nth-child(6) .el-aside {
            line-height: 260px;
        }
    
        .el-container:nth-child(7) .el-aside {
            line-height: 320px;
        }
    </style>
    

    Home.vue

    <template>
        <div class="home">
            <Nav />
            <h1>
                <span @click="goCarPage">欢迎来到汽车系统</span>
            </h1>
        </div>
    </template>
    
    <script>
        import Nav from '../components/Nav'
    
        export default {
            name: "Home",
            components: {
                Nav
            },
            methods: {
                goCarPage() {
                    if (this.$route.path !== '/car') {
                        this.$router.push('/car')
                    }
                }
            }
        }
    </script>
    
    <style scoped>
        h1 {
            /*background-color: red;*/
            text-align: center;
            margin-top: 160px;
        }
        h1 span {
            /*background-color: orange;*/
            cursor: pointer;
            font: bold 60px/70px 'STSong';
        }
    </style>
    

    router——index.js

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home'
    import Car from '../views/Car'
    import CarDetail from '../views/CarDetail'
    import Element from '../views/Element'
    
    Vue.use(VueRouter);
    
    const routes = [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/car',
            name: 'car',
            component: Car
        },
        {
            path: '/car/detail/:pk',
            name: 'car-detail',
            component: CarDetail
        },
        {
            path: '/element',
            name: 'element',
            component: Element
        }
    ];
    
    const router = new VueRouter({
        mode: 'history',
        base: process.env.BASE_URL,
        routes
    });
    
    export default router
    
    

    store——index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {
      },
      mutations: {
      },
      actions: {
      },
      modules: {
      }
    })
    
    

    components——Nav.vue

    <template>
        <div class="nav">
            <ul>
                <li>
                    <router-link to="/">主&nbsp;页</router-link>
                </li>
                <li>
                    <router-link to="/car">汽&nbsp;车</router-link>
                </li>
                <li>
                    <router-link to="/element">饿&nbsp;了&nbsp;么</router-link>
                </li>
            </ul>
        </div>
    </template>
    
    <script>
        export default {
            name: "Nav"
        }
    </script>
    
    <style scoped>
        .nav {
            height: 60px;
            background-color: #eee;
        }
        .nav ul {
             1100px;
            margin: 0 auto;
        }
        .nav li {
            float: left;
            padding: 15px 20px 0;
        }
        .nav a {
            border-bottom: 3px solid transparent;
            padding-bottom: 2px;
        }
        .nav a.router-link-exact-active {
            color: orange;
            border-bottom-color: orange;
        }
    </style>
    

    components——CarTag.vue

    <template>
        <div class="car-tag">
            <router-link :to="`/car/detail/${car.id}`">
                <img :src="car.img" alt="">
                <h3>
                    <span>{{ car.title }}</span>
                </h3>
            </router-link>
        </div>
    </template>
    
    <script>
        export default {
            name: "CarTag",
            props: ['car'],
        }
    </script>
    
    <style scoped>
        .car-tag {
            /*border: 1px solid black;*/
            border-radius: 10px;
            overflow: hidden;
             200px;
            /*height: 280px;*/
            float: left;
            margin-right: 25px;
            margin-bottom: 25px;
            background-color: beige;
            cursor: pointer;
        }
        .car-tag a.router-link-active {
            display: block;
        }
    
        .car-tag:nth-child(5n) {
            margin-right: 0;
        }
    
        .car-tag img {
             200px;
            height: 125px;
        }
    
        .car-tag h3 {
            margin: 5px auto;
            text-align: center;
        }
    </style>
    

    Django后端app文件夹(admin.py)

    from django.contrib import admin
    
    from . import models
    admin.site.register(models.Car)
    
    

    Django后端(apps.py)

    from django.apps import AppConfig
    
    
    class AppConfig(AppConfig):
        name = 'app'
    

    Django后端app文件夹(models.py)

    from django.db import models
    
    class Car(models.Model):
        title = models.CharField(max_length=64)
        price = models.DecimalField(max_digits=11, decimal_places=2)
        img = models.ImageField(upload_to='car', default='default.jpg')
        info = models.TextField()
    
        class Meta:
            db_table = 'old_boy_car'
            verbose_name = '汽车'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.title
    

    Django后端app文件夹(views.py)

    
    from django.http import JsonResponse
    from django.conf import settings
    from . import models
    def get_cars(request, *args, **kwargs):
        # print(request.method)
        # print(request.GET)
        # print(request.POST)
        # print(request.body)
        # return JsonResponse({'msg': 'get ok'})
    
        car_query = models.Car.objects.values('id', 'title', 'img')
        car_list = list(car_query)
        for car in car_list:
            car['img'] = '%s%s%s' % ('http://localhost:8000', settings.MEDIA_URL, str(car.get('img')))
        return JsonResponse(car_list, safe=False)
    
    
    def get_car(request, *args, **kwargs):
        pk = kwargs.get('pk')
        car_obj = models.Car.objects.filter(pk=pk).values('id', 'title', 'img', 'price', 'info').first()
        if car_obj:
            car_obj['img'] = '%s%s%s' % ('http://localhost:8000', settings.MEDIA_URL, str(car_obj.get('img')))
            return JsonResponse(car_obj, json_dumps_params={'ensure_ascii': False})
        return JsonResponse({'msg': '数据不存在'})
    

    Django后端d-proj文件夹urls文件

    from django.conf.urls import url
    from django.contrib import admin
    
    from django.views.static import serve
    from django.conf import settings
    
    from app import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^cars/$', views.get_cars),
        url(r'^car/(?P<pk>d+)/$', views.get_car),
    
    
        url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
    ]
    

    Django后端d-proj文件夹settings文件

     注掉csrf中间件
     # 'django.middleware.csrf.CsrfViewMiddleware',
    
    # 打开跨越
    CORS_ORIGIN_ALLOW_ALL = True
    
    # ap:国际化配置
    # TODO 国际化配置
    LANGUAGE_CODE = 'zh-hans'
    TIME_ZONE = 'Asia/Shanghai'
    USE_TZ = False
    
    # media
    MEDIA_URL = '/media/'
    # 项目media文件夹的绝对路径
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media'
    
  • 相关阅读:
    python数据库操作读书笔记
    python玩微信跳一跳实验报告
    制作自己的第一个网页
    python文件读写笔记
    Ethernet(以太网) 详解 MAC、MII、PHY
    Ethernet(以太网) 物理介质(10Base、100Base-T、100Base-TX等)
    QByteArray 转 QBitArray
    QT 线程应用
    QT release 发布打包压缩
    Qt中利用qDebug()记日志到文件
  • 原文地址:https://www.cnblogs.com/gfhh/p/12081488.html
Copyright © 2011-2022 走看看