vue 基础(七)

Vue组件基础和Ref对象

组件

概念: 组件系统是 Vue 的一个重要概念,Vue允许我们将代码拆分独立成一些将小型的可复用模块。这些模块就被成为组件,使用这些组件就可以构建一个大型项目。在Vue中组件分为全局组件私有组件

组件的创建

  • 全局组件

概念: 注册在Vue构造函数中的组件,在Vue实例任何地方任何组件中都可以使用

语法: Vue.component('组件名', {组件的配置对象})

<div id="app">
        <gec-title></gec-title>
</div>

<script>
        //全局组件,使用Vue构造函数提供的component API添加在构造函数中,在Vue实例对象的任何地方都可以使用.\
        Vue.component('gec-title', {
            // 这里的配置选项与Vue实例对象的配置选项(除了没有el以外)基本相同
            // template 模板配置选项,Vue实例配置选项中也有此选项
            // 当前组件/vue实例渲染在页面中的DOM模板
            template: `
            <div>
                <h2>{{12 + 8}}</h2>
                我是组件gec-title的模板
            </div>
            `
        })

        new Vue({
            el: '#app'
        })
</script>
  • 私有组件

概念: 通过components配置选项注册在Vue实例对象或其他子组件内部,只能在注册的父组件内部使用。

语法: Vue配置选项和组件配置选项都支持components属性 components: {组件名: { 组件配置选项 }}

<div id="app">
        <gec-title></gec-title>
        <component-a></component-a>
</div>

<script>
        //全局组件,使用Vue构造函数提供的component API添加在构造函数中,在Vue实例对象的任何地方都可以使用.\
        Vue.component('gec-title', {
            // 这里的配置选项与Vue实例对象的配置选项(除了没有el以外)基本相同
            // template 模板配置选项,Vue实例配置选项中也有此选项
            // 当前组件/vue实例渲染在页面中的DOM模板
            template: `
            <div>
                <h2>{{12 + 8}}</h2>
                我是组件gec-title的模板
            </div>
            `
        })

        new Vue({
            el: '#app',
            components: {
                // 在Vue实例中注册的局部组件 'component-a',只能在Vue的实例对象中使用
                'component-a': {
                    template: `
                    <div>
                        <h3>我是组件A</h3>
                        <child-a></child-a>
                        <gec-title/>
                    </div>
                    `,
                    components: {
                        // 在组件'component-a'中注册的局部组件,该组件只能在组件'component-a'中使用
                        'child-a': {
                            template: '<h2>我是组件A的子组件childA</h2>'
                        }

                    }
                }

            }
        })
</script>

注意: template属性指定DOM模板结构中必须有且仅有一个根DOM元素!

组件的data配置选项

概念: 组件设计初衷就是将哪些独立的可复用的代码块封装起来,因为对象是引用数据类型如果直接将组件的data属性设置为对象的话。同一个组件在复用时会导致多个组件同时读写同一个对象,严重的影响了组件可复用性和独立性。为了解决这个问题Vue明确规定组件的data不可以是个对象,而是一个返回data对象的工厂模式函数。

语法:

// 普通函数
  Vue.component('gec-title', {
            template: `
            <div>
                <h2>{{name}}</h2>
            </div>
            `,
            data() {
                return {
                    name: '小明',
                    age: 18
                }
            }
        })
 // 箭头函数
 Vue.component('gec-title', {
            template: `
            <div>
                <h2>{{name}}</h2>
            </div>
            `,
            data: () => ({
                    name: '小明',
                    age: 18
                })
        })

单项数据流

概念: 在Vue中组件之间是单项数据流的。单项数据流规定子组件不可以直接访问父组件的数据,只能通过props属性让父组件把数据传递给子组件。并且子组件不可以直接修改父组件传递给子组件的数据

props的使用

概念: 组件可以通过特殊的配置选项props给自身设置自定义属性,父组件就可通过props属性传值将父组件的数据传递给子组件,因为Vue是单项数据流子组件不可以修改props(props是只读的)

注意:组件的data属性与props属性不能同名

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <div id="app">
        <h2>{{age}}</h2>
        <my-label v-bind:a="age" b="hello" :c="age >= 18?'已成年':'未成年'"/>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                age: 15
            },
            components: {
                'my-label': {
                    // 给当前my-label设置了三个自定义属性a b c
                    // 组件组件自身就可以通过 this.props.a 
                    props: ['a','b','c'],
                    data: () => ({
                        name: 'my-label'
                    }),
                    template: `
                    <div> 
                        <p>a:{{a}}</p>
                        <p>b:{{b}}</p>
                        <p>c:{{c}}</p>
                        <child-a v-bind:name="name" :rootage="a"></child-a>
                    </div>    
                    `,
                    components: {
                        'child-a': {
                            props: ['name','rootage'],
                            template: '<div>我是childA 父组件的name为{{name}} rootAge{{rootage}}</div>'
                        }
                    }
                }
            }
        })
    </script>

反向传值

因为Vue是单项数据流的,规定只允许父组件向子组件传递状态,而不允许子组件直接修改父组件传递过来的状态。Vue提供了自定义事件API,通过父组件监听子组件自定义事件, 当子组件想要修改父组件的状态时会通过 $emit 方法触发自定义事件。父组件对应监听子组件自定义事件的回调函数就会被触发,这样父组件自身的方法就会相应的去修改自身的状态。子组件的props就会更新

语法: $emit('自定义事件名', 向父组件回调函数传递参数)

注意: $emit只接受两个参数,参数一触发父组件监听的指定事件名,参数二(可选)向父组件监听事件回调函数传递的数据

案例: $emit的使用

 <div id="father">
        <child :zfb="money" @call="callHandel"/>
    </div>

    <script>
        new Vue({
            el:'#father',
            data: {
                money: 1500
            },
            methods: {
                callHandel() {
                    console.log('儿子给我打电话了,说钱不够花')
                    this.money += 500
                }
            },
            components: {
                'child': {
                    props: ['zfb'],
                    template: `
                    <div>
                        父亲通过支付宝转生活费额度:{{zfb}}
                        <button @click="$emit('call')">向父亲打电话</button>
                    </div>
                `
                },
               
            }
        }) 

    </script>

Vue脚手架安装使用

  • Step1 在系统变量中安装Vue脚手架工具vue-cli
#全局安装vue-cli环境配置
npm install -g @vue/cli

[图片上传失败...(image-f5a03d-1623249421811)]

  • Step2访问到指定目录,使用vue指令创建新项目
#全局安装完毕后,以后 vue create 项目名称 搭建项目
vue create project_name   

[图片上传失败...(image-3c5470-1623249421811)]

  • Step3执行创建vue项目指令时会返回一个vue项目配置询问,先直接使用默认vue 2.0 模板
? Please pick a preset: (Use arrow keys)
> Default ([Vue 2] babel, eslint) #使用默认vue 2.0 模板
  Default (Vue 3 Preview) ([Vue 3] babel, eslint) #使用默认vue 3.0 模板
  Manually select features      #自定义模板

[图片上传失败...(image-58dc1f-1623249421811)]

  • Step4 安装完毕后
# 访问新创建的项目目录
cd project_name
#启动测试用服务开发指令
npm run serve
#项目开发完毕打包指令
npm run build

Vue-cli项目结构

<pre>
webpack-demo
|- /public // 公共目录,这个目录中的文件不会被webpack打包而是作为一个静态目录
// 放置在 public 目录下或通过绝对路径被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。
|- index.html // vue中 html模板文件
|- /src // 整个项目代码开发目录
|- main.js // 项目的入口文件
|- babel.config.js // webpack babel-loader配置文件
|- package.json // 项目的配置描述文件
|- README.md // 项目的readme文件
+|- vue.config.js // 可自定义Vue webpack相关配置的文件
</pre>

局部关闭 ESlint 校检

ESlint 是一个js代码检测工具,约束开发人员的代码风格,如果想具体了解,请查阅其文档

相关文档: https://blog.csdn.net/qq_39557024/article/details/107519531

public 文件夹

概念: 任何放置在 public 文件夹的静态资源都会被简单的复制,而不经过 webpack。你需要通过绝对路径来引用它们。

注意: 我们推荐将资源作为你的模块依赖图的一部分导入,这样它们会通过 webpack 的处理并获得如下好处:

  • 脚本和样式表会被压缩且打包在一起,从而避免额外的网络请求。

  • 文件丢失会直接在编译时报错,而不是到了用户端才产生 404 错误。

  • 最终生成的文件名包含了内容哈希,因此你不必担心浏览器会缓存它们的老版本。

public 目录提供的是一个应急手段,当你通过绝对路径引用它时,留意应用将会部署到哪里。如果你的应用没有部署在域名的根部,那么你需要为你的 URL 配置 publicPath 前缀,在 public/index.html 或其它通过 html-webpack-plugin 用作模板的 HTML 文件中,你需要通过 <%= BASE_URL %> 设置链接前缀:

<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="<%= BASE_URL %>css/style.css">

在js文件中 使用process.env.BASE_URL作为pubulic文件的前缀

<template>
  <div id="app">
    // 直接引入静态目录中的文件
    <img alt="Vue logo" :src="`${publicPath}imgs/01.jpg`">
    // 相对路径的引入会导致webpack对该文件进行打包
    <img alt="Vue logo" src="../public/imgs/01.jpg">

  </div>
</template>

<script>

export default {
  name: 'App',
  data() {
    return {
       // 获取公共目录路径
      publicPath: process.env.BASE_URL
    }
  }
}
</script>

publicPath配置实在项目的根目录下vue.config.js中设置publicPath选项就好了

module.exports = {
    publicPath: process.env.NODE_ENV === 'production'
      ? '/production-sub-path/' //真实开发的话,如果你的项目存放在公司域名二级路径下 只需要将 /production-sub-path/改为 /公司二级路径/就可以了
      : '/'
  }

webpack 相关(了解)

介绍: 在vue-cli中简单的配置webpack方式就是在Vue项目的根目录下创建vue.config.js文件。这个通过配置这个文件中 module.exports 公开的对象实现对Vue Webpack进行修改。

  1. 指定项目静态资源模块的相对路径
  2. 指定打包后文件的目录(默认dist文件)
  3. assets文件的目录
  4. 多页面应用开发
  5. css模块化 loader等
  6. 给项目添加Webpack plugin
  7. 配置当前项目的开发测试服务器
// vue.config.js
module.exports = {
    publicPath: process.env.NODE_ENV === 'production'
        ? '/production-sub-path/' //真实开发的话,如果你的项目存放在公司域名二级路径下 只需要将 /production-sub-path/改为 /公司二级路径/就可以了
        : '/',
    devServer: { // 服务器代理,当请求了代理设置的路径时 会自动跳转到指定服务器上,解决跨域问题
        proxy: {
            "/search": {
                target: 'http://musicapi.leanapp.cn/',
                changeOrigin: true
                // 当你请求 /search?123123 时 会代理到 'http://musicapi.leanapp.cn/search?123123'
            }
        }
    }
}

了解Vue-cli src目录结构

介绍: 在src文件中main.js是整个项目的入口文件,也是实例化Vue对象的地方

因为vue-cli是模块化开发,所以整个项目不适用< script >标签引入Vue支持而是使用模块化依赖模式通过import引入Vue对象

import Vue from 'vue'
import App from './App.vue' // 引入单文件App组件

Vue.config.productionTip = false
// 实例化Vue
new Vue({
  render: h => h(App)  
  // render是template字符串模板的替代方案,render是一个函数函数接收一个参数(createElement)
  // 这个参数可以将组件生成为一个Vue DOM节点渲染在页面上
  // 所以上面这句化等价于 template: '<App></App>' 
}).$mount('#app')

// 如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。
// 这时可以使用 vm.$mount() 手动地挂载一个未挂载的实例。

认识单文件组件

我们观察下面的代码,在Vue实例中添加了局部组件App,如果说除了Vue实例以外其他组件可能也需要注册App局部组件的话。我们推荐将App抽离出来提供给其他组件复用

new Vue({
    el: '#app',
    components: {
        App: {
            props: ['name','age'],
            data() {
                return {
                    address: 'bj'
                }
            },
            template: `
            <div>
                <h2>用户:{{name}} 年龄:{{age}}</h2>
                <p>地址:{{address}}</p>   
            </div>
            `
        }
    }
})

抽离后

const App = {
    props: ['name','age'],
    data() {
        return {
            address: 'bj'
        }
    },
    template: `
    <div>
        <h2>用户:{{name}} 年龄:{{age}}</h2>
        <p>地址:{{address}}</p>   
    </div>
    `
}


new Vue({
    el: '#app',
    components: {
        App
    }
})

我们在开发中推荐使用模块化开发,建议将每个可复用的组件单独封装成一个js模块,通过import引入其他文件中复用。这样的好处是便于维护更新让项目的结构更明确。

// 将App组件封装成一个js模块
// App.js
export default {
    props: ['name','age'],
    data() {
        return {
            address: 'bj'
        }
    },
    template: `
    <div>
        <h2>用户:{{name}} 年龄:{{age}}</h2>
        <p>地址:{{address}}</p>   
    </div>
    `
}

// 其他组件或实例注册App组件
import App from './App'

new Vue({
    el: '#app',
    components: {
        App
    }
})

Vue为了简化template字符串模板的开发(使用字符串写HTML语法js无法格式化代码,编译器无法对模板进行补全和检查),Vue提供了一个.vue文件简化了js文件创建单文件组件时template字符串模板开发不便。.vue文件单独的将template选项抽离出来以HTML的形式进行开发。

上面的App.js就可以转化为:

// App.vue
// template 被抽离出来变成了一个独立的标签,内部本来使用字符串模板代码变成HTML语法
<template>
  <div>
    <h2>用户:{{name}} 年龄:{{age}}</h2>
    <p>地址:{{address}}</p>
  </div>
</template>

<script>
export default {
  props: ["name", "age"],
  data() {
    return {
      address: "bj",
    }
  }
}
</script>

注意

  1. .vue文件不仅支持template标签指定组件的模板样式和script 公开当前模板配置选项,还支持style标签内置的设置当前组件的样式,而且style标签支持使用sass\less\stylus预编译语言
<template>
  <div class="demo">
      我是Demo,在vue文件中 
<!-- template内部遵循XML语法规则,所有单一型标签后面一定要跟一个/,并且template标签内部有且仅有一个根元素 -->
      <input/>
  </div>
</template>

<script>
export default {};
</script>
<!--
style有两个可选属性 
    lang="scss" 内部使用sass语法,项目要额外安装 sass-loader  
    lang="less" 内部使用less语法,项目要额外安装 less-loader  
    lang="stylus" 内部使用less语法,项目要额外安装 stylus-loader 
    不设置该属性则使用css
    scoped 样式私有化,如果设置了该属性,style标签内的所有样式只会对组件自身有效
-->
<style lang="less" scoped>
.demo {
    color: green;
}
</style>
  1. 建议使用.vue创建组件时,组件名与文件名一致并且使用每个单词首字母大写的命名方法。例: HelloWorld.vue、DemoComponent.vue

Props验证

概念:在开发中我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这一模式会在开发中帮开发人员捕获大量的异常。

语法: props可以是一个数组,数组中的每一项都是当前组件的props属性名。props属性还是是一个对象为每个指定的props属性指定其验证规则以及默认值

props: {
        // 当前组件的propsA属性必须是Number数据类型或者为空(可忽略)
        propA: Number, 
        // propB与propA等价
        // prop为指定数据类型只需要设置该属性type值为对应数据类型的构造函数
        propB: {
            type: Number
        },
        // prop属性可以设置为必要属性,渲染该组件时必须给该属性传值并且不可为空
        propC: {
            type: Number,
            required: true 
        },
        // prop属性支持默认值,当没有给该prop传递属性是,该属性则会使用默认值
        // 注意: 默认值优先级小于required
        propD: {
            type:Number,
            default: 15
        },
        propE: {
          type: Object,
          // 对象或数组默认值必须从一个工厂函数获取
          default: function () {
            return { message: 'hello' }
          }
        }
    }

Props验证规则

 props: {
        // 通过构造函数指定prop数据类型
        propA: Number,
        propB: Boolean,
        propC: String,
        propD: Array,
        propE: Object,
        propF: Symbol,
        propG: RegExp,
        propH: Date,
        propI: Cat, // 可以指定任何构造函数作为prop的type,当前prop接收到的值必须是当前指定构造函数的实例对象
        propJ: Function
        // prop验证支持 多个可能的类型
        propK: [String, Number], 
        // 自定义验证规则,不满足验证条件是return false
        propL: {
          validator(val) {// val 传入到 propL属性的值
            if (typeof val === "string") {
              if (/fuck/gi.test(val)) {
                console.error("组件ComponentA中 属性 PropL包含敏感词汇!");
              } else {
                return true;
              }
            } else {
              console.error("数据必须是字符串");
            }
            return false;
          }
        }
    }

动态组件

概念: VUe 提供了一个标签component,该标签可以使用 is attribute 来切换不同的组件:

<div id="app">
        <component :is="`my-${name}`"></component>
     
        <button @click="name ='a'">a</button>
        <button @click="name ='b'">b</button>
    </div>

    <script>
         new Vue({
             el: '#app',
             data: {
                 name: 'a'
             },
             components: {
                 'my-a': {
                     template: '<h2>我的组件A</h2>'
                 },
                 'my-b': {
                     template: '<h2 @click="num++">组件B{{num}}</h2>',
                     data() {
                         return {num: 7}
                     }
                 },
             }
         })   

 </script>

在动态组件上使用 keep-alive

概念: 当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。

 <div id="app">
        <!-- 失活的组件将会被缓存!-->
        <keep-alive>
            <component :is="`my-${name}`"></component>
        </keep-alive>
       
        <button @click="name ='a'">a</button>
        <button @click="name ='b'">b</button>
    </div>

    <script>
         new Vue({
             el: '#app',
             data: {
                 name: 'a'
             },
             components: {
                 'my-a': {
                     template: '<h2>我的组件A</h2>'
                 },
                 'my-b': {
                     template: '<h2 @click="num++">组件B{{num}}</h2>',
                     data() {
                         return {num: 7}
                     }
                 },
             }
         })   

    </script>

注意: 在上面的案例中如果没有使用keep-alive缓存失活的组件,那么失活的组件将被丢弃(卸载),组件切换时每次都是挂载一个全新的组件

异步组件(了解)

介绍: 在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。例如:

Vue.component('async-example', function (resolve, reject) {
 setTimeout(function () {
   // 向 `resolve` 回调传递组件定义
   resolve({
     template: '<div>I am async!</div>'
   })
 }, 1000)
})

如你所见,这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:

Vue.component('async-webpack-example', function (resolve) {
 // 这个特殊的 `require` 语法将会告诉 webpack
 // 自动将你的构建代码切割成多个包,这些包
 // 会通过 Ajax 请求加载
 require(['./my-async-component'], resolve)
})

你也可以在工厂函数中返回一个 Promise,所以把 webpack 2 和 ES2015 语法加在一起,我们可以这样使用动态导入:

Vue.component(
   'async-webpack-example',
  // 这个动态导入会返回一个 `Promise` 对象。
  () => import('./my-async-component')
)

当使用局部注册的时候,你也可以直接提供一个返回 Promise 的函数:

new Vue({
 // ...
 components: {
   'my-component': () => import('./my-async-component')
 }
})

如果你是一个 Browserify 用户同时喜欢使用异步组件,很不幸这个工具的作者明确表示异步加载“并不会被 Browserify 支持”,至少官方不会。Browserify 社区已经找到了一些变通方案,这些方案可能会对已存在的复杂应用有帮助。对于其它的场景,我们推荐直接使用 webpack,以拥有内置的头等异步支持。

懒加载状态 (2.3.0+ 新增)

这里的异步组件工厂函数也可以返回一个如下格式的对象:

const AsyncComponent = () => ({
 // 需要加载的组件 (应该是一个 `Promise` 对象)
 component: import('./MyComponent.vue'),
 // 异步组件加载时使用的组件
 loading: LoadingComponent,
 // 加载失败时使用的组件
 error: ErrorComponent,
 // 展示加载时组件的延时时间。默认值是 200 (毫秒)
 delay: 200,
 // 如果提供了超时时间且组件加载也超时了,
 // 则使用加载失败时使用的组件。默认值是:`Infinity`
 timeout: 3000
})

Ref

概念: Vue给组件元素提供了一个ref属性,绑定了ref属性的组件元素可以在当前vue实例对象中通过$refs访问其真实DOM节点(标签元素)或实例对象(组件)。

在原生html标签中使用ref

语法: <div ref="变量名"></div> 当前组件内部 this.$refs.变量名 访问其真实DOM节点

 <div id="app">
        <audio ref="myAudio" src="./药水歌.mp3" controls></audio>
        <button @click="showAudio">show</button>
 </div>   
 
<script>
 new Vue({
     el: '#app',
     methods: {
         showAudio() {
             console.log(this.$refs.myAudio)
         }           
    }
})
</script>  

在组件中中使用ref

语法<MyComponent ref="变量名" /> 当前组件内部 this.$refs.变量名 访问这个子组件的实例对象,可以获取这个组件实例的属性和方法(尽量避免使用该模式,因为他会增加组件间的耦合性)

<template>
    <Demo ref="myDemo" />
</template>

<script>
import Demo from './components/Demo'

export default {
  name: 'App',

  methods: {
    show() {
      // 子组件Demo的方法在父组件中被调用了
      this.$refs.myDemo.sayHello()
    }
  },
  components: {
    Demo
  }
}
</script>

注意:

  1. vue实例中每个标签或组件都可以设置ref属性,绑定了ref属性的元素可以有任意个
<div id="app">
        <audio ref="myAudio" src="./药水歌.mp3" controls></audio>
        <button ref="myBtn" @click="showAudio">show</button>
        <p ref="textEl">text</p>
 </div>  
 // 这时可以在组件中通过 this.$refs不同的变量名访问对应的DOM元素 
  1. ref配合列表渲染(v-for)使用时,$refs返回值为包含列表渲染出来的所有元素的一个数组
    <div id="app">
       // 与v-for同级的ref 返回值都是列表渲染出来当前元素数组集合
        <p v-for="num in arr" :key="num" ref="numList">
        //v-for 内部的ref 返回值也是列表渲染出来当前元素数组集合
            <span ref="spanList">{{num}}-span</span>
            <a>没用的a</a>
            {{num}}
        </p>
        <button @click="showRefList">click</button>
    </div>

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

推荐阅读更多精彩内容

  • Vue -渐进式JavaScript框架 介绍 vue 中文网 vue github Vue.js 是一套构建用户...
    桂_3d6b阅读 826评论 0 0
  • 相关概念 混合开发和前后端分离 混合开发(服务器端渲染) 前后端分离后端提供接口,前端开发界面效果(专注于用户的交...
    他爱在黑暗中漫游阅读 2,794评论 4 45
  • Vue.js - Day5 - Webpack 在网页中会引用哪些常见的静态资源? JS .js .jsx ....
    折枝赠远方阅读 403评论 0 0
  • 生命周期函数 组件挂载以及组件更新、组件销毁的一系列的方法。这些方法就叫做生命周期函数。 其中函数有: befor...
    Zola_4f36阅读 1,244评论 0 0
  • 一、 vue的基础用法 二、父子组件传值(父传子) 1.父传子的时候通过属性传递 2.子要声明props:["属性...
    江南之城阅读 482评论 0 2