Vue学习记录

Here, you can get source code.

Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable.

Vue

Using IDEA plugin:

image-20200915111843300

Using Vue, You can create an index.html file and include Vue with:

<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

or:

<!-- production version, optimized for size and speed -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

Declarative Rendering

At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax:

<div id="app">
  {{ message }}
</div>

You can offer the data by:

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

Run it:

Hello Vue!

The data and the DOM are now linked, and everything is now reactive. How do we know? Open your browser’s JavaScript console (right now, on this page) and set app.message to a different value. You should see the rendered example above update accordingly.

vue_reactive

Note that we no longer have to interact with the HTML directly. A Vue app attaches itself to a single DOM element (#app in our case) then fully controls it.

In addition to text interpolation, we can also bind element attributes like this:

<div id="app-2">
  <span v-bind:title="message">
    Hover your mouse over me for a few seconds
    to see my dynamically bound title!
  </span>
</div>
    var app2 = new Vue({
        el: '#app-2',
        data: {
            message: 'You loaded this page on ' + new Date().toLocaleString()
        }
    })

Hover your mouse over me for a few seconds to see dynamically bound title.

Here we are encountering something new. The v-bind attribute you are seeing is called a directive. Directives are prefixed with v- to indicate that they are special attributes provided by Vue, and as you may have guessed, they apply special reactive behavior to the rendered DOM. Here, it is basically saying “keep this element’s title attribute up-to-date with the message property on the Vue instance.”

If you open up your JavaScript console again and enter app2.message = 'some new message', you’ll once again see that the bound HTML - in this case the title attribute - has been updated like before.

Conditionals and Loops

It’s easy to toggle the presence of an element, too:

<div id="app-3">
  <span v-if="seen">Now you see me</span>
</div>
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})

result:

Now you see me

Go ahead and enter app3.seen = false in the console. You should see the message disappear.

There are quite a few other directives, each with its own special functionality. For example, the v-for directive can be used for displaying a list of items using the data from an Array:

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: 'Learn JavaScript' },
      { text: 'Learn Vue' },
      { text: 'Build something awesome' }
    ]
  }
})

result:

image-20200916102159331

In the console, enter app4.todos.push({ text: 'New item' }). You should see a new item appended to the list.

Handling User Input

To let users interact with your app, we can use the v-on directive to attach event listeners that invoke methods on our Vue instances:

<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">Reverse Message</button>
</div>
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
vue_reverse

Note that in this method we update the state of our app without touching the DOM - all DOM manipulations are handled by Vue, and the code you write is focused on the underlying logic.

Vue also provides the v-model directive that makes two-way binding between form input and app state a breeze:

<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>
var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})
vue_model

Composing with Components

The component system is another important concept in Vue, because it’s an abstraction that allows us to build large-scale applications composed of small, self-contained, and often reusable components. If we think about it, almost any type of application interface can be abstracted into a tree of components:

Component Tree

In Vue, a component is essentially a Vue instance with pre-defined options. Registering a component in Vue is straightforward:

// Define a new component called todo-item
Vue.component('todo-item', {
  template: '<li>This is a todo</li>'
})

var app = new Vue(...)

Now you can compose it in another component’s template:

<ol>
  <!-- Create an instance of the todo-item component -->
  <todo-item></todo-item>
</ol>

But this would render the same text for every todo, which is not super interesting. We should be able to pass data from the parent scope into child components. Let’s modify the component definition to make it accept a prop:

Vue.component('todo-item', {
  // The todo-item component now accepts a
  // "prop", which is like a custom attribute.
  // This prop is called todo.
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

Now we can pass the todo into each repeated component using v-bind:

<div id="app-7">
  <ol>
    <!--
      Now we provide each todo-item with the todo object
      it's representing, so that its content can be dynamic.
      We also need to provide each component with a "key",
      which will be explained later.
    -->
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id"
    ></todo-item>
  </ol>
</div>
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
  el: '#app-7',
  data: {
    groceryList: [
      { id: 0, text: 'Vegetables' },
      { id: 1, text: 'Cheese' },
      { id: 2, text: 'Whatever else humans are supposed to eat' }
    ]
  }
})

run it:

image-20200916110629416

This is a contrived example, but we have managed to separate our app into two smaller units, and the child is reasonably well-decoupled from the parent via the props interface. We can now further improve our <todo-item> component with more complex template and logic without affecting the parent app.

In a large application, it is necessary to divide the whole app into components to make development manageable. We will talk a lot more about components later in the guide, but here’s an (imaginary) example of what an app’s template might look like with components:

<div id="app">
  <app-nav></app-nav>
  <app-view>
    <app-sidebar></app-sidebar>
    <app-content></app-content>
  </app-view>
</div>

Vue-Axios

Vue 实例生命周期

Axios是一个开源的可以在浏览器端和NodeJS的异步通信框架,主要作用是实现Ajax异步通信。

准备一份JSON文件:

{
  "name": "Q",
  "url": "https://hellooooo.top",
  "page": 1,
  "liangzai": true
}

使用Vue的钩子函数进行Axios异步请求:

    var vue = new Vue({
        el: '#app',
        data: {
            message: "Hello"
        },
        //钩子
        mounted(){
            axios.get('/Vue/vue-first/data.json').then(response => console.log(response.data));
        }
    });

结果:

image-20200922102058918

将Axios得到的数据与页面进行绑定:

    var vue = new Vue({
        el: '#app',
        data() {
            return{
                info: {
                    name: null,
                    url: null,
                    liangzai: null
                }
            }
        },
        //钩子
        mounted(){
            // axios.get('/Vue/vue-first/data.json').then(response => console.log(response.data));
            axios.get('/Vue/vue-first/data.json').then(response => this.info = response.data);

        }
    });

页面:

<div id="app">
    <span>{{info.name}}</span>
    <span>{{info.url}}</span>
    <span>{{info.liangzai}}</span>
</div>

结果:

image-20200922103904787

计算属性

有缓存的味道。

    var vm = new Vue({
        el: '#app',
        data: {
            message: "Hello"
        },
        methods: {
            currentTime: function (){
                return Date.now();
            }
        },
        //计算属性
        //注意methods和computed尽量不要重名
        computed: {
            currentTime2: ()=>{
                return Date.now();
            }
        }
    });
    <p>current: {{currentTime()}}</p>
    <p>current: {{currentTime2}}</p>

运行:

vue_computed

可以看到currentTime方法输出的时间都在变化,而currentTime2每次都输出相同的时间戳。

内容分发


    Vue.component("todo",{
        template: '<div>' +
            '<slot name="todo-title"></slot>' +
            '<ul>' +
            '<slot name="todo-items"></slot>' +
            '</ul>' +
            '</div>'
    });

    Vue.component("todo-title", {
        props: ['title'],
        template: '<div>{{title}}</div>'
    });

    Vue.component("todo-items", {
        props: ['item'],
        template: '<li>{{item}}</li>'
    });

    var vm = new Vue({
        el: '#app',
        data: {
            title: "liang",
            todoItems: [
                'Liang0',
                'Liang1',
                'Liang2',
                'Liang3'
            ]
        }

    });

下面的":"是"v-bind:"的简写,":title"相当于"v-bind:title"。

<div id="app">
    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items>
    </todo>
</div>

效果:

image-20200922111638314

如果需要在每个项目之后增添一个删除按钮:

    Vue.component("todo-items", {
        props: ['item'],
        template: '<li>{{item}} <button @click="remove">Delete</button></li>',
        methods: {
            remove: ()=>{
                alert("Choose delete.")
            }
        }
    });
    var vm = new Vue({
        el: '#app',
        data: {
            title: "liang",
            todoItems: [
                'Liang0',
                'Liang1',
                'Liang2',
                'Liang3'
            ]
        },
        methods:{
            removeItems: (index)=>{
                console.log("Will remove: " + this.todoItems[index]);
                //删除当前
                this.todoItems.splice(index, 1);
            }
        }

    });

可以做到监听,但是组件无法做到调用Vue实例的removeItems方法删除数据。

即组件如何删除Vue实例中的数据?

自定义事件

this.$emit

    Vue.component("todo",{
        template: '<div>' +
            '<slot name="todo-title"></slot>' +
            '<ul>' +
            '<slot name="todo-items"></slot>' +
            '</ul>' +
            '</div>'
    });

    Vue.component("todo-title", {
        props: ['title'],
        template: '<div>{{title}}</div>'
    });

    Vue.component("todo-items", {
        props: ['item', 'index'],
        template: '<li>{{index}}:{{item}} <button @click="remove">Delete</button></li>',
        methods: {
            remove: function (index){
                // alert("Choose delete.")
                this.$emit('remove', index);
            }
        }
    });

    var vm = new Vue({
        el: '#app',
        data: {
            title: "liang",
            todoItems: [
                'Liang0',
                'Liang1',
                'Liang2',
                'Liang3'
            ]
        },
        methods:{
            removeItems: function (index){
                console.log("Will remove: " + this.todoItems[index]);
                //删除当前
                this.todoItems.splice(index, 1);
            }
        }

    });
<div id="app">
    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <todo-items slot="todo-items" v-for="item,index in todoItems" :item="item" :index="index" :key="index" v-on:remove="removeItems(index)"></todo-items>
    </todo>
</div>

Vue-Cli

官方提供的一个脚手架。

先安装Node.js,安装完成后,打开CMD:

C:\Users\Q>node -v
v10.18.0
C:\Users\Q>npm -v
6.13.4

安装淘宝镜像加速器:

# -g 全局安装
npm install cnpm -g

如果不想安装可以在安装的时候增加如下参数:

npm install --registry=https://registry.npm.taobao.org

安装vue-cli:

cnpm install vue-cli -g

查看:

vue list
image-20200922160314070

创建第一个vue-cli应用程序

在命令行执行:

vue init webpack myvue

myvue为项目名称.

image-20200922161813167

初始化并且运行:

cd myvue
npm install
npm run dev
image-20200922162200979

Webpack

安装Webpack:

npm install webpack -g
npm install webpack-cli -g

查看版本:

webpack -v
webpack-cli -v

新建文件夹webpack-study并进入:

mkdir webpack-study
cd webpack-study

新建modules:

mkdir modules

在其内新建一个Hello.js:

//暴露一个方法
exports.sayHi = ()=>{
    document.write("<h1>Liangzai</h1>")
};

新建一个main.js:

var hello = require("./hello");
hello.sayHi();

在webpack-study内新建一个webpack.config.js:

module.exports = {
    entry: './modules/main.js',
    output: {
        filename: "./js/bundle.js"
    }
};
image-20200922183904503

在命令行输入:

webpack

自动生成了bundle.js:

image-20200922184053396

测试使用:

新建index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>
</html>
image-20200922184240938

Vue-Router

进入自己项目根目录,安装:

npm install vue-router --save-dev

声明使用Vue-Router

import VueRouter from "vue-router";
//显式声明使用Vue-Router
Vue.use(VueRouter);

简单使用:

新建两个Component,一个Content,一个Main:

<template>
  <h1>Content</h1>
</template>

<script>
export default {
  name: "Content"
}
</script>

<style scoped>

</style>
<template>
<h1>Main</h1>
</template>

<script>
export default {
  name: "Main"
}
</script>

<style scoped>

</style>

在src目录下新建router目录,并添加index.js作为配置文件:

import Vue from "vue";
import VueRouter from "vue-router";
import Content from "../components/Content";
import Main from "../components/Main";
//安装路由
Vue.use(VueRouter);

//配置导出路由
export default new VueRouter({
  routes: [
    {
    //  路由路径
      path: '/content',
      name: "content",
    //  跳转组件
      component: Content
    },
    {
      //  路由路径
      path: '/main',
      name: "main",
      //  跳转组件
      component: Main
    }
  ]
})

编辑main.js配置路由:

//自动扫描里的路由配置
import router from './router';
...
//在Vue实例内配置路由
new Vue({
  el: '#app',
  //在Vue实例配置路由
  router,
  components: { App },
  template: '<App/>'
})

配置App.vue,添加路由跳转:

<template>
  <div id="app">
    <h1>靓仔</h1>
    <router-link to="/main">Main</router-link>
    <router-link to="/content">Content</router-link>
    <router-view></router-view>
  </div>
</template>

其他保持不变,运行测试:

vue-router

Vue + ElementUI

创建一个名为hello-vue的工程:

vue init webpack hello-vue

进入hello-vue安装vue-router,element-ui,sass-loader和node-sass:

npm install vue-router --save-dev
npm i element-ui -S
#安装依赖
npm install
#安装SASS加载器
npm install sass-loader node-sass --save-dev
#启动测试
npm run dev

准备Main页面以及Login页面,

Main:

<template>
  <h1>MAIN</h1>
</template>

<script>
export default {
  name: "Main"
}
</script>

<style scoped>

</style>

Login:

<template>
  <div>
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号" prop="username">
        <el-input type="text" placeholder="请输入账号" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" placeholder="请输入密码" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
      </el-form-item>
    </el-form>

    <el-dialog
      title="温馨提示"
      :visible.sync="dialogVisible"
      width="30%">
      <span>请输入账号和密码</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<style lang="scss" scoped>
.login-box{
  border: 1px solid #DCDFE6;
  width: 350px;
  margin:180px auto;
  padding:35px 35px 15px 35px;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  box-shadow:0 0 25px #909399;
}

.login-title{
  text-align:center;
  margin:0 auto 40px auto;
  color:#303133;
}
</style>
<script>
  export  default {
    name:"Login",
    data(){
      return {
        form:{
          username: '',
          password: ''
        },
        //表单验证,需要再el-form-item 元素中增加prop属性
        rules:{
          username:[
            {required:true,message:'账号不能为空',trigger:'blur'}
          ],
          password:[
            {required: true,message: '密码不能为空',trigger:'blur'}
          ]
        },
        //对话框显示和隐藏
        dialogVisible:false
      }
    },
    methods:{
      onSubmit(formName) {
        //为表单绑定验证功能
        this.$refs[formName].validate((valid) =>{
          if (valid){
            //使用 vue-router路由到指定页面,该方式称之为编程式导航
            this.$router.push("/main");
          } else {
            this.dialogVisible = true;
            return false;
          }
        });
      }
    }
  }
</script>

路由配置:

import Vue from "vue";
import VueRouter from "vue-router";

import Main from "../views/Main";
import Login from "../views/Login";

Vue.use(VueRouter);

export default new VueRouter({
  routes: [
    {
      path: '/login',
      component: Login
    },
    {
      path: '/main',
      component: Main
    }
  ]
});

App.vue配置展示界面:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

main.js配置:

import Vue from 'vue'
import App from './App'
import router from "./router";

import Element from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.config.productionTip = false

Vue.use(router);
Vue.use(Element);

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render: h => h(App),
  components: { App },
  template: '<App/>'
})

如果报错:

 ERROR  Failed to compile with 1 errors    

可能是sass版本太高所致:

卸载当前sass版本:

npm uninstall sass-loader
npm install sass-loader@7.3.1 --save-dev

结果:

vue-router-elementui

路由嵌套

替换Main.vue:

<template>
  <div>
    <el-container>
      <el-aside width="200px">
        <el-menu :default-openeds="['1']">
          <el-submenu index="1">
            <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
            <el-menu-item-group>
              <el-menu-item index="1-1">
                <router-link to="/user/profile">个人信息</router-link>
              </el-menu-item>
              <el-menu-item index="1-2">
                <router-link to="/user/list">用户列表</router-link>
              </el-menu-item>
            </el-menu-item-group>
          </el-submenu>
          <el-submenu index="2">
            <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
            <e1-menu-item-group>
              <el-menu-item index="2-1">分类管理</el-menu-item>
              <el-menu-item index="2-2">内容列表</el-menu-item>
            </e1-menu-item-group>
          </el-submenu>
        </el-menu>
      </el-aside>

      <el-container>
        <el-header style="text-align: right; font-size: 12px">
          <el-dropdown>
            <i class="el-icon-setting" style="margin-right:15px"></i>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>个人信息</el-dropdown-item>
              <el-dropdown-item>退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </el-header>
      </el-container>

      <el-container>
        <el-header style="text-align: right; font-size: 12px">
          <el-dropdown>
            <i class="el-icon-setting" style="margin-right:15px"></i>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>个人信息</el-dropdown-item>
              <el-dropdown-item>退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </el-header>
        <el-main>
          <router-view/>
        </el-main>
      </el-container>
    </el-container>

  </div>
</template>

<script>
export default {
  name: "Main"
}
</script>

<style scoped lang="scss">
.el-header {
  background-color: #048bd1;
  color: #333;
  line-height: 60px;
}

.el-aside {
  color: #333;
}
</style>

我这代码抄得有点问题,但是大致还能看看。

在views下新建user目录并添加List .vue和profile.vue:

<template>
<h1>UserList</h1>
</template>

<script>
export default {
  name: "List"
}
</script>

<style scoped>

</style>
<template>
<h1>Profile</h1>
</template>

<script>
export default {
  name: "Profile"
}
</script>

<style scoped>

</style>
image-20200923110940907

配置路由组件router/index.js:

import List from "../views/user/List";
import Profile from "../views/user/Profile";
...
export default new VueRouter({
  routes: [
    {
      path: '/login',
      component: Login
    },
    {
      path: '/main',
      component: Main,//嵌套路由
      children: [
        {
          path: '/user/profile',
          component: Profile
        },
        {
          path: '/user/list',
          component: List
        }
      ]
    }
  ]
});

测试:

vue-router-elementui-childrouter

参数传递及重定向

个人信息页面应该因人而异。

修改Main.vue的个人信息的<router-link>:

<router-link :to="{name:'UserProfile',params: {id: 1}}">个人信息</router-link>

这里的name是路由配置router/index.js中添加的name:

        {
          path: '/user/profile/:id',
          name: 'UserProfile',
          component: Profile
        }

Profile.vue展示这个数字:

<template>
<!--  Component template should contain exactly one root element.-->
  <div>
    <h1>Profile</h1>
    {{$route.params.id}}
  </div>
</template>

还可以通过props达到目的

关于重定向:

<el-menu-item index="1-3">
  <router-link to="/goHome">GoHOME</router-link>
</el-menu-item>

编辑路由配置index.js:

routes: [
    {
      path: '/login',
      component: Login
    },
    {
      path: '/main',
      component: Main,//嵌套路由
      children: [
        {
          path: '/user/profile/:id',
          name: 'UserProfile',
          component: Profile
        },
        {
          path: '/user/list',
          component: List
        },
        {
          path: '/goHome',
          redirect: '/main'
        }
      ]
    }
  ]

通过redirect进行即可,结果:

vue-router-redirect

比如,我们登录之后需要把用户名展示在页面,我们可以这样。

将用户名放在main路径之后:

修改Login.vue

            //使用 vue-router路由到指定页面,该方式称之为编程式导航
            this.$router.push("/main" + "/" + this.form.username);

修改index.js:

      path: '/main/:name',
      component: Main,//嵌套路由
      props: true,
      children: [
          ...

修改Main.vue,展示用户名:

<span>{{name}}</span>
...
export default {
  props: ['name'],
  name: "Main"
}

运行:

vue-router-username

如何去除访问路径中的‘#’?

编辑路由配置文件:

export default new VueRouter({
  mode: 'history',//hash
  ...

将模式修改为'history'即可。

404

如何统一展示404?

在views下新建NotFound.vue:

<template>
<div>
  <h1>404,Not Found</h1>
</div>
</template>

<script>
export default {
  name: "NotFound"
}
</script>

<style scoped>

</style>

在路由配置中添加该组件:

import NotFound from "../views/NotFound";

同时配置路径:

  routes: [
    {
      path: '/login',
      component: Login
    },
      ...
    {
      path: '*',
      component: NotFound
    }
  ]

测试:

vue-router-404

此外,Vue还提供了各种钩子回调:

export default {
  name: "Profile",
  beforeRouteEnter: (to, from, next) => {
    console.log("进入路由之前");
    next();
  },
  beforeRouteLeave: (to, from, next) => {
    console.log("进入路由之后");
    next();
  }
}

到时候可以再看。

参考

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