前言
在上大學那陣子,jQuery正流行,于是憑借著“一邊百度一邊敲代碼的本領”,怎能把自己想要的效果顯示出來,但是jQuery背后瘋狂操縱dom的事實,和日后難維護的問題,當時并沒有顧及太多(但是當時我就發現了,想要變換個什么功能,在代碼里面找起來,是真的費勁)。
等開始實習的時候,實習單位使用的是Angular(剛入職的時候使用的AngularJs 后來使用了Angular4 這兩個的關系就像是貓和熊貓的關系,根本不是一回事。)他們把Js代碼軍團組織的更加完整了,分離出來了MVC(Model,View,Controller)。使用起來給我們提供了很多的方便。但是總感覺他們并不是我的菜,怎么也提不起來對他們的興趣。
直到后來我接觸了Vue,簡直就是前端各種框架的一股清流,引入了MVVM(Model,View,View-Model)。全文上下,變量,方法,組件,包裹在實例中,被安排的明明白白。由原來的事件作為驅動力,改為了數據作為驅動力,View的數據變動,通過View-Model修改了Model,同樣的,Model的變化,通過View-Model修改了View的顯示。View-Model像是一個橋梁一樣連接著View和Model。
這是我學Vue的第一個小練習—— todo-list。
正文
學習一門技術,官網永遠是最好的老師。
這里是官網教程入口
這里是講解MVVM結構的入口,廖雪峰老師官方網站
簡單例子引入
我們首先由一個簡單的例子引入,在這里不使用Vue-Cli,只是通過CDN的方式引入。
先創建一個空的html文件,在其中輸入以下代碼:
<html>
<head>
<!--通過CDN引入vue.js源代碼-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<h3>element:root</h3>
<div id="root">
<div>
{{msg}}
</div>
<!-- v-html 可以把data中的數據以html形式顯示出來-->
<div v-html="htmlInput">
</div>
<!-- v-text直接顯示數據, 并不是在意以什么形式顯示出來-->
<div v-text="textInput">
</div>
<!-- v-on: (事件綁定),也可以寫為@click="clickFunction"可以簡寫為"@"符號,-->
<div v-on:click="clickFunction">
{{clickText}}
</div>
</div>
<hr>
<h3>element:app-2</h3>
<div id="app-2">
<!-- v-bind(屬性綁定) 直接可以簡寫為":"-->
<span v-bind:title="message">
鼠標懸停幾秒鐘查看此處動態綁定的提示信息!
</span>
<br>
<!-- v-bind 用于單向綁定,數據驅動頁面的變化,但是頁面變化不會同時對應到后臺上-->
<input :value="content">
<!-- v-model 用于雙向綁定-->
<input v-model="content">
<div>{{content}}</div>
</div>
<hr>
<h3>element:app-3</h3>
<div id="app-3">
first name:<input v-model='firstname'/>
last name:<input v-model='lastname'/>
<br>
full name:<div >{{fullname}}</div>
</div>
<script type="text/javascript">
//創建一個vue實例,這是整個vue的靈魂,這就是傳說中的mvvm中的vm——viewmodel
var root = new Vue({
el:"#root",
data:{
msg: "harry is worderful",
htmlInput: "<b>this is a test text</b>",
textInput: "<b>this is a test text</b>",
clickText: "you can click it"
},
methods:{
clickFunction:function(){
root.clickText = "congretulation";
}
}
});
var app2 = new Vue({
el: '#app-2',
data: {
message: '頁面加載于 ' + new Date().toLocaleString(),
content: "this is a content"
}
});
new Vue({
el: "#app-3",
data: {
firstname: '',
lastname: ''
},
computed: {
fullname: function(){
return this.firstname + ' ' + this.lastname;
}
}
});
</script>
</body>
</html>
這段代碼大家可以直接創建一個.html文件然后粘在里面查看一下效果,我也有寫上注釋。大概的思路是這樣的,首先new 一個Vue實例,然后在實例中配置,首先設置“el”屬性用來綁定dom的id,然后把需要定義的變量放在“data”屬性中,把方法房子“methods”屬性中,需要計算的變量,放在“computed”屬性中。
初識todo-list
下面使用CDN創建一個todo-list簡單的例子。todo-list實現的效果是,在一個文本框中輸入數據,點擊一個按鈕,然后數據會顯示在下方的一個list中。
<html>
<head>
<!--通過CDN引入vue.js源代碼-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<input type="text" v-model='variable'/>
<br>
<button @click='clickEvent'>click</button>
<ul>
<li v-for='(item, index) of list'>{{item}}</li>
</ul>
<hr>
<h4>使用組件形式</h4>
<ul>
<todo-list v-for="(item, index) of list" :key="index" :content="item" :index="index" @delete="handleDelete"></todo-list>
</ul>
</div>
<script type="text/javascript">
//這是全局的組建可以被用于這個項目中的任何地方。
Vue.component('todo-list',{
props: ['content','index'],
template: '<li @click="handleClick">{{content}} {{index}}</li>',
methods:{
handleClick: function(){
this.$emit('delete',this.index);
}
}
});
new Vue({
el: "#root",
data:{
variable: '',
list: []
},
methods:{
clickEvent: function(){
this.list.push(this.variable);
this.variable= '';
},
handleDelete: function(index){
this.list.splice(index,1);
}
}
});
</script>
</body>
</html>
大家可以先放到自己的文件中,查看一下效果。
我們可以很容易的觀察到,這個例子,和剛剛哪個簡單例子的區別。
在這個例子中為了說明組件的概念,將ul中的li單獨抽了出來作為了一個組件。
主要的還是多了以下這段代碼:
//html代碼
<ul>
<todo-list v-for="(item, index) of list" :key="index" :content="item" :index="index" @delete="handleDelete"></todo-list>
</ul>
//js代碼
Vue.component('todo-list',{
props: ['content','index'],
template: '<li @click="handleClick">{{content}} {{index}}</li>',
methods:{
handleClick: function(){
this.$emit('delete',this.index);
}
}
});
剛開始看到這塊的代碼,我整個人也是挺蒙的,下面我們來分析分析。
Vue.component(),這個方法用來創建一個組件,這是創建了一個全局的組件,就是在整個應用中的所有地方都可以使用這個組件,還有一種方法就是使用局部組件,大概的使用方法是這樣的:
首先定義一個Json,里面還是放我剛剛說過的那些實例中的屬性。
var todoList = {
template: '<li>item</li>';
};
然后我們在外層實例中,使用"component"屬性。
里面寫入:
component: {
'todo-list':todoList
}
todo-list為dom標簽的名字,而他的value就是咱們剛剛定義的那個屬性值。
回到剛剛說的定義的全局組件,component方法的第一個參數是使用這個組件的名稱,第二個參數就像是我們Vue實例一樣,里面有相應的參數設置。
- props: 如果在子組件中,我們需要父組件傳遞進來的參數,首先需要在html的標簽上綁定需要傳進去的參數,在這里一個是content,一個是index,然后需要在這個屬性注冊以下。
- template: 定義的自組件的模版。
- methods: 自組件需要用到的方法。
剛剛說到了父傳子,那子傳父我們應該怎么辦呢?
當一個事件在自組件被觸發的時候,我們需要在這個事件中加入
this.$emit('delete',this.index);
向外部發送一個名字叫做delete的事件(這個事件名稱可以自己隨意起),然后在后面的參數中加上想要傳遞的參數,最后在外部組件的當前元素中監聽剛剛發送的那個事件
@delete="handleDelete
再使用handleDelete方法進行具體處理就行。
Vue-cli 創建todo-list
下面咱們使用Vue-cli,進行一次todo-list的練習。
首先要確保自己的電腦上有node.js
沒有的話可以自行下載一下,node js 官網。
安裝好了之后,通過 node -v查看一下是否安裝成功了。
接下來我們就可以安裝vue-cli了
1.npm install --global vue-cli
2.vue init webpack projectName
在這步過程中cli會對這個項目的一些設置進行詢問,根據自己的需要填寫就行了。
3.npm run dev,啟動后輸入localhost:8080就有以下效果。
我是使用atom作為編輯器,打開工程后,進入src文件夾將main.js修改成下面這樣:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import ToDoList from './ToDoList'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { ToDoList },
template: '<ToDoList/>'
})
然后添加一個ToDoList.vue文件
<template>
<div>
<input v-model="inputValue"/>
<button @click="clickEvent">提交</button>
<ul>
<listitem v-for="(item,index) of list" :content="item" :index="index" @delete="deleteEvent"></listitem>
</ul>
</div>
</template>
<script>
import listitem from './components/listitem'
export default {
name: 'ToDoList',
components: {
listitem
},
data () {
return {
inputValue : '',
list:[]
}
},
methods:{
clickEvent:function(){
this.list.push(this.inputValue);
this.inputValue = '';
},
deleteEvent:function(index){
this.list.splice(this.index,1);
}
}
}
</script>
<style>
</style>
再添加一個listitem.vue文件
<template>
<li @click="clickEvent">{{content}}</li>
</template>
<script>
export default {
name: 'listitem',
props:['content','index'],
methods:{
clickEvent () {
this.$emit('delete',this.index);
}
}
}
</script>
<style >
</style>
可以看到為了徹底的接觸耦合,vue文件把代碼分為了三塊分別為 template(html代碼) ,script(js代碼),style(以及css代碼的形式)
還是啟動剛剛的localhost:8080,就可以看到效果了。
Tips:值得注意的是,我們現在要想使用data這個屬性,就不能使用key-value的形式了,而是需要寫成函數的形式,然后把數據作為返回值return出去:
data () {
return {
inputValue : '',
list:[]
}
}
后記
這是我vue的第一步,在這里做一個總結,之后的不斷學習,我也會不斷發文章進行更新的。