Vue快速學習_第二節
阿新 • • 發佈:2019-07-14
-
表單輸入繫結(v-model)
v-model
指令在表單 <input>
、<textarea>
及 <select>
元素上建立雙向資料繫結(注意只在表單這幾個可以,實際上就是負責監聽使用者的輸入事件以更新資料)
注意:v-model
會忽略所有表單元素的 value
、checked
、selected
特性的初始值而總是將 Vue 例項的資料作為資料來源.
v-model
在內部為不同的輸入元素使用不同的屬性並丟擲不同的事件:
-
text 和 textarea 元素使用
value
屬性和input
事件; -
checkbox 和 radio 使用
checked
change
事件; -
select 欄位將
value
作為 prop 並將change
作為事件。
上面的解釋來源於官網,感覺不錯就拿過來了,好了,接著來實際操作下看看吧
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box"> <!--下面是v-model使用例項,雙向資料繫結--> <!--1.input文字使用--> <input type="text" v-model="msg" placeholder="請輸入值"> <p>{{ msg }}</p> <br> <!--2.textarea富文字使用,這樣一旦一個改變,介面上所有引用的地方都會改變, 在文字區域插值 (<textarea>{{text}}</textarea>) 並不會生效,應用 v-model 來代替。--> <textarea v-model="msg" placeholder="富文字輸入"></textarea> <br> <!--3.單個複選框使用,checked選中就是true,沒選中就是false--> <input type="checkbox" id="checked" v-model="checked"> <!--label的作用就是for關聯對應的id標籤,點選label文字就相當於點選了input--> <label for="checked">{{ checked }}</label> <br> <!--4.多個複選框使用--> <div> <input type="checkbox" id="c1" value="apple" v-model="checked_list"> <label for="c1">apple</label> <input type="checkbox" id="c2" value="banana" v-model="checked_list"> <label for="c2">banana</label> <input type="checkbox" id="c3" value="peach" v-model="checked_list"> <label for="c3">peach</label> <br> <!--將選擇的value值存入checked_list中--> <span>多選的是: {{ checked_list }}</span> </div> <br> <!--5.單選使用,同樣是儲存value值--> <div> <input type="radio" id="r1" value="apple" v-model="radio_one"> <label for="r1">apple</label> <input type="radio" id="r2" value="banana" v-model="radio_one"> <label for="r2">banana</label> <br> <span>單選的是: {{ radio_one }}</span> </div> <br> <!--6.選擇框的使用--> <div> <!--v-model 表示式的初始值未能匹配任何選項,<select> 元素將被渲染為“未選中”狀態, 所以建議用下面的方法,第一個為請選擇但是設定disabled--> <select v-model="selected"> <!--在v-model下select下的option要設定value=""才會預設第一個顯示--> <option disabled value="">請選擇</option> <option>A</option> <!--有value就會將value值賦值給selected,沒有則用文字的B--> <option value="2">B</option> <option value="3">C</option> </select> <span>你的選擇是: {{ selected }}</span> </div> <br> <!--7.多選繫結到一個數組--> <div> <!--data裡面selecteds為一個空陣列--> <select multiple v-model="selecteds"> <option disabled value="">請選擇</option> <option>A</option> <!--有value就會將value值賦值給selected,沒有則用文字的B--> <option value="2">B</option> <option value="3">C</option> </select> <span>你的選擇是: {{ selecteds }}</span> </div> <!--依舊是多選,但是是用v-for動態渲染--> <div> <!--select_for賦值了A,因此會預設選中value為A的選項--> <select v-model="select_for"> <option v-for="(item, index) in option_list" :key="index" :value="item.value">{{ item.text }}</option> </select> </div> <br> <!--8.值的繫結,對於單選按鈕,複選框及選擇框的選項,v-model 繫結的值通常是靜態字串 (對於複選框也可以是布林值), 但是有時我們可能想把值繫結到 Vue 例項的一個動態屬性上,這時可以用 v-bind 實現,並且這個屬性的值可以不是字串--> <input type="radio" v-model="toggle" v-bind:value="bind_value"> <!--value的值變成了動態屬性bind_value--> <span>{{toggle}}</span> <br> <!--9.修飾符 .lazy,在“change”時而非“input”時更新 ,也就是輸入中不改變msg,回車或確定時改變--> <input v-model.lazy="msg" > <br> <!--10.修飾符 .number,自動將使用者的輸入值轉為數值型別--> <input v-model.number="age" type="number"> <br> <!--11.修飾符 .trim,自動過濾使用者輸入的首尾空白字元--> <input v-model.trim="msg"> </div> </body> <script src="vue.js"></script> <script> // 多選列表資料 var options = [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ]; new Vue({ el: '#box', data(){ return { msg: '', checked: false, checked_list: [], radio_one: '', selected: '', selecteds: [], option_list: [], // 初始化給了A,這樣select就會選中value為A的選項 select_for: 'A', toggle: '', bind_value: '值被綁定了', age: '', } }, created(){ this.option_list = options } }) </script> </html>
-
元件化開發
-
全域性元件(通用元件可以考慮變成全域性元件)
// 宣告全域性元件, 第一個引數是元件的名字(Vbtn), 第二個引數是options,宣告完之後就可以在其他元件呼叫,不需要掛載 Vue.component('Vbtn', { data(){ return { msg: '按鈕' } }, template:`<button>{{ msg }}</button>` });
-
區域性元件
遵循三步驟: 聲子(建立元件), 掛子(掛載到父元件), 用子(父元件使用子元件),下面程式碼使用包含全域性元件的呼叫
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box"> <!--直接使用App元件--> <App/> </div> </body> <script src="vue.js"></script> <script> /* 注意:如果僅僅是例項化Vue例項化物件中 既有el又有template,如果template中定義模板的內容, 那麼template模板的優先順序大於el,就會使用template的內容,沒有的話就會使用el的內容 */ // 宣告全域性元件, 第一個引數是元件的名字(Vbtn), 第二個引數是options,宣告完之後就可以在其他元件呼叫,不需要掛載 Vue.component('Vbtn', { data(){ return { msg: '按鈕' } }, // 通過slot插槽分發內容(元件傳遞內容),就相當於別的元件呼叫傳值會替換slot標籤的位置 template:`<button> <slot></slot> </button> ` }); // 定義App下的header區域,第一步聲子,,然後App父元件就可以呼叫了 let Vheader = { data(){ return { header_login: '登入', header_reg: '註冊', } }, // 定義herader區域的模板內容,使用全域性元件Vbtn,介面顯示登入和註冊按鈕 template:` <div> <Vbtn>{{ header_login }}</Vbtn> <Vbtn>{{ header_reg }}</Vbtn> </div> ` }; // 1.聲子, Vue中 元件的名字首字母必須大寫(與標籤區分),元件中的data必須是一個函式且要有返回值,這裡定義一個App let App = { data(){ return { name: 'liu', } }, // 定義App元件內容,使用App元件的內容,注意template裡面一定是有一個根標籤包裹全部標籤,使用Vheader template:` <div class="app1"> <h2>{{ name }}</h2> <Vheader/> <Vbtn>提交</Vbtn> </div> `, components: { // 掛載header元件 Vheader } }; new Vue({ el:'#box', data(){ return { } }, // 元件掛載 components:{ // 2.掛子,如果key和value(App:App)一樣可以只寫一個(App) // App:App App } }) </script> </html>
-
元件的巢狀(單向資料流)
-
父子元件傳值
-
父往子傳值(props)
-
在子元件中 使用props宣告(注意要宣告一個數組),可以直接在子元件中任意使用
// 子元件Vheader let Vheader = { data(){ return { } }, // 在子元件中 使用props宣告(注意要宣告一個數組),可以直接在子元件中任意使用 props:['t_name', 'title', 'post2'], // 定義herader區域的模板內容,下面是使用父元件傳過來的值 template:` <div> <span>{{ t_name }}</span> <span>{{ title }}</span> <span>{{ post2.title }}</span> </div> ` };
-
父元件要定義自定義屬性
// 父元件App let App = { data(){ // 父元件的資料 return { name: 'liu', post1: { id: 1, title: 'My Journey with Vue' }, post2: { id: 2, title: 'test post' } } }, // 傳入一個物件的所有屬性可以v-bind="post1"也可以:post2="post2",第一種相當於 v-bind:id="post1.id"和v-bind:title="post1.title",所以在子元件中直接接收id和title並使用. template:` <Vheader :t_name="name" v-bind="post1" :post2="post2"></Vheader> `, components: { // 掛載header元件 Vheader } };
-
-
子往父傳值(通過事件向父級元件傳值,示例也包含了父向子傳值)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box"> <!--直接使用App元件--> <App/> </div> </body> <script src="vue.js"></script> <script> // 全域性元件Vbtn Vue.component('Vbtn', { data(){ return { } }, props:['id'], template:`<button @click="clickHandler"> {{ id }} </button> `, methods:{ // 1.點選觸發clickHandler方法,接著$emit就去觸發父元件的事件方法 clickHandler(){ // $emit是vue方法,第一個引數寫父元件宣告自定義的事件,第二個引數傳值 this.$emit('headerClick', this.id) } } }); // Vheader元件 let Vheader = { data(){ return { } }, props:['post'], // 2.父元件自定義事件,子元件點選按鈕後通過$emit()觸發父元件的headerClick中的headerHandler方法 template:` <div> <Vbtn :id="post.id" @headerClick="headerHandler"></Vbtn> </div> `, methods: { // 3.觸發方法後,接著又去觸發app父元件的appClick事件 headerHandler(val){ this.$emit('appClick', val) } } }; // App父元件 let App = { data(){ return { name: 'liu', post: { id: 1, title: 'My Journey with Vue' }, } }, // 4.header子元件通過$emit()觸發父元件的appClick中的appHandler方法 template:` <div class="app1"> <Vheader :t_name="name" :post="post" @appClick="appHandler"></Vheader> </div> `, components: { // 掛載header元件 Vheader }, methods:{ // 5.該方法就是接收子元件的傳值,並加1,重新賦值渲染介面 appHandler(val){ val++; this.post.id = val; } } }; new Vue({ el:'#box', data(){ return { } }, // 元件掛載 components:{ App } }) </script> </html>
-
-
平行元件傳值
注意:A->B傳值,那麼B要宣告事件,通過$on('事件的名稱', function(){}), A則要觸發事件 $emit('B元件中宣告的事件名', '值val'),還有記住,前提條件是這兩個方法必須繫結在同一個例項化物件中(比如let bus = new Vue()),同時繫結到bus上
let bus = new Vue(); // 全域性元件Test, Test向Vheader傳值msg, 因此$emit('Vheader元件中宣告的事件名', '值val') Vue.component('Test', { data(){ return { msg: '我是全域性子元件的資料', } }, template:`<button @click="clickHandler"> 按鈕 </button> `, methods:{ clickHandler(){ // $emit和$on的事件要一樣 bus.$emit('testData', this.msg) } } }); // Vheader元件 let Vheader = { data(){ return { // 定義一個text接收msg text: '' } }, template:` <div> <Test /> {{ text }} </div> `, methods: { }, // 接收$emit()傳過來的值 created(){ // 這裡的是bus呼叫,this指的是bus,所以要指向Vheader就需要用箭頭函式指向父級 bus.$on('testData', (val) => { this.text = val; }) } };