最近接到一个项目,之前是使用vue + webpack 写的,立项之前根据之前的业务逻辑写的差不多了,但是现在正式立项,项目经理觉得使用vue+webpack 前后端彻底分离,后端改不了前台,后期不利于维护,维护成本过高,并且是在eclipse里面要启动两个项目,所以准备弃用webpack,所以我现在准备只使用vue,问:我需要准备什么?作为一个只学了vue 半年的半小白,要从哪里入手?怎么去搭建项目?需要怎么做呢????
1 <!DOCTYPE html> 2 <html lang="zh"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Todo, Done & Problems</title> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <link href="https://cdn.bootcss.com/element-ui/1.2.9/theme-default/index.css" rel="stylesheet"> 9 <script src="https://cdn.bootcss.com/vue/2.2.6/vue.min.js"></script> 10 <script src="https://cdn.bootcss.com/element-ui/1.2.9/index.js"></script> 11 <style> 12 p, 13 body { 14 margin: 0; 15 padding: 0; 16 } 17 18 #app { 19 position: absolute; 20 margin: auto; 21 right: 0; 22 left: 0; 23 } 24 25 .filter { 26 margin-top: 20px; 27 margin-bottom: 10px; 28 } 29 30 .el-card { 31 margin: 0.5rem; 32 } 33 34 .placeholder { 35 height: 260px; 36 } 37 38 .single-post { 39 min-width: 320px; 40 } 41 42 .card-header { 43 position: relative; 44 } 45 46 .card-header-side { 47 position: absolute; 48 right: -8px; 49 top: -8px; 50 } 51 52 span.card-header-side { 53 color: #48576a; 54 line-height: 36px; 55 } 56 57 .item-label { 58 color: #48576a; 59 } 60 61 .item-label:not(:first-child) { 62 margin-top: 1rem; 63 } 64 65 @media screen and (max-width: 700px) { 66 .filter { 67 margin: 0.5rem; 68 } 69 .filter .item-label { 70 display: inline-block; 71 } 72 .single-post { 73 min-width: initial; 74 } 75 } 76 77 @media screen and (min-width: 700px) { 78 .filter { 79 width: 700px; 80 margin-left: calc(50% - 340px); 81 } 82 .placeholder { 83 width: 320px; 84 } 85 .posts { 86 display: flex; 87 width: 100%; 88 flex-wrap: wrap; 89 justify-content: center; 90 } 91 .single-post { 92 max-width: 330px; 93 } 94 .new-post { 95 width: 600px; 96 left: calc(50% - 300px); 97 position: relative; 98 } 99 } 100 101 @media screen and (min-width: 1200px) { 102 .filter { 103 width: 1200px; 104 margin-left: calc(50% - 600px); 105 } 106 .single-post { 107 max-width: 400px; 108 } 109 .new-post { 110 width: 700px; 111 left: calc(50% - 350px); 112 } 113 } 114 </style> 115 </head> 116 117 <body> 118 <div id="app"> 119 <el-menu mode="horizontal" theme="dark"> 120 <el-menu-item index="1">View & Post</el-menu-item> 121 </el-menu> 122 <div class="filter"> 123 <span class="item-label">按日期过滤:</span> 124 <el-date-picker v-model="filterDate" align="left" type="date"> 125 </el-date-picker> 126 <span class="item-label" v-if="filterDate">共找到 {{selectedRecords.length}} 条记录</span> 127 </div> 128 <div class="posts"> 129 <el-card v-if="loadingPosts" v-loading="loadingPosts"> 130 <div class="placeholder"></div> 131 </el-card> 132 <template v-else> 133 <el-card v-for="r in selectedRecords" class="single-post" :key="r.id"> 134 <div slot="header" class="card-header"> 135 <span class="name">{{r.name}}</span> 136 <span class="card-header-side">{{r.date.toDateString()}}</span> 137 </div> 138 <section> 139 <p class="item-label">DONE:</p> 140 <p class="done">{{r.content.done}}</p> 141 <p class="item-label">TODO:</p> 142 <p class="todo">{{r.content.todo}}</p> 143 <p class="item-label">PROBLEM:</p> 144 <p class="problem">{{r.content.problem}}</p> 145 </section> 146 </el-card> 147 </template> 148 </div> 149 <div class="new-post"> 150 <el-card v-loading="postingNew"> 151 <div slot="header" class="card-header"> 152 <span>New Post</span> 153 <el-button type="primary" class="card-header-side" @click="newPost">Go!</el-button> 154 </div> 155 <el-form :model="payload" label-width="80px"> 156 <el-form-item label="NAME"> 157 <el-input v-model="payload.name"></el-input> 158 </el-form-item> 159 <el-form-item label="DONE"> 160 <el-input type="textarea" v-model="payload.content.done"></el-input> 161 </el-form-item> 162 <el-form-item label="TODO"> 163 <el-input type="textarea" v-model="payload.content.todo"></el-input> 164 </el-form-item> 165 <el-form-item label="PROBLEM"> 166 <el-input type="textarea" v-model="payload.content.problem"></el-input> 167 </el-form-item> 168 </el-form> 169 </el-card> 170 </div> 171 </div> 172 173 <script> 174 new Vue({ 175 el: '#app', 176 data() { 177 let urlPrefix; 178 switch (location.protocol) { 179 case 'file:': 180 urlPrefix = 'http://report.auto601.com'; 181 break; 182 case 'http:': 183 case 'https:': 184 urlPrefix = '' 185 } 186 return { 187 urlPrefix, 188 filterDate: null, 189 records: [], 190 payload: { 191 name: '', 192 content: { 193 done: '', 194 todo: '', 195 problem: '' 196 } 197 }, 198 loadingPosts: true, 199 postingNew: false 200 }; 201 }, 202 computed: { 203 selectedRecords() { 204 if (!this.filterDate) { 205 return this.records; 206 } else { 207 const start = this.filterDate.getTime(); 208 const end = this.filterDate.getTime() + 24 * 3600 * 1000; 209 return this.records.filter(i => i.date.getTime() <= end && i.date.getTime() >= start); 210 } 211 } 212 }, 213 methods: { 214 clear() { 215 this.payload = { 216 name: '', 217 content: { 218 done: '', 219 todo: '', 220 problem: '' 221 } 222 }; 223 } 224 , 225 async getAll() { 226 this.loadingPosts = true; 227 try { 228 this.records = await fetch(`${this.urlPrefix}/api/posts`) 229 .then(r => r.json()) 230 .then(j => { 231 j.forEach(i => i.date = new Date(i.date)); 232 return j; 233 }); 234 } 235 catch (err) { 236 this.$message.error('Load failed!'); 237 } 238 this.loadingPosts = false; 239 }, 240 async getMarkDown(text) { 241 return await fetch('https://api.github.com/markdown', { 242 method: 'POST', 243 body: JSON.stringify({ text, mode: 'gfm' }) 244 }).then(r => r.text()); 245 }, 246 async newPost() { 247 this.postingNew = true; 248 const resp = await fetch(`${this.urlPrefix}/api/posts`, { 249 method: 'POST', 250 headers: { 251 'Content-Type': 'application/json' 252 }, 253 body: JSON.stringify(this.payload) 254 }); 255 this.postingNew = false; 256 if (resp.status == 200) { 257 this.$message.success('Post Success!'); 258 this.clear(); 259 } else { 260 this.$message.error('Post Failed! Error code: ' + resp.status); 261 } 262 this.getAll(); 263 } 264 }, 265 created() { 266 this.getAll(); 267 } 268 }); 269 </script> 270 </body> 271 272 </html>
你可以看看我上面给出的这个 index.html
一个使用 ElementUI + Vue 的单页应用(因为只有一个 Index.html)
当你移除了 Webpack 之后,模块化就不太好实现,如果后端想要不接触 js 模块化相关的内容,你就必须要放弃 Vue 中要使用模块化的功能,就一个页面一个 Vue app,只用 Vue 来渲染 ajax 数据,像什么路由啊之类的都交给后端来做。
简单来说,把 Vue 当作 JQuery 来用就对了。
<script src="//cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
引入就完啦?怎么构建呢