目錄javascript
經過對框架的瞭解與運用程度,來決定其在整個項目中的應用範圍,最終能夠獨立以框架方式完成整個web前端項目
能夠獨立完成先後端分離式web項目的JavaScript框架
三大主流框架之一:Angular React Vue 先進的前端設計模式:MVVM 能夠徹底脫離服務器端,之前端代碼複用的方式渲染整個頁面:組件化開發
單頁面web應用 數據驅動 數據的雙向綁定 虛擬DOM
<div id="app"> {{ }} </div> <script src="js/vue.min.js"></script> <script> new Vue({ el: '#app' }) </script>
new Vue({ el: '#app' }) // 實例與頁面掛載點一一對應 // 一個頁面中能夠出現多個實例對應多個掛載點 // 實例只操做掛載點內部內容
<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實例直接或間接訪問-->
<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爲事件提供實現體-->
<div id="app"> <input type="text" v-model="a"> <input type="text" v-model="b"> <div> {{ c }} </div> </div> <script> // 一個變量依賴於多個變量 new Vue({ el: "#app", data: { a: "", b: "", }, computed: { c: function() { // this表明該vue實例 return this.a + this.b; } } }) </script>
<div id="app"> <input type="text" v-model="ab"> <div> {{ a }} {{ b }} </div> </div> <script> // 多個變量依賴於一個變量 new Vue({ el: "#app", data: { ab: "", a: "", b: "", }, watch: { ab: function() { // 邏輯根據需求而定 this.a = this.ab[0]; this.b = this.ab[1]; } } }) </script>
<div id='app'> ${ msg } </div> <script> new Vue({ el: '#app', data: { msg: 'message' }, delimiters: ['${', '}'] }) </script>
new Vue({ el: "#app", data: { msg: "message" }, beforeCreate () { console.log("實例剛剛建立"); console.log(this.msg); }, created () { console.log("實例建立成功, data, methods已擁有"); console.log(this.msg); }, mounted () { console.log("頁面已被vue實例渲染, data, methods已更新"); } // 拿到需求 => 肯定鉤子函數 => 解決需求的邏輯代碼塊 })
<div id="app"> <!-- 插值表達式 --> <p>{{ msg }}</p> <!-- eg:原文本會被msg替換 --> <p v-text='msg'>原文本</p> <!-- 能夠解析帶html標籤的文本信息 --> <p v-html='msg'></p> <!-- v-once控制的標籤只能被賦值一次 --> <p v-once>{{ msg }}</p> </div> <script type="text/javascript"> // 指令: 出如今html標籤中能夠被vue解析處理的全局屬性 new Vue({ el: "#app", data: { msg: "message" } }) </script>
<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> <!-- 避免頁面閃爍-->
<!-- 給自定義全局屬性綁定變量 --> <p v-bind:abc="abc"></p> <!-- 以原字符串形式綁定全局屬性 --> <p v-bind:title="'abc'"></p> <!-- 單類名綁定 --> <p v-bind:class="c1"></p> <!-- 多類名綁定 --> <p v-bind:class="[c2, c3]"></p> <!-- 類名狀態綁定 --> <p v-bind:class="{c4: true|false|var}"></p> <!-- 多類名狀態綁定 --> <p v-bind:class="[{c5: true}, {c6: flase}]"></p> <!-- 樣式綁定 --> <div :style="div_style"></div> <div :style="{width: '100px', height: '100px', backgroundColor: 'blue'}"></div> <script type="text/javascript"> new Vue({ el:"#app", data: { abc: "abc", c1: "p1", c2: "p2", c3: "p3", div_style: { width: "200px", height: "200px", backgroundColor: "cyan" } } }) </script> <!-- v-bind: 指令能夠簡寫爲 : -->
<!-- v-on: 指令 簡寫 @ --> <!-- 不傳參事件綁定,但事件回調方法能夠獲取事件對象 --> <p @click="fn"></p> <!-- ()能夠傳入具體實參 --> <p @click="fn()"></p> <!-- ()狀況下,事件對象應該顯式傳入 --> <p @click="fn($event)"></p>
<div id="app"> <!-- v-model針對於表單元素 --> <form action="" method="get"> <!-- 一、雙向綁定:服務於文本輸入框 --> <!-- v-model存儲的值爲輸入框的value值 --> <div> <input type="text" name="usr" v-model="in_val"> <input type="password" name="ps" v-model="in_val" > <textarea name="info" v-model="in_val"></textarea> </div> <!-- 二、單選框 --> <div> <!-- 單選框是以name進行分組,同組中只能發生單選 --> <!-- v-model存儲的值爲單選框的value值 --> 男:<input type="radio" name="sex" value="男" v-model="ra_val"> 女:<input type="radio" name="sex" value="女" v-model="ra_val"> {{ ra_val }} </div> <!-- 三、單一複選框 --> <!-- v-model存儲的值爲true|false --> <!-- 或者爲自定義替換的值 --> <div> <input type="checkbox" v-model='sin_val' true-value="選中" false-value="未選中" /> {{ sin_val }} </div> <!-- 四、多複選框 --> <!-- v-model存儲的值爲存儲值多複選框value的數組 --> <div> <input type="checkbox" value="喜愛男的" name="cless" v-model='more_val' /> <input type="checkbox" value="喜愛女的" name="cless" v-model='more_val' /> <input type="checkbox" value="不挑" name="cless" v-model='more_val' /> {{ more_val }} </div> </form> </div> <script type="text/javascript"> new Vue({ el: '#app', data: { in_val: '', // 默認值能夠決定單選框默認選項 ra_val: '男', // 默認值爲true,單一複選框爲選中,反之false爲不選中 sin_val: '', // 數組中存在的值對應的複選框默認爲選中狀態 more_val: ['喜愛女的','不挑'] } }) </script>
<div id="app"> <button @click="toggle">顯隱切換</button> <!-- v-if --> <div class="box r" v-if="isShow"></div> <!-- v-show --> <div class="box o" v-show="isShow"></div> <!-- 1.條件渲染的值爲true|false --> <!-- 2.true表明標籤顯示方式渲染 --> <!-- 3.false v-if不渲染到頁面,v-show以display:none渲染到頁面,但也不會顯示 --> <!-- v-if v-else-if v-else 案例 --> <ul> <li @mouseover="changeWrap(0)">red</li> <li @mouseover="changeWrap(1)">green</li> <li @mouseover="changeWrap(2)">blue</li> </ul> <!-- red頁面邏輯結構 --> <div class="wrap red" v-if="tag == 0" key="0">...</div> <!-- green頁面邏輯結構 --> <div class="wrap green" v-else-if="tag == 1" key="1">...</div> <!-- blue頁面邏輯結構 --> <div class="wrap blue" v-else key="2">...</div> <!-- v-if相關分支操做,在未顯示狀況下,是不會被渲染到頁面中 --> <!-- 經過key全局屬性操做後,渲染過的分支會創建key對應的緩存,提升下一次渲染速度 --> <!-- v-show 案例 --> <ul> <li @mouseover="changeMain(0)">red</li> <li @mouseover="changeMain(1)">green</li> <li @mouseover="changeMain(2)">blue</li> </ul> <!-- red頁面邏輯結構 --> <div class="main red" v-show="whoShow(0)">...</div> <!-- green頁面邏輯結構 --> <div class="main green" v-show="whoShow(1)">...</div> <!-- blue頁面邏輯結構 --> <div class="main blue" v-show="whoShow(2)">...</div> </div> <script type="text/javascript"> new Vue({ el: "#app", data: { isShow: false, tag: 0, flag: 0 }, methods: { toggle () { this.isShow = !this.isShow; }, changeWrap (num) { this.tag = num; }, changeMain (num) { // this.flag num this.flag = num; }, whoShow (num) { // this.flag num return this.flag == num; } } }) </script>
<div id="app"> <h1>{{ msg }}</h1> <!-- v-for="item in items" --> <!-- 遍歷的對象: 數組[] 對象(字典){} --> <ul> <li>{{ list[0] }}</li> <li>{{ list[1] }}</li> <li>{{ list[2] }}</li> <li>{{ list[3] }}</li> <li>{{ list[4] }}</li> </ul> <!-- n爲遍歷的元素值 --> <ul> <li v-for="n in list">{{ n }}</li> </ul> <!-- 通常列表渲染須要創建緩存 --> <!-- 列表渲染是循環,須要賦值變量給key,使用key須要v-bind:處理 --> <!-- v-for變量數組[]時,接收兩個值時,第一個爲元素值,第二個爲元素索引 --> <ul> <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li> </ul> <ul> <li>{{ dic['name'] }}</li> <li>{{ dic.age }}</li> <li>{{ dic.gender }}</li> </ul> <!-- v-for變量對象{}時,接收三個值時,第一個爲元素值,第二個爲元素鍵,第三個爲元素索引 --> <ul> <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li> </ul> <!-- 遍歷的嵌套 --> <div v-for="(person, index) in persons" :key="index" style="height: 21px;"> <div v-for="(v, k) in person" :key="k" style="float: left;">{{ k }} : {{ v }} </div> </div> </div> <script type="text/javascript"> new Vue({ el: "#app", data: { msg: "列表渲染", list: [1, 2, 3, 4, 5], dic: { name: 'zero', age: 88888, gender: 'god' }, persons: [ {name: "zero", age: 8}, {name: "egon", age: 78}, {name: "liuXX", age: 77}, {name: "yXX", age: 38} ] } }) </script>
<div id="app"> <div> <input type="text" v-model="val"> <button type="button" @click="submitMsg">提交</button> </div> <ul> <li v-for="(v, i) in list" :key="i" @click="removeMsg(i)">{{ v }}</li> </ul> {{ list }} </div> <script type="text/javascript"> new Vue({ el: "#app", data: { val: "", list: [] }, methods: { submitMsg () { if (this.val) { this.list.push(this.val); this.val = "" } }, removeMsg(index) { this.list.splice(index, 1) } } }) </script>
<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>
<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>
<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>
<div id="app"> <global-tag :sup_data1='sup_data1' :supData2='sup_data2'></global-tag> </div> <script type="text/javascript"> Vue.component('global-tag', { props:['sup_data1', 'supdata2'], template: '<div>{{ sup_data1 }} {{ supdata2 }}</div>' }) new Vue({ el: '#app', data: { sup_data1: '數據1', sup_data2: '數據2' } }) </script>
<div id="app"> <global-tag @send_action='receiveAction'></global-tag> </div> <script type="text/javascript"> Vue.component('global-tag', { data () { return { sub_data1: "數據1", sub_data2: '數據2' } }, template: '<div @click="clickAction">發生</div>', methods: { clickAction () { this.$emit('send_action', this.sub_data1, this.sub_data2) } } }) new Vue({ el: '#app', methods: { receiveAction (v1, v2) { console.log(v1, v2) } } }) </script>
<div id="app"> <div> <input type="text" v-model="val"> <button type="button" @click="submitMsg">提交</button> </div> <ul> <!-- <li v-for="(v, i) in list" :key="i" @click="removeMsg(i)">{{ v }}</li> --> <todo-list v-for="(v, i) in list" :key="i" :v="v" :i="i" @delect_action="delect_action"></todo-list> </ul> </div> <script type="text/javascript"> Vue.component("todo-list", { template: "<li @click='delect_action'><span>第{{ i + 1 }}條: </span><span>{{ v }}</span></li>", props: ['v', 'i'], methods: { delect_action () { this.$emit("delect_action", this.i) } } }) new Vue({ el: "#app", data: { val: "", list: [] }, methods: { submitMsg () { // 往list中添加input框中的value if (this.val) { this.list.push(this.val); this.val = "" } }, delect_action(index) { this.list.splice(index, 1) } } }) </script>
官網下載安裝包,傻瓜式安裝:https://nodejs.org/zh-cn/
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install -g @vue/cli
npm cache clean --force
vue creat 項目名 // 要提早進入目標目錄(項目應該建立在哪一個目錄下) // 選擇自定義方式建立項目,選取Router, Vuex插件
npm run serve / ctrl+c // 要提早進入項目根目錄
npm run build // 要在項目根目錄下進行打包操做
dist: 打包的項目目錄(打包後會生成) node_modules: 項目依賴 public: 共用資源 src: 項目目標,書寫代碼的地方 -- assets:資源 -- components:組件 -- views:視圖組件 -- App.vue:根組件 -- main.js: 入口js -- router.js: 路由文件 -- store.js: 狀態庫文件 vue.config.js: 項目配置文件(沒有能夠本身新建)
module.exports={ devServer: { port: 8888 } } // 修改端口,選作
new Vue({ el: "#app", router: router, store: store, render: function (h) { return h(App) } })
<template> <!-- 模板區域 --> </template> <script> // 邏輯代碼區域 // 該語法和script綁定出現 export default { } </script> <style scoped> /* 樣式區域 */ /* scoped表示這裏的樣式只適用於組件內部, scoped與style綁定出現 */ </style>
{ 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') }] }
<!-- 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 />
a.router-link-exact-active { color: #42b983; }
// router的邏輯轉跳 this.$router.push('/one-view') // router採用history方式訪問上一級 this.$router.go(-1)
// 在任何一個組件中,都可以經過this.$store.state.msg訪問msg的數據 // state永遠只能擁有一種狀態值 state: { msg: "狀態管理器" }, // 讓state擁有多個狀態值 mutations: { // 在一個一個組件中,都可以經過this.$store.commit('setMsg', new_msg)來修改state中的msg setMsg(state, new_msg) { state.msg = new_msg } }, // 讓mutations擁有多個狀態值 actions: { }
// 安裝cookie的命令 // npm install vue-cookie --save // 爲項目配置全局vue-cookie import VueCookie from 'vue-cookie' // 將插件設置給Vue原型,做爲全局的屬性,在任何地方均可以經過this.$cookie進行訪問 Vue.prototype.$cookie = VueCookie
// 持久化存儲val的值到cookie中 this.$cookie.set('val', this.val) // 獲取cookie中val字段值 this.$cookie.get('val')
// 安裝 axios(ajax)的命令 // npm install axios--save // 爲項目配置全局axios import Axios from 'axios' Vue.prototype.$ajax = Axios
let _this = this this.$ajax({ method: 'post', url: 'http://127.0.0.1:5000/loginAction', params: { usr: this.usr, ps: this.ps } }).then(function(res) { // this表明的是回調then這個方法的調用者(axios插件),也就是發生了this的重指向 // 要更新頁面的title變量,title屬於vue實例 // res爲回調的對象,該對象的data屬性就是後臺返回的數據 _this.title = res.data }).catch(function(err) { window.console.log(err) })
# 用pycharm啓動該文件模擬後臺 from flask import Flask, request, render_template from flask_cors import CORS app = Flask(__name__) CORS(app, supports_credentials=True) @app.route('/') def index(): return "<h1>主頁</h1>" @app.route('/loginAction', methods=['GET', 'POST']) def test_action(): # print(request.args) # print(request.form) # print(request.values) usr = request.args['usr'] ps = request.args['ps'] if usr != 'abc' or ps != '123': return 'login failed' return 'login success' if __name__ == '__main__': app.run()