本项目主要仿照慕课网饿了么APP(基于vue1.x),然后我使用vue2.x重写了一遍,由于也没有vue实战经历,完全是用这个项目来练手和学习vue的语法,项目还有待改进。
- vue@2.1.10
- vue-cli
- vue-router
- axios
- ES2015
- webpack@2.2.1
- sass
# clone the repo
git clone https://github.com/YeaseonZhang/vue-eleme.git
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
MVVM: M 是 数据, V 是 DOM ,VM 即 VUE实例。
扩展HTML元素,封装可重用代码
- 页面上每个独立的可视/可交互区域视为一个组件
- 每个组件对应一个工程目录,组件所需的各种资源在目录下就近维护
- 页面是组件的容器,组件可以嵌套自由组合形成完整的页面
Vue-cli脚手架工具的功能:
- 目录结构
- 本地调试
- 代码部署
- 热加载
- 单元测试
-
将svg矢量图标制作成字体文件
使用icomoon工具,生成一个包
-
reset.css Download
npm install sass-loader node-sass --save-dev
https://router.vuejs.org/zh-cn/essentials/getting-started.html
npm install vue-router
// router.js
import Vue from 'vue';
import router from 'vue-router';
Vue.use(router);
export default new Router({
routes: [
// "/"根目录自动重定向到“/goods”
{
path: '/',
redirect: '/goods'
},
{
path: '/goods',
name: 'Goods',
component: Goods
}
]
});
// HTML
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/goods">Go to Goods</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
挂载到Vue实例上
import Vue from 'vue';
import App from './App';
import router from './router';
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
});
将localhost,替换成ifconfig/ipconfig
的本机IP,通过草料网将我们的链接生成二维码,微信扫码访问即可。
// 定义一个代码块
@mixin border-1px($color){
position: relative;
&:after {
display: block;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
border-top: 1px solid $color;
content: ' '
}
}
// 媒体查询
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) {
.border-1px {
&::after {
-webkit-transform: scaleY(0.7);
transform: scaleY(0.7);
}
}
}
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
.border-1px {
&::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
}
// 使用
@include border-1px(rgba(7, 17, 27, 0.1));
组件中使用axios过程中偶遇bug
// error, can't set data
created: () => {
var self = this;
axios.get('/api/seller').then((res) => {
if (res.data.errno === ERR_OK) { // success
self.seller = res.data.data;
console.log(self.seller);
};
});
}
// correct
created () {
var self = this;
axios.get('/api/seller').then((res) => {
if (res.data.errno === ERR_OK) { // success
self.seller = res.data.data;
console.log(self.seller);
};
});
}
<div class="parent">
<v-header :seller="seller"></header>
<!-- something -->
</div>
var parent = new Vue({
el: '.parent',
data: {
seller: '...'
}
})
<div class="child">
<p>{{ seller.title }}</p>
</div>
var child = new Vue({
el: '.child',
// props 属性用于接收来自父组件的数据
props: {
seller: Object
}
})
注:chrome最小font-size
: 12px;
{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
white-space
: 设置如何处理元素中的空白
值
normal: 连续的空白符会被合并,换行符会被当作空白符来处理。填充line盒子时,必要的话会换行。
pre: 连续的空白符会被保留。在遇到换行符或者<br>
元素时才会换行。
nowrap: 和 normal 一样,连续的空白符会被合并。但文本内的换行无效。
pre-wrap: 连续的空白符会被保留。在遇到换行符或者<br>
元素,或者需要为了填充line盒子时才会换行。
pre-line: 连续的空白符会被合并。在遇到换行符或者<br>
元素,或者需要为了填充line盒子时会换行。
属性值 | 换行符 | 空格和制表符 | 文字转行 |
---|---|---|---|
normal | 合并 | 合并 | 转行 |
nowrap | 合并 | 合并 | 不转行 |
pre | 保留 | 保留 | 不转行 |
pre-wrap | 保留 | 保留 | 转行 |
pre-line | 保留 | 合并 | 转行 |
- HTML
<div class="detail-wrapper clearfix">
<div class="detail-main">
// content
</div>
</div>
<div class="detail-close">
// close btn
<i class="icon-close"></i>
</div>
- SASS
.clearfix {
display: inline-block;
&:after {
display: block;
content: ".";
height: 0;
line-height: 0;
clear: both;
visibility: hidden;
}
}
.detail-wrapper {
min-height: 100%;
.detail-main {
padding-bottom: 64px;
}
}
.detail-close {
position: relative;
width: 32px;
height: 32px;
margin: -64px auto 0 auto;
clear: both;
font-size: 32px;
}
先引入,后注册
import star from 'components/star/star';
export default {
data () {
...
},
methods: {
...
},
created () {
...
}
components: {
star
}
};
- HTML
<transition name="fade">
<div v-show="detailShow" class="detail">
// some
</div>
</transition>
使用<transition name="fade">
标签包裹使用过渡效果的组件,name
是使用的过渡效果
- CSS
.detail {
transition: all .5s;
background: rgba(7, 17, 27, 0.8);
&.fade-transition {
opacity: 1;
}
&.fade-enter, &.fade-leave {
opacity: 0;
background: rgba(7, 17, 27, 0);
}
}
在组件内部使用transition
属性。
backdrop-filter: blur(10px);
模糊效果,仅iOS Safari支持。
Vue通过ref
属性引用元素或者组件的DOM节点。
<div ref="divBox">
// use
vm.$refs.divBox
注:ref属性统一使用驼峰命名法,不支持短横线div-box
。
$event
可以获取事件属性
<div @click="foo(params, $event)">
methods: {
foo (params, event) {
//...
}
}
设置为50%为圆形
border-radius: 50%
Props
传入属性值类型为Array
时,default
为一个函数,类似data
。
props: {
arr: {
type: Array,
default () {
return [];
}
}
}
Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
.image-header {
position: relative;
width: 100%;
height: 0;
padding-top: 100%;
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
height: 0; padding-top: 100%;
是重点,通过父元素的hight
设置为0,padding=top/padding-bottom
设置width
的百分比撑开高度。
// defined
@click="doSomething"
methods: {
doSomething(event) {
}
}
v-show
赋值一个函数,函数返回值true
or false
.
子组件修改父组件prop
属性。