1. 程式人生 > >Vue 初級筆記

Vue 初級筆記

一,漸進式框架     

 1.vue 按需引入

     mvvm     module  view  view-module  資料驅動

 2. vue   模組化  

    什麼是模組化開發
    單頁面應用 spa   路由

 3.模板輸出

    {{}} 可以進行簡單的計算或者換算處理 

 4.建立例項

html:

<div id="box">
			{{a}}
		</div>

js:

<script>
	//第一步
	var lee = new Vue({
		el:'#box',
		data:{
			a:12
		}
	})
		
</script>

結果: 

 

二,兩種開發

 1.簡單的幾個頁面

    使用srcript引用

<script src="vue.js"></script>

  2. 商城

     vue-cli  框架式

三,指令 

  用之前需要先宣告 例項

屬性 作用 實際操作
v-text text輸出

<div v-text="<p style="color:red;">hello</p>"></div>

輸出 <p style="color:red;">hello</p>

v-html html輸出

<div v-text="<p style="color:red;">hello</p>

"></div>

輸出 hello

v-show 顯示/隱藏

v-show = true/false 布林值

 

v-show 都會載入  沒有快取  消耗相對低 
     適合頻繁的切換

v-if 判斷 v-if 只會載入真的部分 有快取 消耗高
      適合偶爾的顯示隱藏切換
v-else 判斷 v-else只會載入真的部分 有快取 消耗高
      適合偶爾的顯示隱藏切換
v-else-if 判斷 v-else-if 只會載入真的部分 有快取 消耗高
      適合偶爾的顯示隱藏切換
v-for 迴圈

 陣列 

<p v-for="(i,$index) in arr"></p>

  json資料

 <p v-for="(i,$key,$index) in arr"></p>

v-model 雙向繫結 多用於下拉框 value>text
v-bind 屬性繫結 <div :style="{'color':‘red’}"></div>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

四,例項方法

data、methods、computed三者名字不可以重複

new Vue({
   el:'' >繫結的作用域
   data: 放資料的
   methods:事件函式
   computed:計算屬性
  })

五,生命週期鉤子

beforeCreate (){} 建立前
created(){} 建立後
beforeMount(){} 渲染前
mounted(){} 渲染後
beforeUpdate(){} 資料更新前
updated(){} 資料更新後
beforeDestroy(){} 銷燬前
destroyed (){} 銷燬後

六,計算屬性和偵聽器

1.偵聽屬性 :偵聽某一項資料的變化,this是vue例項,可以監控到計算屬性的變化
2.生命週期:偵聽所有的資料變化,this是vue例項
3.計算屬性:沒有呼叫不會觸發,this是vue例項

4.watch  
      可以和data重名
      可以和methods重名
      可以和computed重名

5.陣列,通過下標去修改資料,是不會被索引檢測的,所以檢視不會更新

    當你利用索引直接設定一個項時,例如:vm.items[indexOfItem] = newValue
    當你修改陣列的長度時,例如:vm.items.length = newLength

    解決方法
         1.this.arr.splice(1,1,23)
          2.this.$set(this.arr,1,23)

七,ajiax

1.安裝

      npm install vue-resourc

      使用命令符視窗進行安裝,快捷鍵:window鍵+R;輸入cmd確定

     

  2.安裝完後找到 node_modules/vue-resource/dist/vue-resource.js

  開啟node_modules找到vue-resource資料夾開啟再找到dist開啟

   找到vue-resource.js或vue-resource.min.js

   vue-resource.min.js是壓縮過後的

3.引用

<script src=" node_modules/vue-resource/dist/vue-resource.js"></script>

 4.使用例項

<script>
        //post獲取
		var vm = new Vue({
		
			el: "#box",
			data:{},
			methods:{
				ajaxs(){
					this.$http.$.post('', {data}, {emulateJSON:true}).then((data) {
						//成功
					},(data)=>{
						//失敗
					});
				}
			}
		})
        //get獲取
		var vm = new Vue({
		
			el: "#box",
			data:{},
			methods:{
				ajaxs(){
					this.$http.get('',{params:{data}}).then((data)=>{
						//成功
					},(data)=>{
						// 失敗
					})
				}
			}
		
		})
        jsonp跨越
		var vm = new Vue({
		
			el: "#demo",
			data:{

			},
			methods:{
				ajaxs(){
					this.$http.$.jsonp('', {params:{},jsonp:'cb'}).then({
						// 成功
					},(data)=>{

					});
				}
			}
		
		})
	</script>

八,自定義過濾

全域性      Vue.filter( id, [definition] )

引數

  • {string} id
  • {Function} [definition]

用法

1.註冊或獲取全域性過濾器。

// 註冊
Vue.filter('my-filter', function (value) {
  // 返回處理後的值
})

// getter,返回已註冊的過濾器
var myFilter = Vue.filter('my-filter')

2.你可以在一個元件的選項中定義本地的過濾器:

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

 過濾器函式總接收表示式的值 (之前的操作鏈的結果) 作為第一個引數。在上述例子中,capitalize 過濾器函式將會收到 message 的值作為第一個引數。

3.過濾器可以串聯:

{{ message | filterA | filterB }}

 在這個例子中,filterA 被定義為接收單個引數的過濾器函式,表示式 message 的值將作為引數傳入到函式中。然後繼續呼叫同樣被定義為接收單個引數的過濾器函式 filterB,將 filterA 的結果傳遞到 filterB 中。

九,自定義指令

Vue.directive( id, [definition] )

引數

  • {string} id
  • {Function | Object} [definition]

用法

註冊或獲取全域性指令。

// 註冊
Vue.directive('my-directive', {
  bind: function () {},
  inserted: function () {},
  update: function () {},
  componentUpdated: function () {},
  unbind: function () {}
})

// 註冊 (指令函式)
Vue.directive('my-directive', function () {
  // 這裡將會被 `bind` 和 `update` 呼叫
})

// getter,返回已註冊的指令
var myDirective = Vue.directive('my-directive')

 當頁面載入時,該元素將獲得焦點 (注意:autofocus 在移動版 Safari 上不工作)。事實上,只要你在開啟這個頁面後還沒點選過任何內容,這個輸入框就應當還是處於聚焦狀態。現在讓我們用指令來實現這個功能:

// 註冊一個全域性自定義指令 `v-focus`
Vue.directive('focus', {
  // 當被繫結的元素插入到 DOM 中時……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

如果想註冊區域性指令,元件中也接受一個 directives 的選項:

directives: {
  focus: {
    // 指令的定義
    inserted: function (el) {
      el.focus()
    }
  }
}

然後你可以在模板中任何元素上使用新的 v-focus 屬性,如下:

<input v-focus>

鉤子函式

一個指令定義物件可以提供如下幾個鉤子函式 (均為可選):

  • bind:只調用一次,指令第一次繫結到元素時呼叫。在這裡可以進行一次性的初始化設定。

  • inserted:被繫結元素插入父節點時呼叫 (僅保證父節點存在,但不一定已被插入文件中)。

  • update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前後的值來忽略不必要的模板更新 (詳細的鉤子函式引數見下)。

  • componentUpdated:指令所在元件的 VNode 及其子 VNode 全部更新後呼叫。

  • unbind:只調用一次,指令與元素解綁時呼叫。

接下來我們來看一下鉤子函式的引數 (即 elbindingvnode 和 oldVnode)。

鉤子函式引數

指令鉤子函式會被傳入以下引數:

  • el:指令所繫結的元素,可以用來直接操作 DOM 。
  • binding:一個物件,包含以下屬性:
    • name:指令名,不包括 v- 字首。
    • value:指令的繫結值,例如:v-my-directive="1 + 1" 中,繫結值為 2
    • oldValue:指令繫結的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
    • expression:字串形式的指令表示式。例如 v-my-directive="1 + 1"中,表示式為 "1 + 1"
    • arg:傳給指令的引數,可選。例如 v-my-directive:foo 中,引數為 "foo"
    • modifiers:一個包含修飾符的物件。例如:v-my-directive.foo.bar 中,修飾符物件為 { foo: true, bar: true }

 

十,插槽

Vue 實現了一套內容分發的 API,這套 API 基於當前的 Web Components 規範草案,將 <slot> 元素作為承載分發內容的出口。

它允許你像這樣合成元件:

<navigation-link url="/profile">
  Your Profile
</navigation-link>

然後你在 <navigation-link> 的模板中可能會寫為:

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>

 

當元件渲染的時候,這個 <slot> 元素將會被替換為“Your Profile”。插槽內可以包含任何模板程式碼,包括 HTML:

<navigation-link url="/profile">
  <!-- 新增一個 Font Awesome 圖示 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>

 

如果 <navigation-link> 沒有包含一個 <slot> 元素,則任何傳入它的內容都會被拋棄。

具名插槽

有些時候我們需要多個插槽。

對於這樣的情況,<slot> 元素有一個特殊的特性:name。這個特性可以用來定義額外的插槽:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

在向具名插槽提供內容的時候,我們可以在一個父元件的 <template> 元素上使用 slot 特性:

<base-layout>
  <template slot="header">
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template slot="footer">
    <p>Here's some contact info</p>
  </template>
</base-layout>

 

插槽的預設內容

你可以在元件模板裡的 <slot> 標籤內部指定預設的內容來做到這一點。

<button type="submit">
  <slot>Submit</slot>
</button>

如果父元件為這個插槽提供了內容,則預設的內容會被替換掉。

編譯作用域

當你想在插槽內使用資料時,例如:

navigation-link url="/profile">
  Logged in as {{ user.name }}
</navigation-link>

該插槽可以訪問跟這個模板的其它地方相同的例項屬性 (也就是說“作用域”是相同的)。但這個插槽不能訪問 <navigation-link> 的作用域。例如嘗試訪問 url 是不會工作的。牢記一條準則。

十一,元件

基本例項

// 定義一個名為 button-counter 的新元件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

元件是可複用的 Vue 例項,且帶有一個名字:在這個例子中是 <button-counter>。我們可以在一個通過 new Vue 建立的 Vue 根例項中,把這個元件作為自定義元素來使用:

<div id="components-demo">
  <button-counter></button-counter>
</div>




new Vue({ el: '#components-demo' })

因為元件是可複用的 Vue 例項,所以它們與 new Vue 接收相同的選項,例如 datacomputedwatchmethods 以及生命週期鉤子等。僅有的例外是像 el這樣根例項特有的選項。

元件的複用·

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

data必須是個函式

當我們定義這個 <button-counter> 元件時,你可能會發現它的 data 並不是像這樣直接提供一個物件:

data: {
  count: 0
}

取而代之的是,一個元件的 data 選項必須是一個函式,因此每個例項可以維護一份被返回物件的獨立的拷貝:

data: function () {
  return {
    count: 0
  }
}

如果 Vue 沒有這條規則,點選一個按鈕就可能會影響到其它所有例項

為了能在模板中使用,這些元件必須先註冊以便 Vue 能夠識別。這裡有兩種元件的註冊型別:全域性註冊區域性註冊。至此,我們的元件都只是通過 Vue.component 全域性註冊的:

Vue.component('my-component-name', {
  // ... options ...
})

全域性註冊的元件可以用在其被註冊之後的任何 (通過 new Vue) 新建立的 Vue 根例項,也包括其元件樹中的所有子元件的模板中。

通過 Prop 向子元件傳遞資料

Prop 是你可以在元件上註冊的一些自定義特性。當一個值傳遞給一個 prop 特性的時候,它就變成了那個元件例項的一個屬性。為了給博文元件傳遞一個標題,我們可以用一個 props 選項將其包含在該元件可接受的 prop 列表中:

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

一個元件預設可以擁有任意數量的 prop,任何值都可以傳遞給任何 prop。在上述模板中,你會發現我們能夠在元件例項中訪問這個值,就像訪問 data 中的值一樣

<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>

十二,子級向父級傳值

1建立一個子元件


			
			<lee :num='a'>我是父級{{a}}</lee>

		<template id="lee">
			<div>
				<button>+</button>
				<slot></slot>
				<button>-</button>
			</div>
		</template>


	<script>
		Vue.component('lee',{
			template:'#lee',
			props:['num']
		})
		
		new Vue({
			el:'#box',
			data:{
				a:12
			}
		})
	</script>

在響應該點選事件的函式中使用$emit來觸發一個自定義事件,並傳遞一個引數


		<div id="box">
			
			<lee :num='a'>	
				{{a}}
			</lee>
		</div>
		<template id="lee">
			<div>
				<button @click="jia">+</button>
				<slot></slot>
				<button @click="jian">-</button>
			</div>
		</template>


	<script>
		Vue.component('lee',{
			template:'#lee',
			props:['num'],
			data(){
				return{
					a:this.num
				}
			},
			methods:{
				jia(){
					this.a++
					this.$emit('lee',this.a)//建立的自定義事件
				},
				jian(){
					this.a--
					this.$emit('lee',this.a)
				}
			}
		})
		
		new Vue({
			el:'#box',
			data:{
				a:12
			}
		})
	</script>

3.在父元件中的子標籤中監聽該自定義事件並新增一個響應該事件的處理方法


		<div id="box">
		    //用剛才建立的事件繫結這個函式即可
			<lee :num='a' @lee="lee">我是父級{{a}}</lee>
		</div>
		<template id="lee">
			<div>
				<button @click="jia">+</button>
				<slot></slot>
				<button @click="jian">	-</button>
			</div>
		</template>


	<script>
		Vue.component('lee',{
			template:'#lee',
			props:['num'],
			data(){
				return{
					a:this.num
				}
			},
			methods:{
				jia(){
					this.a++
					this.$emit('lee',this.a)
				},
				jian(){
					this.a--
					this.$emit('lee',this.a)
				}
			}
		})
		
		new Vue({
			el:'#box',
			data:{
				a:12
			},
			methods:{
//響應事件的處理方法建一個函式來接受子級穿的資料
				lee(a){
					this.a = a
				}
			}
		})

4.儲存修改的檔案,在瀏覽器中點選按鈕

子元件向父元件傳值成功
總結一下:

  • 子元件中需要以某種方式例如點選事件的方法來觸發一個自定義事件

  • 將需要傳的值作為$emit的第二個引數,該值將作為實參傳給響應自定義事件的方法
  • 在父元件中註冊子元件並在子元件標籤上繫結對自定義事件的監聽
  • 在通訊中,無論是子元件向父元件傳值還是父元件向子元件傳值,他們都有一個共同點就是有中間介質,子向父的介質是自定義事件,父向子的介質是props中的屬性。抓準這兩點對於父子通訊就好理解了

十三,vue bus

有時候兩個元件也需要通訊(非父子關係)。當然Vue2.0提供了Vuex,但在簡單的場景下,可以使用一個空的Vue例項作為中央事件匯流排。

參考:http://blog.csdn.net/u013034014/article/details/54574989?locationNum=2&fps=1

例子:https://segmentfault.com/q/1010000007491994

<div id="app">
    <c1></c1>
    <c2></c2>
</div>

 

 

var Bus = new Vue(); //為了方便將Bus(空vue)定義在一個元件中,在實際的運用中一般會新建一Bus.js
Vue.component('c1',{ //這裡已全域性元件為例,同樣,單檔案元件和區域性元件也同樣適用
template:'<div>{{msg}}</div>',
  data: () => ({
    msg: 'Hello World!'
  }),
  created() {
    Bus.$on('setMsg', content => { 
      this.msg = content;
    });
  }
});
Vue.component('c2',{
  template: '<button @click="sendEvent">Say Hi</button>',
  methods: {
    sendEvent() {
      Bus.$emit('setMsg', 'Hi Vue!');
    }
  }
});
var app= new Vue({
    el:'#app'
})

 

在實際運用中,一般將Bus抽離出來:

Bus.js


const Bus = new Vue()

元件呼叫時先引入

元件1

 

Vue.component:{
    data() {
        return {
            .........
            }
      },
  methods: {
        ....
        Bus.$emit('log', 120)
    },

  }        

元件2

import Bus from './Bus'

4 {
    data() {
        return {
            .........
            }
      },
    mounted () {
       Bus.$on('log', content => { 
          console.log(content)
        });    
    }    
} 

但這種引入方式,經過webpack打包後可能會出現Bus區域性作用域的情況,即引用的是兩個不同的Bus,導致不能正常通訊

 實際運用二(推薦):

當然也可以直接將Bus注入到Vue根物件中,

import Vue from 'vue'
const Bus = new Vue()

var app= new Vue({
    el:'#app',
   data:{
    Bus
    }  

})

十四,安裝 vue-cli

全域性安裝

安裝 vue-cli前先安裝以下外掛

cnpm i webpack webpack-cli webpack-dev-server -g

 好了在安裝以下外掛

cnpm i vue-cli -g

vue-cli有三個版本,分別為

  • simple 簡單的
  • webpack webpack版本 複雜的’
  • webpack-simple 中和 

教程

vue init webpack webpack
         //安裝的版本  後邊的是名字,名字不定 

你會看到以下情況 一直按enter即可 

在這裡可能需要一些時間,需要等待 

 接下來再看已經安裝好了 

cd webpack 通過這段程式碼進入你建立的資料夾

npm run dev 通過這段程式碼執行這個例項 ,在頁面輸入http://localhost:8080開啟頁面

當你把頁面寫完! 通過npm run build 進行打包

會打包在一個叫dist的資料夾中

當然你再開啟打包好後index.html的時候會報錯應該是以下所示

解決方法 以下圖所示在 /dist/build.js前面加一個點

 

在子元件中通過this.$root.Bus.$on(),this.$root.Bus.$emit()來呼叫