Python Day 79 Vue框架

  ##一、走進Vuejavascript

#一、what -- 什麼是Vue
    漸進式 JavaScript 框架、能夠獨立完成先後端分離式web項目的JavaScript框架

#二、why -- 爲何要學習Vue
三大主流框架之一:Angular React Vue
先進的前端設計模式:MVVM
能夠徹底脫離服務器端,之前端代碼複用的方式渲染整個頁面:組件化開發

#三、special -- 特色
1)單頁面 - 硬件要求低
2)組件化開發
3)數據驅動
4)數據的雙向綁定
5)虛擬DOM
6)輕量級

#四、how -- 如何使用Vue
- 開發版本:[vue.js](https://vuejs.org/js/vue.js)
- 生產版本:[vue.min.js]
<div id="app">
    {{ }}
</div>
<script src="js/vue.min.js"></script> //下載到本引入vue
<script>
    new Vue({
        el: '#app'
    })
</script>

   ##二、Vue實例css

   ##2-一、el實例html

new Vue({
    el: '#app'
})
// 實例與頁面掛載點一一對應
// 一個頁面中能夠出現多個實例對應多個掛載點
// 實例只操做掛載點內部內容

  ##2-二、data數據前端

<div id='app'>
    {{ msg }}
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            msg: '數據',
        }
    })
    console.log(app.$data.msg);
    console.log(app.msg);
</script>
<!-- data爲插件表達式中的變量提供數據 -->
<!-- data中的數據能夠經過Vue實例直接或間接訪問-->

  ##2-三、methods 方法vue

<style>
    .box { background-color: orange }
</style>
<div id='app'>
    <p class="box" v-on:click="pClick">測試</p>
    <p class="box" v-on:mouseover="pOver">測試</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        methods: {
            pClick () {
                // 點擊測試
            },
            pOver () {
                // 懸浮測試
            }
        }
    })
</script>
<!-- 瞭解v-on:爲事件綁定的指令 -->
<!-- methods爲事件提供實現體-->

  ##2-四、computed 計算屬性java

<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>監聽多個變量</title></head><body><divid="app"><inputtype="text"v-model="a_val"><inputtype="text"v-model="b_val"><inputtype="text"v-model="c_val"><p>{{val_fn}}</p></div></body><scriptsrc="js/vue.js"></script><script>newVue({el:'#app',data:{a_val:'',b_val:'',c_val:'',},//computed內部書寫方法-管理能夠監聽多個變量的方法//1)方法名能夠直接做爲變量被渲染,值爲方法的返回值//2)在方法名被渲染後(在頁面中使用了),方法內部的全部變量都會被監聽//3)computed用來解決一個變量值依賴一個或多個變量值computed:{val_fn(){//this.a_val;//this.b_val;//this.c_val;console.log('該方法被調用了');returnthis.a_val+this.b_val+this.c_val;}}})</script></html>
案例1
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <div id="app">
        <p>
            姓:<input type="text" v-model="last_name">
        </p>
         <p>
            名:<input type="text" v-model="first_name">
        </p>
        <p>
            姓名:{{ full_name }}
        </p>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            last_name: '',
            first_name: '',
        },
        computed: {
            full_name () {
                return this.last_name + ' ' + this.first_name;
            }
        }
    })
</script>
</html>
案例2

  ##2-五、watch 監聽屬性node

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>監聽屬性</title>
</head>
<body>
    <div id="app">
        <p>
            姓名:<input type="text" v-model="full_name">
        </p>
        <p>
            姓:<input type="text" v-model="last_name">
        </p>
         <p>
            名:<input type="text" v-model="first_name">
        </p>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            full_name: '',
            last_name: '',
            first_name: '',
        },
        // watch內部書寫方法 - 管理 監聽綁定的屬性(提早要存在) 的方法
        // 1)方法名 被監聽的變量名(屬性)
        // 2) 在方法名被渲染後,方法名錶明的屬性值改變,綁定的方法就會被調用
        // 3)watch用來解決多個變量值依賴一個變量值
        watch: {
            full_name () {
                console.log('被調用了');
                // full_name變量值改變,要完成的任何邏輯均可以書寫在此方法中
                let name = this.full_name.split(' ');
                this.last_name = name[0];
                this.first_name = name[1];
            }
        }
    })
</script>
</html>
View Code

  ##2-六、delimiters 分隔符ios

<div id='app'>
    ${ msg } //修改後的分隔符
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'message'
        },
        delimiters: ['${', '}']  
    })
</script>

  ##三、生命週期鉤子web

 

表示一個vue實例從建立到銷燬的這個過程,將這個過程的一些時間節點賦予了對應的鉤子函數

鉤子函數: 知足特色條件被回調的方法

#重點掌握兩個方法
    created
    mounted

#vue api 連接  生命週期
https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90  


#生命週期圖示: 可直接查看官網
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>vue組件的生命週期鉤子</title>
</head>
<body>
    <div id="app">
        <h1>一個vue組件從建立到銷燬整個生命週期過程當中一些時間節點回調的方法</h1>
        <local-tag></local-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    let localTag = {
        template: `
        <div>
            <h2 @click="btnClick">{{ msg }}</h2>
        </div>
        `,
        data () {
            return {
                msg: '局部組件',
                x: 'x',
                y: 'y'
            }
        },
        methods: {
            btnClick () {
                console.log(this.msg)
            },
            zzz() {}
        },
        beforeCreate () {
            console.log('組件開始建立,數據和事件都爲建立');
            console.log(this.msg);
            console.log(this.btnClick);
            console.log(this.$data);
        },
        pppp: [1, 2, 3],
        created () {
            console.log('組件已經建立完畢,數據與事件都準備就緒');
            console.log(this.msg);
            console.log(this.btnClick);
            console.log(this.$data);
            console.log(this.$options.methods);
            console.log(this.$options.pppp);
        },
    };

    new Vue({
        el: '#app',
        components: {
            localTag,
        }
    })
</script>
</html>
View Code

  ##四、Vue指令ajax

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>文本指令</title>
</head>
<body>
    <div id="app">
        <!--一、插值表達式:在內部直接寫變量或變量表達式-->
        <p>{{ msg }}</p>
        <p>{{ (num + 1 - 3) / 2 }}</p>

        <!--二、v-text v-html v-once 三個文本指令 -->
        <!--v-text:純文本-->
        <p v-text="msg"></p>
        <!--v-html:能夠解析標籤-->
        <p v-html="'<b>加粗文本</b>'"></p>
        <p v-html="htmlMSG" @click="changeMsg"></p>
        <!--v-once:插值表達式渲染文本,once來限制文本不可修改-->
        <!--插值表達式中一個變量被限制,整個結果都被限制-->
        <p v-once="htmlMSG">{{ htmlMSG + msg }}</p>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'message',
            num: 10,
            htmlMSG: '<b>加粗文本</b>'
        },
        methods: {
            changeMsg: function () {
               this.htmlMSG = '<i>加粗文本</i>';
               this.msg = '11111111111111';
            }
        }
    })
</script>
</html>
文本指令
<style type="text/css">
    [v-cloak] { display: none; }
</style>
<div id="app" v-cloak>
    {{ msg }}
</div>
<script src="js/vue.min.js"></script>
<script type="text/javascript">
    new Vue({
        el: "#app",
        data: {
            msg: "message"
        }
    })
</script>
<!-- 避免頁面閃爍-->
斗篷指令解決閃爍問題
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>事件指令</title>
    <style>
        [aaa*='2'] {
            color: red;
        }
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>
    <div id="app" v-cloak aaa="123">
        <!-- v-on指令: 1)明確事件名 2)明確事件函數  v-on:事件名="事件函數"  -->

        <!--一、基礎的事件綁定-->
        <p v-on:click="clickAction">單擊</p>
        <p v-on:dblclick="dblclickAction">雙擊</p>

        <!--二、綁定事件並傳參-->
        <ul>
            <li v-on:click="liAction(0)">{{ li1 }}</li>
            <li v-on:click="liAction(1)">222</li>
            <li v-on:click="liAction(2)">333</li>
        </ul>

        <!--三、傳遞事件對象-->
        <p v-on:click="sysAction1">不傳自定義參數</p>
        <p v-on:click="sysAction2(888, $event)">傳自定義參數</p>

        <!--四、v-on: 能夠簡寫爲 @ -->
        <p @click="clickAction">單擊</p>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
              li1: '111'
        },
        methods: {
            clickAction: function () {
                alert('點擊')
            },
            dblclickAction () {
                alert('雙擊')
            },
            liAction (index) {
                // alert('li被點擊了');
                // alert(this.li1);
                alert(index);
            },
            sysAction1 (ev) {
                console.log(ev)
            },
            sysAction2 (num, ev) {
                console.log(num);
                console.log(ev);
            }

        }

    })
</script>
</html>
事件指令
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>屬性指令</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: orange;
        }
        .wrap {
            width: 100px;
            height: 100px;
            background-color: red;
        }

        .kiss {
            width: 150px;
            height: 150px;
            background-color: cyan;
        }
        .x {
            width: 300px;
        }
        .y {
            height: 300px;
        }
        .z {
            background-color: brown;
        }
    </style>
</head>
<body>
    <div id="app">

        <!-- v-bind屬性指令 :屬性名="屬性變量",v-bind: 能夠簡寫爲: -->
        <!--eg: v-bind:class='myClass' | v-bind:style='myStyle' | v-bind:aaa='myAAA' -->
        <div class="box" v-bind:style="myStyle" @click="changeColor('pink')"></div>

        <!--一、操做單個樣式:w變量的值就是爲屬性寬提供數據的-->
        <div class="box" v-bind:style="{'width': w}" @click="changeWidth"></div>

        <!--二、操做多個樣式: more_style是一個對象變量,能夠賦值多個key:value樣式-->
        <div class="box" v-bind:style="more_style" @click="changeStyle"></div>

        <!--三、v-bind: 能夠簡寫爲 :,能夠綁定全部系統和自定義屬性,屬性一旦綁定,後方就是變量 -->
        <div :aaa="AAA">簡寫v-bind</div>

        <!--四、操做單個類名-->
        <!--直接賦值:c1就是變量,變量的值就是類名-->
        <div :class="c1" @click="changeClass"></div>
        <!--布爾切換:該div有一個kiss類名,kiss_able的true或false決定kiss是否生效-->
        <div :class="{kiss: kiss_able}"></div>

        <!--五、操做多個類名: [變量1, ..., 變量n] 每一個變量的值都是該標籤的類名 -->
        <div :class="[x, y, {z: is_z}]"></div>

    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            myStyle: 'background-color: red;',
            w: '400px',
            more_style: {
                width: '100px',
                height: '100px',
                borderRadius: '50%',
                backgroundColor: 'cyan'
            },
            AAA: 'BBB',
            c1: 'wrap',
            kiss_able: true,
            x: 'x',
            y: 'y',
            // z: 'z',
            is_z: true
        },
        methods: {
            changeColor (color) {
                this.myStyle = 'background-color: ' + color + ';'
            },
            changeWidth () {
                this.w = '500px'
            },
            changeStyle () {
                this.more_style.borderRadius = '30%'

                // this.more_style = {
                //     width: '200px',
                //     height: '200px',
                //     borderRadius: '50%',
                //     backgroundColor: 'tan'
                // }
            },
            changeClass () {
                if (this.c1 === 'box') {
                    this.c1 = 'wrap';
                } else {
                    this.c1 = 'box';
                }

                // 布爾類型值來回切換
                this.kiss_able = !this.kiss_able;
            }
        }
    })
</script>
</html>
屬性指令
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <div id="app">
        <!-- v-model 表單指令 v-model="變量"  變量給value屬性提供值 -->

        <!--一、數據的雙向綁定-->
        <input type="text" v-model="val">
        <input type="text" v-model="val">
        <p>{{ val }}</p>

        <form action="">
            <!--二、普通輸入框: 直接綁定變量便可 -->
            <input type="password" v-model="val">

            <!--三、單選框-->
            <!--radio_val的值是多個單選框中一個的value值,表明該單選框默認選中-->
            <p>
                <label for="male">男</label>
                <input id="male" type="radio" value="male" v-model="radio_val" name="sex">
                <label for="female">女</label>
                <input id="female" type="radio" value="female" v-model="radio_val" name="sex">
                <button @click="alertValue">單選框提交給後臺的value</button>
                <span>{{ radio_val + '被選中' }}</span>
            </p>

            <!--四、獨立使用的複選框 -->
            <!--sure_val的值爲true|false,決定該單個複選框是否選中-->
            <p>
                <input type="checkbox" name="sure" value="贊成" v-model="sure_val">
                <span>{{ sure_val }}</span>
            </p>
            request.GET.get('sure', None)
            <!--五、複選框-->
            <!--hobby_val的值是數組,裏面用來存放複選框全部選項的值,值存在表明該選框選中-->
            <p><input type="checkbox" value="male" name="hobby" v-model="hobby_val"><input type="checkbox" value="female" name="hobby" v-model="hobby_val">
                哇塞<input type="checkbox" value="?" name="hobby" v-model="hobby_val">
                <span>{{ hobby_val }}</span>
            </p>

            <p>
                <input type="submit">
            </p>
        </form>

    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            val: '',
            radio_val: 'male',
            sure_val: true,
            hobby_val: ['?', 'male']
        },
        methods: {
            alertValue () {
                alert(this.radio_val)
            }
        }
    })
</script>
</html>
表單指令
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        [v-cloak] {
            display: none;
        }
        .box {
            width: 200px;
            height: 200px;
        }
        .b1 {background-color: orange;}
        .b2 {background-color: cyan;}

        .r {background-color: red;}
        .b {background-color: blue;}
        .g {background-color: green;}
    </style>
</head>
<body>
    <div id="app" v-cloak>
        <!-- v-if | v-show 條件指令: v-if="變量" | v-show="變量" -->

        <!--一、v-if | v-show比較:二者綁定的變量值都是 true|false-->
        <p>
            <button @click="toggleAction(true)">顯示</button>
            <button @click="toggleAction(false)">隱藏</button>
        </p>
        <!--v-if在隱藏時,不被渲染 | v-show在隱藏時,採用display: none存在-->
        <div class="box b1" v-if="is_show"></div>
        <div class="box b2" v-show="is_show"></div>

        <!--二、v-if、v-else-if、v-else 分支家族 -->
        <p>
            <button @click="toggleShow('red')">紅</button>
            <button @click="toggleShow('blue')">藍</button>
            <button @click="toggleShow('green')">綠</button>
        </p>
        <div class="box r" v-if="color == 'red'"></div>
        <div class="box b" v-else-if="color == 'blue'"></div>
        <div class="box g" v-else></div>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            is_show: false,
            color: 'red'
        },
        methods: {
            toggleAction(is_show) {
                this.is_show = is_show;
            },
            toggleShow(color) {
                this.color = color;
            }
        }
    })
</script>
</html>
條件指令
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>循環指令</title>
</head>
<body>
    <div id="app">
        <div>{{ arr }}</div>
        <hr>
        <ul>
            <li>{{ arr[0] }}</li>
            <li>{{ arr[1] }}</li>
            <li>{{ arr[2] }}</li>
        </ul>
        <hr>
        <!-- v-for 循環指令: v-for="ele in 容器變量" -->

        <!--一、array的循環-->
        <ul>
            <li v-for="s in arr">{{ s }}</li>
        </ul>
        <hr>
        <!--key屬性是vue的屬性,表示爲改標籤在內存中創建緩存的依據-->
        <ul>
            <li v-for="(s, i) in arr" :key="s" b="b">第{{ i }}個:{{ s }}</li>
        </ul>
        <hr>
        <!--二、對象的循環-->
        <ul>
            <li v-for="v in person">{{ v }}</li>
        </ul>
        <hr>
        <ul>
            <li v-for="(v, k) in person">{{ k }}:{{ v }}</li>
        </ul>
        <hr>
        <ul>
            <li v-for="(v, k, i) in person">{{ k }}:{{ v }}:{{ i }}</li>
        </ul>
        <hr>

        <!--name: * | sex:*-->
        <!--name: * | sex:*-->
        <!--name: * | sex:*-->

        <p v-for="stu in stus">
            <span v-for="(v, k, i) in stu">
                <b v-if="i != 0"> | </b>
                <b>{{ k }}:{{ v }}</b>
            </span>
        </p>

    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            arr: ['aaa', 'bbb', 'ccc'],
            person: {
                'name': 'Bob',
                'age': 18,
                'sex': ''
            },
            stus: [
                {
                    'name': 'Alex',
                    'sex': '哇塞'
                },
                {
                    'name': 'Egon',
                    'sex': '哇哦'
                },
                {
                    'name': 'Jason',
                    'sex': '我去'
                }
            ]
        }
    })
</script>
</html>
循環指令
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>todolist</title>
    <style>
        li:hover {
            cursor: pointer;
            color: red;
        }
    </style>
</head>
<body>
    <div id="app">
        <input type="text" v-model="msg_val">
        <button @click="sendMsg">留言</button>

        <ul>
            <li v-for="(msg, i) in msgs" @click="deleteMsg(i)">{{ msg }}</li>
        </ul>
    </div>

</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            // msgs: ['第一條留言', '第二條留言'],
            msgs: localStorage.msgs ? localStorage.msgs.split(',') : [],
            msg_val: '',
        },
        methods: {
            sendMsg () {
                // 1)數據爲空直接結束
                if (!this.msg_val) return;

                // 2)數據添加到留言數組中
                // this.msgs.push(this.msg_val);  // 尾增
                this.msgs.unshift(this.msg_val);  // 首增

                // 數據同步到前臺數據庫
                localStorage.msgs = this.msgs;

                // 3)清空輸入框
                this.msg_val = '';
            },
            deleteMsg (index) {
                // console.log(index);
                this.msgs.splice(index, 1);
                // 數據同步到前臺數據庫
                localStorage.msgs = this.msgs;
            }
        }
    })
</script>
</html>
todolist案例
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>路飛導航案例</title>
    <style>
        body {
            margin: 0;
            height: 3000px;
        }
        ul {
            margin: 0;
            padding: 0;
            list-style: none;
        }
    </style>
    <style>
        .footer {
            width: 100%;
            height: 120px;
            background-color: rgba(0, 0, 0, 0.8);
        }
    </style>
    <style>
        .header {
            width: 100%;
            background-color: #ccc;
            position: fixed;
        }
        .header-slogan {
            width: 1200px;
            font: normal 14px/36px '微軟雅黑';
            color: #333;
            margin: 0 auto;
        }
        .header-nav {
            width: 1200px;
            margin: 0 auto;
            /*background-color: orange;*/
        }
        .header-nav:after {
            content: "";
            display: block;
            clear: both;
        }
        .header-logo, .header-menu {
            float: left;
        }
        .header-owner {
            float: right;
        }
        .header-logo {
            width: 118px;
            height: 36px;
            background: url("img/header-logo.svg") no-repeat;
        }
        .header-menu {
            margin-left: 40px;
        }
        .header-menu li {
            float: left;
            margin-top: 26px;
            cursor: pointer;
            margin-right: 20px;
        }
        .header-menu li:hover {
            color: #444;
            padding-bottom: 5px;
            border-bottom: 2px solid #444;
        }
        .header-owner {
            padding-top: 26px;
        }
        .active {
            color: #444;
            padding-bottom: 5px;
            border-bottom: 2px solid #444;
        }
    </style>
    <style>
        .body-box {
            width: 1200px;
            height: 2000px;
            margin: 0 auto;
        }
        .box-normal-course { background-color: pink }
        .box-light-course { background-color: deeppink }
        .box-super-course { background-color: hotpink }
    </style>
</head>
<body>
    <div id="app">
        <div class="header">
            <div class="header-slogan">老男孩IT教育集團 | 幫助有志向的年輕人經過努力學習得到體面的工做和生活!</div>
            <div class="header-nav">
                <h1 class="header-logo"></h1>
                <ul class="header-menu">
                    <li :class="{active: page == 'normal'}" @click="togglePage('normal')">免費課</li>
                    <li :class="{active: page == 'light'}" @click="togglePage('light')">輕課</li>
                    <li :class="{active: page == 'super'}" @click="togglePage('super')">學位課</li>
                </ul>
                <div class="header-owner">
                    <div v-if="is_logout">
                        <span>登錄</span> | <span>註冊</span>
                    </div>
                    <div v-else>
                        <span>Owen</span> | <span>我的中心</span>
                    </div>
                </div>
            </div>
        </div>

        <div class="body">
            <div class="body-box box-normal-course" v-if="page == 'normal'"></div>
            <div class="body-box box-light-course" v-else-if="page == 'light'"></div>
            <div class="body-box box-super-course" v-else></div>
        </div>

        <div class="footer"></div>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            is_logout: true,
            page: 'normal'
        },
        methods: {
            togglePage(page) {
                this.page = page;
            }
        }
    })
</script>
</html>
路飛學成案例

  ##五、前端數據庫

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>前臺數據庫</title>
</head>
<body>
    <h1>前臺數據庫</h1>
</body>
<script>
    // window.localStorage  // 永久存儲倉庫
    // window.sessionStorage  // 臨時存儲倉庫

    // 存,存完註釋
    // localStorage['name'] = 'Owen'
    // 取
    console.log(localStorage.name);

    // 存,存完註釋
    // sessionStorage.age = 18;
    // 取
    console.log(['age']);

    // localStorage.msgs = []

    // 清空
    localStorage.clear();
    localStorage.clear();

    // localStorage.arr = [1, 2, 3];
    // localStorage.obj = {'1': 1};

</script>
</html>
前端數據庫

  ##六、組件

#組件規則
每個組件都是一個vue實例
每一個組件均具備自身的模板template,根組件的模板就是掛載點
每一個組件模板只能擁有一個根標籤

子組件的數據具備做用域,以達到組件的複用

  ##6-一、根組件

<div id="app">
    <h1>{{ msg }}</h1>
</div>
<script type="text/javascript">
    // 經過new Vue建立的實例就是根組件(實例與組件一一對應,一個實例就是一個組件)
    // 每一個組件組件均擁有模板,template
    var app = new Vue({
        // 根組件的模板就是掛載點
        el: "#app",
        data : {
            msg: "根組件"
        },
        // 模板: 由""包裹的html代碼塊,出如今組件的內部,賦值給組件的$template變量
        // 顯式書寫模塊,就會替換掛載點,但根組件必須擁有掛載點
        template: "<div>顯式模板</div>"
    })
    // app.$template
</script>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <h1 id="app">
        {{ msg }}
    </h1>
    <div id="main">
        {{ msg }}
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    // 1、new Vue建立的是vue實例,一個實例就是一個vue組件,new出了的實例稱之爲根組件
    // 注:在實際開發中一個頁面只有一個根組件
    // 2、每一個組件均由 html模板 css樣式 js邏輯 組成
    //      html模板: template,根組件的模板就採用掛載點便可,無需建立自身template
    //      注:掛載點是必須的(做爲虛擬DOM渲染替換的依據),掛載點能夠讀取,做爲根組件的模板,使用根組件無需書寫template
    // 3、根組件內部能夠註冊使用n個子組件,子組件必須擁有本身的 html模板 css樣式 js邏輯
    //      若是建立子組件 | 如何使用子組件 | 父子組件間的通訊
    let app = new Vue({
        el: '#app',
        data: {
            msg: 'app的msg',
            c: 'red'
        },
        // template: '<ul>{{ msg }}</ul>',
        template: `<h1 id="app" :style="{color: c}" @click="action">
{{ msg }}
</h1>
`,
        methods: {
            action () {
                alert(this.msg)
            }
        }
    });
    let main = new Vue({
        el: '#main',
        data: {
            msg: 'main的msg'
        }
    });
    // 知識點:利用原生js完成兩個組件的交互
    // 獲取組件的數據
    // console.log(app.msg);
    // 修改組件的數據
    // app.msg = '12345';
    main.msg = app.msg;

</script>
</html>
根組件案例 總結

  ##6-二、局部組件

<div id="app">
    <local-tag></local-tag>
    <local-tag></local-tag>
</div>
<script>
    var localTag = {
        data () {
            return {
                count: 0
            }
        },
        template: '<button @click="btnAction">局部{{ count }}</button>',
        methods: {
            btnAction () {
                this.count ++
            }
        }
    }
    new Vue({
        el: "#app",
        components: {
            'local-tag': localTag
        }
    })
</script>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>局部組件</title>
    <style>
        .box {
            width: 200px;
            text-align: center;
            border: 1px solid black;
            border-radius: 10px;
            overflow: hidden;
            float: left;
        }
        .box img {
            width: 100%;
        }
        .box p {
            margin: 0;
        }
        .box span:hover {
            cursor: pointer;
            color: orange;
        }
    </style>
</head>
<body>
    <div id="app">
        <!--<div class="box">-->
            <!--<img src="http://a.hiphotos.baidu.com/image/h%3D300/sign=e543b919a151f3dedcb2bf64a4eff0ec/4610b912c8fcc3cebba8b8e09c45d688d53f20fc.jpg" alt="">-->
            <!--<p>野獸</p>-->
        <!--</div>-->

        <!--<box></box>-->
        <!--<box></box>-->

        <!--<box-tag></box-tag>-->
        <!--<box-tag></box-tag>-->

        <!--
        問題:數據 父組件 => 子組件
        父組件根據數組數據(box_data)渲染多個子組件,遍歷獲得的數據(box_obj)是渲染子組件的,
        如何將遍歷的數據傳遞給子組件
        -->
        <box-tag v-for="box_obj in box_data"></box-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    // 後臺的數據
    let data = [
            {
                img_url: 'img/001.jpg',
                img_title: '野獸1'
            },
            {
                img_url: 'img/001.jpg',
                img_title: '野獸2'
            },
            {
                img_url: 'img/001.jpg',
                img_title: '野獸3'
            }
        ];


    // 建立局部組件 => 在根組件中註冊 => 解析{}中的vue語法 => 造成組件
    let box = {
        template: `
        <div class="box">
            <img src="img/001.jpg" alt="">
            <p>
                <span @click="btnClick">點擊了{{ num }}下</span>
                <p>野獸</p>
            </p>
        </div>
        `,
        // data: {  // 錯誤的
        //     num: 0
        // },
        // data: function () {  // 每一個複用的子組件都應該有本身的一套數據,因此要用一個局部做用域存儲,保證數據的隔離性
        //     return {  // data的值仍是字典,因此函數的返回值是字典便可
        //         num: 0
        //     }
        // },
        data () {
            return {
                num: 0
            }
        },
        methods: {
            btnClick () {
                // alert(123)
                this.num += 1;
            }
        }
    };

    new Vue({
        el: '#app',
        components: {
            // box,  // key與value變量同名
            boxTag: box,  // js支持的駝峯命名法與html的-鏈接有語法對應
            // 'box-tag': box,
        },
        data: {
            box_data: data
        }
        // 僞代碼:頁面的data數據能夠由後臺提供,前臺獲取後賦值給 vue data成員中的變量,vue就能夠渲染到頁面中
        // $.ajax({
        //     success: function (data) {
        //         this.box_data = data
        //     }
        // })
    })
</script>
</html>
局部組件案例

  ##6-三、全局組件

<div id="app">
    <global-tag></global-tag>
    <global-tag></global-tag>
</div>
<script>
    Vue.component('global-tag', {
        data () {
            return {
                count: 0
            }
        },
        template: '<button @click="btnAction">全局{{ count }}</button>',
        methods: {
            btnAction () {
                this.count ++
            }
        }
    })
    new Vue({
        el: "#app"
    })
</script>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>全局組件</title>
</head>
<body>
    <div id="app">
        <!--<p-tag></p-tag>-->
        <!--<p-tag></p-tag>-->

        <g-tag></g-tag>
        <g-tag></g-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    let pTag = {
        template: `
        <p>
            <span @click="action">{{ num }}</span>
        </p>
        `,
        data () {
            return {
                num: 0
            }
        },
        methods: {
            action() {
                this.num++;
            }
        }
    };

    // 全局組件,經過 Vue.component('組件名', 組件對象主體);
    Vue.component('gTag', {
            template: `
            <p>
                <span @click="action">{{ num }}</span>
            </p>
            `,
            data () {
                return {
                    num: 0
                }
            },
            methods: {
                action() {
                    this.num++;
                }
            }
        }
    );

    new Vue({
        el: '#app',
        components: {
            // pTag,
        }
    })
</script>
</html>
全局組件案例

  ##6-四、父子組件

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>父子組件</title>
    <style>
        body, h1, h2 {
            margin: 0;
        }
    </style>
    <style>
        .header {
            height: 120px;
            background-color: orange;
        }
        .body {
            height: 800px;
            background-color: pink;
        }
        .footer {
            height: 180px;
            background-color: brown;
        }
    </style>
</head>
<body>
    <div id="app">
        <view-tag v-if="page == 'tag'" @click="action"></view-tag>
        <view-tag-2 v-else-if="page == 'tag2'"></view-tag-2>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    // 小組件
    let headerTag = {
        template: `
        <div class="header">
            <h1 style="text-align: center; line-height: 120px">頭</h1>
        </div>
        `,
    };

    let footerTag = {
        template: `
        <div class="footer" >
            <h2 style="text-align: center; line-height: 180px">尾</h2>
        </div>
        `,
    };

    // 頁面組件
    let viewTag = {
        template: `
        <div class="view-tag">
            <header-tag></header-tag>
            <div class="body" style="background-color: lawngreen"></div>
            <footer-tag></footer-tag>
        </div>
        `,
        components: {
            headerTag,
            footerTag,
        }
    };

    let viewTag2 = {
        template: `
        <div class="view-tag">
            <header-tag></header-tag>
            <div class="body" style="background-color: cyan"></div>
            <footer-tag></footer-tag>
        </div>
        `,
        components: {
            headerTag,
            footerTag,
        }
    };

    // 根組件
    new Vue({
        el: '#app',
        data: {
            // 問題:數據 子組件 => 父組件
            // page的值須要在父組件中修改,單擊事件只能在子組件中觸發
            // 子組件觸發事件後將要修改的值傳出給父組件,在父組件中完成數據的修改
            page: 'tag'
        },
        components: {
            viewTag,
            viewTag2,
        },
        methods: {
            action () {
                alert('給組件標籤綁定事件沒法激活')
            }
        }
    })
</script>
</html>
View Code

  ##6-五、數據父傳子

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>父傳子</title>
</head>
<body>
    <div id="app">
        <!--總結:
        1)父組件模板中寫子組件標籤
        2)父組件的數據綁定給子組件標籤的自定義屬性
        3)在子組件內部經過props拿到自定義屬性
        4)使用自定義屬性就能夠得到父組件的數據
        -->
        <sub-tag :a="msg"></sub-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    let subTag = {
        // 子組件經過props實例成員獲取自身自定義屬性
        props: ['a'],
        template: `
        <div>
            <h1>{{ a }}</h1>
        </div>
        `
    };

    new Vue({
        el: '#app',
        data: {
            msg: '父級數據'
        },
        components: {
            subTag,
        }
    })
</script>
</html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>父傳子案例</title>
    <style>
        .box {
            width: 200px;
            text-align: center;
            border: 1px solid black;
            border-radius: 10px;
            overflow: hidden;
            float: left;
        }
        .box img {
            width: 100%;
        }
        .box p {
            margin: 0;
        }
        .box span:hover {
            cursor: pointer;
            color: orange;
        }
    </style>
</head>
<body>
    <div id="app">
        <box-tag v-for="box_obj in box_data" :box_obj="box_obj"></box-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>

    let boxTag = {
        props: ['box_obj'],
        template: `
        <div class="box">
            <img :src="box_obj.img_url" alt="">
            <p>
                <span @click="btnClick">點擊了{{ num }}下</span>
                <p>{{ box_obj.img_title }}</p>
            </p>
        </div>
        `,
        data () { //data要定義爲函數形式,函數就存在了做用域,這樣就能夠達到隔離性
            return {
                num: 0
            }
        },
        methods: {
            btnClick () {
                this.num += 1;
            }
        }
    };


    // 後臺的數據
    let back_data = [
            {
                img_url: 'img/001.jpg',
                img_title: '野獸1'
            },
            {
                img_url: 'img/002.jpg',
                img_title: '野獸2'
            },
            {
                img_url: 'img/003.jpg',
                img_title: '野獸3'
            }
        ];

    new Vue({
        el: '#app',
        data: {
            box_data: back_data
        },
        components: {
            boxTag,
        }
    })
</script>
</html>
數據父傳子案例

  ##6-五、數據子傳父

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <div id="app">
        <h1>{{ title }}</h1>
        <sub-tag @send_val="recv_val"></sub-tag>
    </div>
</body>
<script src="js/vue.js"></script>
<script>
    let subTag = {
        template: `
        <div>
            <input type="text" v-model="val">
            <button @click="changeTitle">修改</button>
        </div>
        `,
        data () {
            return {
                val: ''
            }
        },
        methods: {
            changeTitle () {
                if (!this.val) return;

                // 若是有數據,將數據發生給父組件
                this.$emit('send_val', this.val);

                this.val = '';
            }
        }

    };

    new Vue({
        el: '#app',
        data: {
            title: '父組件標題'
        },
        components: {
            subTag
        },
        methods: {
            recv_val (val) {
                this.title = val;
            }
        }
    })
</script>
</html>
View Code

  ##七、Vue-CLI項目搭建

  ##7-一、環境搭建

#一、安裝node
        官網下載安裝包,傻瓜式安裝:https://nodejs.org/zh-cn/
#二、安裝cnpm
        npm install -g cnpm --registry=https://registry.npm.taobao.org
#三、安裝腳手架
        cnpm install -g @vue/cli
#四、若是安裝出現問題 可執行
        npm cache clean --force

  ##7-二、項目建立

1、建立項目
    vue create 項目名
    // 要提早進入目標目錄(項目應該建立在哪一個目錄下)
    // 選擇自定義方式建立項目,選取Router, Vuex插件

啓動

cnpm run serve / ctrl+c
// 要提早進入項目根目錄

訪問:
http://localhost:8080/

  ##7-二、建立好的vue項目怎麼移動到新的環境

1、拷貝文件除了node_modules該文件夾,其他文件拷貝到新得環境中
2、cmd進入新的項目目錄,執行cnpm install  重新安裝依賴
3、經過pycharm打開新建的vue項目
四、在pycharm中編輯該項目,點擊edit編輯,新建(+號)服務、選擇npm

5、安裝vue頁面腳本
若是沒有提示安裝的話 取setting中pluging

六、安裝完成重啓pycharm

   ##7-三、認識項目

node_modules:項目依賴

public:公用文件
    favicon.ico:頁面標籤圖標
    index.html:項目的惟一頁面(單頁面)
    
src:項目開發文件目錄
    assets:靜態資源
        css|js|img
    components:小組件
        *.vue
    views:視圖組件
        *.vue
    App.vue:根組件
    main.js:主腳本文件 程序入口文件
    router.js:路由腳本文件 - vue-router
    store.js:倉庫腳本文件 - vuex
    
*.xml|json|js:一系列配置文件
README.md:使用說明
import Vue from 'vue'  // node_modules下的依賴直接寫名字
import App from './App.vue'  // ./表明相對路徑的當前目錄,文件後綴軍能夠省略
import router from '@/router.js'  // @ 表明src的絕對路徑
import store from './store'
// 在main中配置的信息就是給整個項目配置
// 已配置 vue | 根組件App | 路由 | 倉庫
// 之後還能夠配置 cookie | ajax(axios) | element-ui

Vue.config.productionTip = false;  // Tip小提示

// 配置reset.css
import '@/assets/css/reset.css'

// new Vue({
//   router,
//   store,
//   render: h => h(App)
// }).$mount('#app')

new Vue({
    el: '#app',
    router: router,
    store,
    // render: function (fn) {
    //     return fn(App)
    // }
    // 解釋:function (h) {return 1} | (h) => {return 1} | h => 1
    render: readTemplateFn => readTemplateFn(App)
});
main.js
template>
    <!-- 模板區域 -->
</template>
<script>
    // 邏輯代碼區域
    // 該語法和script綁定出現
    export default {
        
    }
</script>
<style scoped>
    /* 樣式區域 */
    /* scoped表示這裏的樣式只適用於組件內部, scoped與style綁定出現 */
</style>
.vue 文件模板

  ##7-四、項目功能

  ##路由功能

{
    path: '/',
    name: 'home',
    // 路由的重定向
    redirect: '/home'
}

{
    // 一級路由, 在根組件中被渲染, 替換根組件的<router-view/>標籤
    path: '/one-view',
    name: 'one',
    component: () => import('./views/OneView.vue')
}

{
    // 多級路由, 在根組件中被渲染, 替換根組件的<router-view/>標籤
    path: '/one-view/one-detail',
    component: () => import('./views/OneDetail.vue'),
    // 子路由, 在所屬路由指向的組件中被渲染, 替換該組件(OneDetail)的<router-view/>標籤
    children: [{
        path: 'show',
        component: () => import('./components/OneShow.vue')
    }]
}
route.js
<!-- router-link渲染爲a標籤 -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link :to="{name: 'one'}">One</router-link> |

<!-- 爲路由渲染的組件佔位 -->
<router-view />
app.vue 根組件創建路由
// router的邏輯轉跳
this.$router.push('/one-view')

// router採用history方式訪問上一級
this.$router.go(-1)

  ##路由案例

<template>
    <div>
        <h1 :class="{active:is_active}" @click="btnClick">owen組件</h1>
    </div>
</template>

<script>
    export default {
        data (){
            return {
                is_active : false
            }
        },
        methods:{
            btnClick(){
                this.is_active = !this.is_active
            }
        }
    }
</script>

<style scoped>
    .active{
        color: red;
    }
</style>
在components文件夾中新建OwenComponent.vue
<!-- views/About.vue -->

<template>
    <div class="about">
        <h1>This is an about page</h1>
        <h2>好</h2>
        
        <!-- 使用組件 -->
        <owen-comp></owen-comp>
        <OwenComp></OwenComp>
    </div>
</template>
<script>
    // import OwenComp from '../components/OwenComponent'
    import OwenComp from '@/components/OwenComponent'  // 導入組件,組件名隨意
    export default {
        components: {
            OwenComp,  // 註冊組件
        }
    }
</script>
在views文件夾About.vue文件中
相關文章
相關標籤/搜索