步驟概要
設計步驟
- 拆分組件 (可以先准備好完整的bootstrap美化頁面,然后切分)
- 靜態組件
- 動態組件
軟件編寫步驟
- 准備靜態文件 (含bootstrap等)
- 編寫 vue webpacke
案例1:comment
1. 靜態頁面 與拆分
靜態頁面
先設計html 如 bootstrap css美化過的頁面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="./static/css/bootstrap.css">
<title>vue_demo</title>
</head>
<body>
<div id="app">
<div>
<header class="site-header jumbotron">
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>請發表對Vue的評論</h1>
</div>
</div>
</div>
</header>
<div class="container">
<div class="col-md-4">
<form action="form-horizontal">
<div class="form-group">
<label>用戶名</label>
<input type="text" class="form-control" placeholder="用戶名">
</div>
<div class="form-group">
<label>評論內容</label>
<textarea type="text" class="form-control" placeholder="評論內容"></textarea>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-default pull-right">提交</button>
</div>
</div>
</form>
</div> <!--md4 for Add end -->
<div class="col-md-8">
<h3 class="reply">評論回復:</h3>
<h2>暫無評論,點擊左側添加評論吧!</h2>
<ul class="list-group">
<li class="list-group-item">
<div class="handle">
<a>刪除</a>
</div>
<p class="user"><span>Tom</span><span>說:</span></p>
<p class="centence">jerry是貓</p>
</li>
</ul>
</div> <!--md8 for List end -->
</div>
</div>
</div> <!--app -->
</body>
</html>
頁面拆分


紅框含app,內部黃框為整體App.vue
綠框分割
其中header標記是html5 新標記http://know.webhek.com/html5/html5-header.html
2.代碼過程
2.1代碼靜態分割
main.js
/** * Created by infaa on 2018/9/18. */ import Vue from 'vue' import App from './App' /* eslint-disable no-new */ new Vue({ el: '#app', template: '<App/>', components: {App} })
App.uve
<template>
<div>
<header class="site-header jumbotron">
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>請發表對Vue的評論</h1>
</div>
</div>
</div>
</header>
<div class="container">
<Add/>
<List/>
</div>
</div>
</template>
<script>
import Add from './components/Add.vue'
import List from './components/List.vue'
export default {
components: {
Add,
List
}
}
</script>
<style>
</style>
./components/Add.vue
components 實際復雜情況下為目錄,每個目錄為完整一組功能,含圖片等元素。
<template> <div class="col-md-4"> <form action="form-horizontal"> <div class="form-group"> <label>用戶名</label> <input type="text" class="form-control" placeholder="用戶名"> </div> <div class="form-group"> <label>評論內容</label> <textarea type="text" class="form-control" placeholder="評論內容"></textarea> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="button" class="btn btn-default pull-right">提交</button> </div> </div> </form> </div> <!--md4 for Add end --> </template> <script> export default { } </script> <style> </style>
./components/List.vue
<template> <div class="col-md-8"> <h3 class="reply">評論回復:</h3> <h2>暫無評論,點擊左側添加評論吧!</h2> <ul class="list-group"> <li class="list-group-item"> <div class="handle"> <a>刪除</a> </div> <p class="user"><span>Tom</span><span>說:</span></p> <p class="centence">jerry是貓</p> </li> </ul> </div> <!--md8 for List end --> </template> <script> export default { } </script> <style> </style>
2.2 代碼動態傳遞(父組件->子組件->子組件)
app.vue
數據共享放於父組件
<template>
<div>
<header class="site-header jumbotron">
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>請發表對Vue的評論</h1>
</div>
</div>
</div>
</header>
<div class="container">
<Add :comments="comments"/>
<List :comments="comments"/>
</div>
</div>
</template>
<script>
import Add from './components/Add.vue'
import List from './components/List.vue'
export default {
components: {
Add,
List
},
data () {
return {
comments: [
{
name: 'bob',
content: 'Vue of bobaaaaaaaaaaaaaaaaaaaaaaaaaaa'
},
{
name: 'cat',
content: 'VUE OF CAT'
},
{
name: 'david',
content: 'vue of davie'
}
]
}
}
}
</script>
<style>
</style>
list.uve
components引入子組件,props申明父組件變量,:comment通過屬性向子組件傳遞 。 以上過程可以多次傳遞
<template> <div class="col-md-8"> <h3 class="reply">評論回復:</h3> <h2>暫無評論,點擊左側添加評論吧!</h2> <ul class="list-group" > <item v-for="(comment,index) in comments" :key="index" :comment="comment"></item> </ul> </div> <!--md8 for List end --> </template> <script> import Item from './Item.vue' export default { props: ['comments'], components: {Item} } </script> <style> .reply { margin-top: 0px; } li { transition: .5s; overflow: hidden; } .handle a { display: block; text-decoration: none; } </style>
item.vue
測試再向內傳遞comment值
<template> <li class="list-group-item"> <div class="handle"> <a>刪除</a> </div> <p class="user"><span>{{comment.name}}</span><span>說:</span></p> <p class="centence">{{comment.content}}</p> <Item2 :comment="comment"></Item2> </li> </template> <script> import Item2 from './Item2.vue' export default { props: {'comment': Object}, components: {Item2} } </script> <style> li { transition: .5s; overflow: hidden; } .handle { width: 40px; border: 1px solid #ccc; background: #fff; position: absolute; right: 10px; top: 1px; text-align: center; } .handle a { display: block; text-decoration: none; } .list-group-item .centence { padding: 0px 50px; } .user { font-size: 22px; } </style>
item2.vue
<template> <span :comment="comment">多次傳遞實例{{comment.content}}</span> </template> <script> export default { props:['comment'] } </script> <style> </style>
2.3 動態修改 增加與刪除評論功能添加 (完整代碼)
子組件中操作父組件的數據,通過父組件提供的方法完成(傳遞到子組件)。
數據在哪里,直接操作數據的方法寫在哪里。 子組件中通過傳遞進來的方法再處理。
app.vue
<template>
<div>
<header class="site-header jumbotron">
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>請發表對Vue的評論</h1>
</div>
</div>
</div>
</header>
<div class="container">
<Add :addComment="addComment" />
<List :comments="comments" :deleteComment="deleteComment"/>
</div>
</div>
</template>
<script>
import Add from './components/Add.vue'
import List from './components/List.vue'
export default {
components: {
Add,
List
},
data () {
return {
comments: [
{
name: 'bob',
content: 'Vue of bobaaaaaaaaaaaaaaaaaaaaaaaaaaa'
},
{
name: 'cat',
content: 'VUE OF CAT'
},
{
name: 'david',
content: 'vue of davie'
}
]
}
},
// 數據在哪里,就在哪里定義方法
methods: {
addComment (comment) {
this.comments.unshift(comment)
},
deleteComment (index) {
this.comments.splice(index, 1)
}
}
}
</script>
<style>
</style>
list.vue
<template> <div class="col-md-8"> <h3 class="reply">評論回復:</h3> <h2 v-show="comments.length===0">暫無評論,點擊左側添加評論吧!</h2> <ul class="list-group" > <item v-for="(comment,index) in comments" :index="index" :deleteComment="deleteComment" :comment="comment" :key="index"></item> </ul> </div> <!--md8 for List end --> </template> <script> import Item from './Item.vue' export default { props: ['comments', 'deleteComment'], components: {Item} } </script> <style> .reply { margin-top: 0px; } li { transition: .5s; overflow: hidden; } .handle a { display: block; text-decoration: none; } </style>
item.vue
刪除評論
<template> <li class="list-group-item"> <div class="handle"> <a href="javascript:;" @click="deleteItem">刪除</a> </div> <p class="user"><span>{{comment.name}}</span><span>說:</span></p> <p class="centence">{{comment.content}}</p> </li> </template> <script> export default { props: { 'comment': Object, 'deleteComment': Function, 'index': Number }, methods: { deleteItem () { const {comment, index, deleteComment} = this if (window.confirm(`確定刪除${comment.name}的評論嗎`)) { deleteComment(index) } } } } </script> <style> li { transition: .5s; overflow: hidden; } .handle { width: 40px; border: 1px solid #ccc; background: #fff; position: absolute; right: 10px; top: 1px; text-align: center; } .handle a { display: block; text-decoration: none; } .list-group-item .centence { padding: 0px 50px; } .user { font-size: 22px; } </style>
add.vue
<template> <div class="col-md-4"> <form action="form-horizontal"> <div class="form-group"> <label>用戶名</label> <input type="text" class="form-control" placeholder="用戶名" v-model="name"> </div> <div class="form-group"> <label>評論內容</label> <textarea type="text" class="form-control" placeholder="評論內容" v-model="content"></textarea> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="button" class="btn btn-default pull-right" @click="add">提交</button> </div> </div> </form> </div> <!--md4 for Add end --> </template> <script> export default { props: { addComment: { type: Function, required: true } }, data () { return { name: '', content: '' } }, methods: { add () { const name = this.name.trim() const content = this.content if (!name || !content) { alert('no name or content') return } const comment = { name, content } this.addComment(comment) // 清除輸入 this.name = '' this.content = '' } } } </script> <style> </style>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="./static/css/bootstrap.css">
<title>vue_demo</title>
</head>
<body>
<div id="app">
</div> <!--app -->
</body>
</html>
main.js
/** * Created by infaa on 2018/9/18. */ import Vue from 'vue' import App from './App' /* eslint-disable no-new */ new Vue({ el: '#app', template: '<App/>', components: {App} })
參考
https://github.com/sunny-sky/VueDemo
