vuejs 單文件組件.vue 文件

vuejs 自定義了一種.vue文件,能夠把html, css, js 寫到一個文件中,從而實現了對一個組件的封裝, 一個.vue 文件就是一個單獨的組件。因爲.vue文件是自定義的,瀏覽器不認識,因此須要對該文件進行解析。 在webpack構建中,須要安裝vue-loader 對.vue文件進行解析。在 sumlime 編輯器中,咱們 書寫.vue 文件,能夠安裝vue syntax highlight 插件,增長對文件的支持。css

  用vue-cli 新建一個vue項目,看一下.vue文件長什麼樣? 在新建項目的過程當中,命令行中會詢問你幾個問題,當詢問是否安裝vue-router 時,這裏先選擇否。項目完成後,咱們看到src  目錄下有一個componet 目錄,裏面有一個 Hello.vue 文件,內容以下,這裏對template 裏面的內容作了一些刪減html

複製代碼

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<style scoped>
h1, h2 {
  font-weight: normal;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

複製代碼

  能夠看到,在 .vue 文件中, template 中都是html 代碼,它定義了在頁面中顯示的內容,因爲裏面還有變量,也能夠說定義了一個模版;script中都是js 代碼,它定義這個組件中所須要的數據和及其操做,style 裏面是css 樣式,定義這個組件的樣式,scoped 代表這裏寫的css 樣式只適用於該組件,能夠限定樣式的做用域。vue

  script 標籤中 export defalut 後面的對象的理解。webpack

  在不使用.vue 單文件時,咱們是經過 Vue 構造函數建立一個 Vue 根實例來啓動vuejs 項目,Vue 構造函數接受一個對象,這個對象有一些配置屬性 el, data, component, template 等,從而對整個應用提供支持。web

複製代碼

new Vue({
  el: '#app',
  data: {
        msg: "hello Vue"     
  }  
})

複製代碼

  在.vue文件中,export default 後面的對象 就至關於 new Vue() 構造函數中的接受的對象,它們都是定義組件所須要的數據(data), 以及操做數 據的方法等, 更爲全面的一個 export default 對象,有methods, data, computed, 這時能夠看到, 這個對象和new Vue() 構造函數中接受的對象是如出一轍的。但要注意data 的書寫方式不一樣。在 .vue 組件, data 必須是一個函數,它return(返回一個對象),這個返回的對象的數據,供組件實現。vue-router

    把項目中自帶的hello.vue 內容清空,咱們本身寫一個組件來體驗一下這種相同。vuex

複製代碼

<template>
  <div class="hello">
    <input type="txet" placeholder="請輸入文字" v-model="msg" @keypress.enter="enter">
    <p>{{upper}}</p>
  </div>
</template>

<script>
export default {
  data () {
    return {
      msg: 'hello'
    }
  },
  methods:{
    enter () {
      alert(this.msg);
    }
  },
  computed: {
    upper () {
      return this.msg.toUpperCase();
    }
  }
}
</script>

<style scoped>
  input {
    width: 200px;
    height: 20px;
  }
  p {
    color: red;
  }
</style>

複製代碼

  頁面中有一個input輸入框,當進行輸入的時候,輸入框下面的內容會進行同步顯示,只不過它是大寫,當輸入完成後,按enter鍵就會彈出咱們輸入的內容。獲取用戶輸入的內容,咱們用的是v-model 指令,這個指令將用戶輸入的內容綁定到變量上,而且它響應式的,咱們的變量值會隨着用戶輸入的變化而變化,也就是說咱們始終獲取的都是用戶最新的輸入。下面大寫的顯示,用的是computed屬性,彈窗則是給綁定了一個keypress事件,經過描述,你會發現,它簡直就是一個vue實例,實際上它就是個vue實例。每個vue組件都是一個vue實例,更容易明白 export default 後面的對象了。vue-cli

  父子組件之間的通訊數組

  每個.vue 文件就是一個 組件,組件和組件相互組合,就成了一個應用,這就涉及到的組件和組件之間的通訊,最經常使用的就是父子之間的通訊。在vue 中, 在一個組件中經過 import 引入另外一個組件,這個組件就是父組件,被引入的組件就是子組件。瀏覽器

  在咱們這個vue-cli 項目中,src 文件夾下有一個App.vue 文件,它的script標籤中,import Hello from './components/Hello',那麼 App.vue 就是父組件,components 文件夾下的Hello.vue 就是子組件。父組件經過props 向子組件傳遞數據,子組件經過自定義事件向父組件傳遞數據。

  父組件向子組件傳值, 它主要是經過元素的屬性進行的. 在App.vue 的template中,有一個 <hello></hello>, 這就是咱們引入的子組件.  給其添加屬性如 mes-father="message from father";  父組件將數據傳遞進去,子組件須要接收才能使用. 怎樣接收呢?

  在Hello.vue 中, export default 後面的對象中,添加一個字段props, 它是一個數組, 專門用來接收父組件傳遞過來的數據. props: ["mesFather"], 這裏定義了mesFather 字符串, 和父組件中定義的元素的屬性一一對應. 可是咱們在父組件,就是在 <hello /> 元素中定義的屬性是mes-father, 沒有一一對應啊?  這主要是由於,在html 元素中大小寫是不敏感的。 若是咱們寫成<hello mesFather="message from father"></hello>, 裏面的mesFather  就會轉化成mesfather, 至關於咱們向子組件傳遞了一個mesfather數據, 若是在js 文件中,咱們定義 props: ["mesFather"],咱們是接受不到數據的,由於js 是區分大小寫的, 只能寫成props: ["mesfather"].  可是在js 文件中,像這種兩個單詞拼成的數據,咱們習慣用駝峯命名法,因此vue 作了一個轉化,若是在組件中屬性是 - 表示,它 自動會轉化成駝峯式。  傳進來的數據是mes-father, 轉化成mesFather, 咱們在js 裏面寫mesFather, 一一對應,子組件能夠接受到組件。 props 屬性是和data, methods 屬性並列的,屬同一級別。 props 屬性裏面定義的變量,在 子組件中的template 中能夠直接使用。

  App.vue 的template 更改以下:

複製代碼

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <hello mes-father="message from father"></hello>
  </div>
</template>

複製代碼

  Hello.vue組件,這裏仍是把項目中自帶的Hello.vue 清空,本身寫,變成以下內容

複製代碼

<template>
  <div class="hello">
    <p>{{mesFather}}</p>
  </div>
</template>

<script>
export default {
  props:['mesFather']
}
</script>

複製代碼

  這時,在頁面中看到 message from father 字樣,父元素向子元素傳遞數據成功。

  子組件向父組件傳遞數據,須要用到自定義事件。 例如,咱們在Hello.vue ,寫入一個input, 接收用戶輸入,咱們想把用戶輸入的數據傳給父組件。這時,input 須要先綁定一個keypress 事件,獲取用戶的輸入,同時還要發射自定義事件,如valueUp, 父組件只要監聽這個自定義事件,就能夠知道子組件要向他傳遞數據了。子組件在發射自定義事件時,還能夠攜帶參數,父組件在監聽該事件時,還能夠接受參數,參數,就是要傳遞的數據。

  在 Hello.vue template中,添加一個input輸入框,給它一個v-model 獲取用戶的輸入,再添加keypress的事件,用於發射事件,傳輸數據。script 中添加data,定義變量來獲取用戶的輸入,添加methods 來處理keypress事件的處理函數enter, 整個Hello.vue 文件以下

複製代碼

<template>
  <div class="hello">
    <!-- 添加一個input輸入框 添加keypress事件-->
    <input type="text" v-model="inputValue" @keypress.enter="enter">
    <p>{{mesFather}}</p>
  </div>
</template>

<script>
export default {
  props:['mesFather'],

  // 添加data, 用戶輸入綁定到inputValue變量,從而獲取用戶輸入
  data: function () {
    return {
      inputValue: ''  
    }
  },
  methods: {
    enter () {
      this.$emit("valueUp", this.inputValue) 
      //子組件發射自定義事件valueUp, 並攜帶要傳遞給父組件的值,
      // 若是要傳遞給父組件不少值,這些值要做爲參數依次列出 如 this.$emit('valueUp', this.inputValue, this.mesFather); 
    }
  }
}
</script>

複製代碼

  在App.vue 中, template中hello 組件綁定一個自定義事件,@valueUp =「receive」, 用於監聽子組件發射的事件,再寫一個 p 元素,用於展現子組件傳遞過來的數據,<p>子組件傳遞過來的數據 {{ childMes }}</p>

相應地,在scrpit中,data 中,定義一個變量childMes, 並在 methods 中,定義一個事件處理函數reciever。整個App.vue修改以下:

複製代碼

<template>
  <div id="app">
    <img src="./assets/logo.png">

    <!-- 添加自定義事件valueUp -->
    <hello mes-father="message from father" @valueUp="recieve"></hello>

    <!-- p元素,用於展現子組件傳遞過來的數據 -->
    <p>子組件傳遞過來的數據 {{childMes}}</p>
  </div>
</template>

<script>
import Hello from './components/Hello'

export default {
  name: 'app',
  components: {
    Hello
  },
  // 添加data
  data: function () {
    return {
      childMes:''
    }
  },

  // 添加methods,自定義事件valueUp的事件處理函數recieve
  methods: {
    recieve: function(mes) { // recieve 事件須要設置參數,這些參數就是子組件傳遞過來的數據,所以,參數的個數,也要和子元素傳遞過來的一致。
      this.childMes = mes;
    }
  }
}
</script>

複製代碼

  這時在input中輸入內容,而後按enter鍵,就以看到子組件傳遞過來的數據,子組件向父組件傳遞數據成功。 

  當在input輸入框中輸入數據,並按enter鍵時,它會觸發keypress.enter事件,從而調用事件處理函數enter, 在enter 中, 咱們發射了一個事件valueUp, 並攜帶了一個參數,因爲在<hello @valueUp=」recieve」></hello> 組件中, 咱們綁定valueUp 事件,因此父組件在時刻監聽valueUp 事件, 當子組件發射value 事件時,父組件馬上捕獲到,並當即調用它的回調函數receive, 在receive 中,咱們獲取到子組件傳遞過來的數據,並賦值了data 中的變量childMes, 因爲data 數據發生變化,從而觸發dom更新,頁面中就顯示子組件傳遞過來的內容。

  其實在子組件中, props 最好的寫法是props 驗證,咱們在子組件Hello.vue中寫 props:['mesFather'], 只是表達出,它接受一個參數mesFather, 若是寫成props 驗證,不只能表達出它須要什麼參數,還能表達參數類型,而且若有錯誤,vue 會作出警告。如今把props 改爲props 驗證的寫法, Hello.vue 中的js中的props修改以下:

複製代碼

props: {
      'mesFather': {
          type: String,
          default: 'from father',
          required:true
      }
  }

複製代碼

  若是是組件與組件之間的通訊很是複雜,不光是父子組件,還有兄弟組件,那就須要用到狀態管理,vuex

相關文章
相關標籤/搜索