Vue

vue

传统开发模式 现代开发模式
jQuery vue/react
80%的精力放在表现层 20%的精力放在表现层
前端渲染 后台渲染
降低服务器负担、带宽压力小、用户体验好 SEO、兼容、安全性

vue的核心是数据

  • {{}}
<body>
    <div id="div1">
        {{name}}
        {{age}}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
    let vm = new Vue({
        el: '#div1',
        data: {
            age: 18,
            name: 'zhangsan'
        }
    })
    </script>
</body>

{{}}双括号里面的内容vue会到data里面去找。但是缺点是页面加载延迟的时候会出现{{name}}的状态
./1.php

<?php
sleep(3)
?>
sleep(3)

./index.html

<body>
    <div id="div1">
        {{name}}
        {{age}}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
    let vm = new Vue({
        el: '#div1',
        data: {
            age: 18,
            name: 'zhangsan'
        }
    })
    </script>
</body>

扔到服务器去访问

三秒前


image.png

三秒后


image.png

v-clock

<style>
  *[v-clock] {display: none}
</style>

指令

补充了html的属性

v-bind

v-bind:绑定数据,用于任何属性

<div id="div1">
      <p v-bind:title="age">{{name}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      let vm = new Vue({
        el:'#div1',
        data: {
          age: 18,
          name: 'zhangsan'
        }
      })
    </script>
image.png

v-bind:xxx
:xxx(缩写)

<p :title="age">{{name}}</p>

两个属性有另外的写法
(1)class="aa bb"

.aa {
  width: 200px;
  height: 200px
}
.bb {
  background-color: red
}
<div id="div1">
  <div :class="class_str">1</div>
  <hr>
  <div :class="class_arr">2</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  let vm = new Vue({
  el: '#div1',
  data: {
    class_str: 'aa bb',
    class_arr: ['aa', 'bb']
  }
})
</script>

image.png

(2)style="width: 200px;backgound-color: red"

<div id="div1">
<p :style="style_str">{{content}}</p>
<strong :style='style_json'>{{content}}</strong>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  let vm = new Vue({
    el: '#div1',
    data: {
      content: '我是中国人',
      style_str: 'color: red; fontSize: 40px',
      style_json: {color:'green',fontSize:'20px'}
    }
  })
</script>
image.png

v-mode

双向绑定

<div id='div1'>
  <input v-model="name" type='text'/>
  <p>{{name}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  let vm = new Vue({
    el: '#div1',
    data: {
        name: 'lwp'
    }
  })
image.png

你输入啥就立马显示啥

事件

v-on:click=""||@click=""

<body>
    <div id="div1">
        <input type="button" @click="fn()">
    </div>
</body>
<script>
    let vm = new Vue({
        el: '#div1',
        methods: {
            fn() {
                alert('1')
            }
        }
    });
</script>

事件修饰符

事件冒泡

<body>
    <div id="div1" @click="father()">
        <input type="button" @click="son()">
    </div>
</body>
<script>
    let vm = new Vue({
        el: '#div1',
        methods: {
            father() {
                alert('father')
            },
            son() {
                alert('son')
            }
        }
    });
</script>

.stop阻止事件冒泡

<body>
    <div id="div1" @click="father()">
        <input type="button" @click.stop="son()">
    </div>
</body>
<script>
    let vm = new Vue({
        el: '#div1',
        methods: {
            father() {
                alert('father')
            },
            son() {
                alert('son')
            }
        }
    });
</script>
修饰符 作用
prevent 阻止默认事件
stop 阻止事件冒泡
native 原生(配合组件使用)
keycode|name 按键
once 只会一次操作,后面就失效了
self 只认自己
capture 捕获阶段的事件

key:连着用,多个按键同时按才触发

.ctrl.enter

computed

<body>
    <div id="div1">
        {{num1}}+{{num2}}={{num3}}
    </div>
</body>
<script>
    let vm = new Vue({
        el: '#div1',
        data: {
            num1: 1,
            num2: 1,
        },
        computed: {
            num3() {
                return this.num1 + this.num2
            },
        }
    });
</script>

这个功能用methods也能实现
但是computed有好处

1、缓存(跟methods每次计算不一样,只有数据变才会重新计算)->性能高
2、方便:既能读又能写

既能读又能写

<body>
    <div id="div1">
        <input type="text" v-model="familyName">
        <input type="text" v-model="givenName">
        <input type="text" v-model="name">
    </div>
</body>
<script>
    let vm = new Vue({
        el: '#div1',
        data: {
            familyName: '张',
            givenName: '三',
        },
        computed: {
            name: {
                get() {
                    return this.familyName + this.givenName
                },
                set(value) {
                    this.familyName = value[0];
                    this.givenName = value.substring(1)
                }
            },
        }
    });
</script>
image.png

既能从前到后


image.png

也能从后到前


image.png

高亮表示输入

监听

<body>
    <div id="div1">
        <input type="text" v-model="name">
    </div>
</body>
<script>
    let vm = new Vue({
        el: '#div1',
        data: {
            name: 'lwp'
        },
        watch: {
            name() {
                console.log('name change')
            }
        }
    });
</script>

数据通信

axios

get

前面我们都是引用vue.js的做法,这种方式太low了,接下来我们用webpack的方式,以后也都用这种方式

npm init -y
npm i axios vue -D

./webpack.config.js

const path = require('path')
module.exports={
  mode:'development',
  entry:'./src/vm.js',
  output:{
    path:path.resolve(__dirname,'build'),
    filename:'bundle.min.js'  
  }
}

./src/vm.js

import Vue from 'vue/dist/vue.esm'
import Axios from 'axios'
let vm=new Vue({
el:'#div1',
data:{
  name:'',
age:''
 },
async created(){
  let {data}=await Axios.get('./data/user.json');
this.name=data.name;
this.age=data.age
},
template:'<div>姓名:{{name}}年龄:{{age}}</div>'
})

./data/user.json

{
"name":"lwp",
"age":18
}

./index.html

<body>
  <div id="div1"></div>
</body>
<script src="./build/bundle.min.js"></script>

把代码扔到服务器去


image.png

webpack编译一下

post

./src/vm.js

import Vue from 'vue/dist/vue.esm'
import Axios from 'axios'
import {stringify} from 'querystring'
const axios=Axios.create({
  transformRequest:[
    function(data){
      stringify(data)
    }
  ]
})
let vm=new Vue({
el:'#div1',
data:{
  sum:0
 },
async created(){
  let {data}=await axiost({
  url:'./data/sum.php',
  data:{a:1,b:1}
  });
this.sum=data
},
template:'<div>{{sum}}</div>'
})

./data/sum.php

<?php
  echo $_POST('a')+$_POST('b')
?>

./index.html

<body>
  <div id="div1"></div>
</body>
<script src="./build/bundle.min.js"></script>

把代码扔到服务器去


image.png

webpack编译一下

fetch

get

./src/vm.js

import Vue from 'vue/dist/vue.esm'
let vm=new Vue({
el:'#div1',
data:{
  name:'',
  age:''
 },
async created(){
  let res=await fetch('./data/user.json');
  let data=await res.json();
  this.name=data.name;
  this.age=data.age
},
template:'<div>姓名:{{name}}年龄:{{age}}</div>'
})

./data/user.json

{
"name":"lwp",
"age":18
}

./index.html

<body>
  <div id="div1"></div>
</body>
<script src="./build/bundle.min.js"></script>

把代码扔到服务器去


image.png

webpack编译一下

post

./src/vm.js

import Vue from 'vue/dist/vue.esm'
let vm=new Vue({
el:'#div1',
data:{
  sum:0
 },
async created(){
  let formdate= new FormData();
  formdate.append('a',1)
  formdate.append('b',1)
  let res=await fetch('./data/sum.php',{
  method: 'post',
  body:formdate
  });
  this.sum=await res.json();
},
template:'<div>{{sum}}</div>'
})

./data/sum.php

<?php
  echo $_POST('a')+$_POST('b')
?>

./index.html

<body>
  <div id="div1"></div>
</body>
<script src="./build/bundle.min.js"></script>

把代码扔到服务器去


image.png

webpack编译一下

组件

局部

./src/vm.js

import Vue from 'vue/dist/vue.esm'
let vue = new Vue({
    el: '#div1',
    data: {},
    template: '<div><cmp1/></div>',
    components: {
        cmp1: {
            data() {
                return { a: 12 }
            },
            template: '<div>{{a}}</div>'
        }
    }
})

代码下载

全局

刚刚正在一块,我们现在把components那块分出去

代码下载

传参

./src/vm.js

import Vue from 'vue/dist/vue.esm'
import './cmp1'
let vue = new Vue({
    el: '#div1',
    data: {},
    template: '<div><cmp1 name="lwp"/></div>',//传过去

})

./src/cmp1.js

import Vue from 'vue/dist/vue.esm'
Vue.component('cmp1', {
    props: ['name'],//接收
    data() {
        return { a: 22 }
    },
    template: '<div>{{name}}</div>'
})

但是有一个问题,如果vm.js想传数字,因为传到cmp1.js的是字符串,再用parseInt太麻烦了,因此数字是这么传的,加个冒号

./src/vm.js

import Vue from 'vue/dist/vue.esm'
import './cmp1'
let vue = new Vue({
    el: '#div1',
    data: {},
    template: '<div><cmp1 name="lwp" :age:"12"/></div>',//传过去

})

代码下载

动态组件

先提取出来
./src/vm.js

import Vue from 'vue/dist/vue.esm'
import './cmp1'
let vue = new Vue({
    el: '#div1',
    data: {},
    template: '<div><component is="cmp1" name="lwp" :age="24"/></div>',

})

./src/vm.js

import Vue from 'vue/dist/vue.esm'
import './cmp1'
let vue = new Vue({
    el: '#div1',
    data: {},
    template: '<div><component is="cmp1" name="lwp" :age="24"/></div>',

})

代码下载

单独实例化

组件如果不想单单在前台渲染而已,想做例如测试,就必须能够new出来
./src/cmp1.js

import Vue from 'vue/dist/vue.esm'
export default Vue.component('cmp1', {
    props: ['name', 'age'],
    data() {
        return { a: 11 }
    },
    template: `<div>
    {{name}}
    <p>{{age+1}}</p>
    </div>`
})

./src/vm.js

import Cmp1 from './cmp1'
let cmp = new Cmp1({
    propsData: {
        name: '张三',
        age: 12
    }

})
let vm = cmp.$mount();
console.log(vm.$el);
if (vm.$el.querySelector('p').innerHTML == '13') {
    console.log('正确')
} else {
    console.log('失败')
}

自定义组件

cnpm i bootstrap@3 -D

./src/vm.js

import MyDialog from './my-dialog'
template:`
  <div>
    <my-dialog>
      <template slot="title">标题</template>
        内容
    </my-dialog>
  </div>
`

./src/my-dialog.js

imort Vue from 'vue/dist/vue.esm'
import from 'bootstrap/dist/css/bootstrap.css'
import from './my-dialog.css'
export default Vue.component('my-dialog',{
  template:`
    <div class="panel panel-default my-dialog">
      <div class="panel-heading">
        <slot name="title"/>
      </div>
      <div class="panel-body">
        <slot/>
      </div>
    </div>
`
})

./src/css/my-dialog.css

.my-dialog.css {
  width: 400px;
  height: 160px;
  border: 1px solid #ccc;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
}

./webpack.config.js

module: {
  rules: [
    {test:/\.css$/,use:['style-loader','css-loader']},
    {test:/(eot|svg|ttf|woff|woff2)$/,use:'file-loader'}
  ]
}

代码下载

重构一下

之前的做法存在一些不方便的问题,通过重构改进一下,可以当成是模板
1.之前得手动在index.html 引入./dest/bundle.min.js表示生产模式,而引入bundle.min.js表示开发模式,使用dev-server,而且还得在浏览器去输入地址

  • --open 可以npm run start完直接打开浏览器访问localhost:8080
"start": "webpack-dev-server --open"

2.之前得import 'vue/dist/vue.esm'

resolve: {
            alias: {
                'vue': 'vue/dist/vue.esm',
                'bootstrap': 'bootstrap/dist/css/bootstrap.css'
            }
        },

有了这个,引入vue就行
代码下载

组件间通信

土办法

组件事件
emit 发送on 接收
off 取消once 一次
父子间通信

非父子间通信十分复杂,这里不做介绍,一般也不会用这种办法

./src/component/father.js

import Vue from 'vue'
import Son from './son'
export defaut Vue.component('father',{
  template:`
    <div>
      <div>父级</div>
      </son>
    </div>
`
})

./src/component/son.js

import Vue from 'vue'
export defaut Vue.component('son',{
  template:`
    <div>
      <div>子级</div>
    </div>
`
})

./src/index.js

import Vue from 'vue'
import Father from './component/father'
let vue = new Vue({
  el:'#div1',
  template: `
    </father>
  `
})
父亲找儿子

./src/component/father.js

import Vue from 'vue'
import Son from './son'
export defaut Vue.component('father',{
  methods:{
    fn(){
      this.$refs.c1.num++;
    }
  },
  template:`
    <div>
      <div">
        父级
        <input type="button" value="+1" @click="fn()" />
      </div>
      <son res="c1"/>
    </div>
`
})

./src/component/son.js

import Vue from 'vue'
export defaut Vue.component('son',{
  data(){
    return{
      num: 0
    }
  },
  template:`
    <div>
      <div>子级</div>
    </div>
`
})

代码下载

儿子找父亲

./src/component/father.js

import Vue from 'vue'
import Son from './son'
export defaut Vue.component('father',{
  data() {
    return {num: 0}
  },
  methods:{
    fn(){
      this.num++;
    }
  },
  template:`
    <div>
      <div">
        父级:{{num}}
      </div>
      <son :parent="this"/>
    </div>
`
})

./src/component/son.js

import Vue from 'vue'
export defaut Vue.component('son',{
  props: ['parent'],
  methods: {
    this.parent.fn();
  },
  template:`
    <div>
      子级
      <input type="button" value="+1" @click="fn()" />
    </div>
`
})

代码下载

emitAndOn

./src/component/father.js

import Vue from 'vue'
import Son from './son'
export default Vue.component('father', {
    methods: {
        fn() {
            this.$refs.c1.$emit('add_num', 7);
        }
    },
    template: `
    <div>
        <div>
            父级
            <input type="button" value="+7" @click="fn()"/>
        </div>
        <son ref="c1"/>
    </div>
    `
})

./src/component/son.js

import Vue from 'vue'
export default Vue.component('son', {
    data() {
        return {
            num: 0
        }
    },
    template: `
    <div>子级:{{num}}</div>
    `,
    created() {
        this.$on('add_num', function(n) {
            this.num += n;
        })
    }
})

代码下载

Vue2.0的写法

Vue2.0和Vue1.0的写法主要在组件的写法,会更简单,最后也会编译成Vue1.0的那种代码

./src/component/1.vue

<template lang="html>
</template>
<script>
export default {
  name:'xx',//这个名字是调试使用
  data() {},
  methods: {}
}
</script>
<style></style scoped>//没有scope表示里面的样式是全局,有是局部,当前页面有效
image.png

使用这个插件的时候报错会报name,利于寻找

cnpm i vue-loader vue-style-loader vue-html-loader vue-template-compiler -D

./webpack.config.js

{test:/\.css/,use:['vue-style-loader','css-loader']},
{test:/\.vue/,use:'vue-loader'}

./config/webpack.development.js

const VueLoaderPlugin=require('vue-loader/lib/plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
plugins:[
  new VueLoaderPlugin()
]

./src/index.js

import Vue from 'vue'
import Cmp1 from './cpmponent/cmp1.vue'
let vue = new Vue ({
  el: '#div1',
  cmponents: {
    Cmp1//注册一下
  },
  template: `
    <div><cmp1/></div>
  `
})

注册一下

代码下载

组件套组件

less

cnpm less less-loader -D
{test:/.less$/,use:['vue-style-loader','css-loader','less-loader']}

代码下载

之后组件的任何写法和前面vue1.0的写法没有任何区别

正经的写法

cnpm i vue-router -S

数据交互

1.aiox

cnpm i axios vue-axios -S

2.vue-resource
3.fetch

cnpm i vue-resource -S
S是生产模式 D是开发模式

./src/index.js

import Vue from 'vue'
import App from './app.vue'
import router from './routers'
// import Axios from 'axios'
// import VueAxios from 'vue-axios'
// Vue.use(VueAxios, Axios);
// import VueResource from 'vue-resource'
// Vue.use(VueResource)
let vue = new Vue({
    el: '#div1',
    data: {},
    components: {
        App
    },
    router,
    template: `
    <App/>
    `
})

./src/components/index.vue

<template lang="html">
    <div >首页</div>
</template>
<script>
import { constants } from 'crypto';
export default {
    name:'index',
    async created(){
        // let {data} = await this.axios.get('http://localhost:8080/data/1.json');
        // let {data} = await this.$http.get('http://localhost:8080/data/1.json')
        
        let res=await fetch('http://localhost:8080/data/1.json')
        let data=await res.json();
        console.log(data)
    }
}
</script>

代码下载

vue-cli(启动器)

脚手架

安装npm i vue-cli -g

vue
如果提示“无法识别 'vue' ” ,有可能是 npm 版本过低,可以使用 npm install -g npm 来更新版本

image.png

vue init 初始化(常用)
vue list 模板(常用)//其他的到github去搜vue template

vue list

image.png

使用webpack

vue init webpack project1

png

前面都选第一个,这里选第三个,因为我们要使用cnpm
vue-cli目录介绍

代码下载

路由

路由拦截

全局

只要没登陆,所有的页面就看不见


image.png

//只要localStorage没有存token或token过期,就会让用户登陆
./src/App.vue

if (!localStorage.token) {
      this.$router.push("/login");
    }

在登陆成功后,把后台获取到的token用localStorage存起来,并跳到首页


image.png
localStorage.token=json.token;
        this.$router.push('/index')

局部

有些页面没登陆就不让你看


image.png

main.js

router.beforeEach((to,from,next)=>{
  if(to.meta.requireAuth){
    if(localStorage.token){
      next()
    }else{
      next({
        path:'/login',
        query:{redirect:to.fullPath}
      })
    }
  }else{
    next()
  }
})
image.png

router.js

 meta:{
                requireAuth:true
            },

有需要登陆的路由就使用这个属性

vuex

cnpm i vuex -S

功能

1.数据跨组件共享
2.防止数据意外修改
3.方便调试


image.png

state:数据
mutations:修改state的唯一渠道,在其他地方修改state会报错,目的就是为了追踪哪个mutation修改了state,修改了哪些地方
devtools监控mutaitions
action:mutations的封装
state修改,vue components(组件)里面的数据也会改
vue components不能直接操作mutation,而必须调用actions,让actions去调用mutation
action可以异步操作,mutations不能
backend api 后台数据
./src/main.js

//1.引入
import vuex from 'vuex'
//2.挂载
//2.1vuex放在vue身上
Vue.use(Vuex)
//3.声明store对象
const store = new Vuex.Store({
  strict:process.env.NODE_ENV!='production',
  getters:{},
  state:{},
  mutations:{},
  modules:{},
  actions:{}
})
//2.2store放在vue身上
new Vue({
  store,
})

strict(true严格模式)在开发阶段设为true,发布阶段设为false,因为strict的实现原理是深度比较做检查,当state一多会非常慢

vuex辅助方法

映射
mapState state -> computed
mapActions actions -> methods
mapGetters getters -> computed
代码下载

动画

vue init webpack animate
在config/index.js26useEslint改成false
cnpm start
cnpm i vue2-animate -D


img

这种显示隐藏十分僵硬

用于一个单个对象

用<transition>标签包起来,name设为fade,fadeDown等其他名字就有不同效果,前提的有个css样式:时间:animate-duration:1s

./src/components/index.vue

<template lang="html">
<div>
<input type="button" value="显示隐藏" @click="b=!b">
<transition name="fadeDown">
<div id="box" v-if="b">fade
    </div>
</transition>
</div>
</template>
<script>
export default {
  name:'Index',
  data(){
    return {b:true}
  },
}
</script>
<style lang="css" scoped>
  #box {
    width: 100px;
    height: 100px;
    background-color: #ccc;
    animation-duration: 1s
  }
</style>

一组

用transition-group包起来,tag设置为我们想要的标签,必须得有key,建议是id,不能使用index

<template lang="html">
<div>
  <transition-group name="fadeUp" tag="ul">  
    <li v-for="item in arr" :key="item">
      {{item}}
    <a href="#" @click="del(index)">delete</a>
  </li>
</transition-group>
</div>
</template>
<script>
export default {
  name: "Index",
  data() {
    return {
      b: true,
      arr: [1, 5, 55, 6, 25, 2, 8, 75, 86, 95]
    };
  },
  methods: {
    del(index) {
      this.arr.splice(index, 1);
    }
  }
};
</script>
<style lang="css" scoped>
ul li {
  width: 100px;
  height: 100px;
  background-color: #ccc;
  animation-duration: 1s;
  margin: 10px;
}
</style>

前往官网查看更多样式
代码下载

vue项目-pc端

https://www.jianshu.com/p/35c9f952a792

vue项目-移动端

https://www.jianshu.com/p/1f4e261543e7

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容

  • 收获1:image.png在某些元素内部只有特殊的元素才有效,这种时候如果需要使用DOM模板(我简单化理解成自定义...
    张路1806阅读 191评论 0 0
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    小姜先森o0O阅读 9,461评论 0 72
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    柴东啊阅读 15,852评论 2 140
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    你猜_3214阅读 11,054评论 0 118
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    王喂马_阅读 6,452评论 1 77