美文网首页
Vue学习日记

Vue学习日记

作者: 好一只帅卤蛋 | 来源:发表于2019-07-24 16:33 被阅读0次

    Vue官方文档
    以下内容作为本人日常学习使用,不作为参考

    一、Vue环境搭建以及vue-cli的使用

    Vue多页面应用文件引用

    直接用 <script> 引入
    · 对于制作原型或学习,你可以这样使用:
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    · npm进行安装
    npm install vue

    vue-cli构建SPA应用

    · npm install -g vue-cli 全局安装vue-cli
    · vue init webpack-simple demo demo是项目名字(简单)
    · vue init webpack demo demo是项目名字(详细)
    构建完成后 npm install
    通过npm run dev开始项目

    二、 网页怎么在浏览器上显示

    natapp 映射到公网
    浏览器默认端口号 80 端口
    telnet 判断端口是否开启
    http://192.18.0.20:3000/index.html 请求协议+sourceIP+目标端口+请求路径
    SEO
    VUE:
    基本用法:网址上自己看
    路由用法:可以自己定义,也可以VueRouter
    状态管理:Vuex
    服务端渲染:nuxt

    三、利用写好的打包工具生成目录

    build —— 打包的配置文件所在的文件夹
    config —— 打包的配置 webpack
    src —— 开发源码 .vue都是入口文件
    static —— 静态资源文件
    .babelrc —— 项目的配置文件,解析例如es6等等
    .gitignore —— 忽略我们git提交的配置
    .postcssrc.js —— HTML添加前缀的配置
    index.html —— 单页面应用程序入口文件
    package.json —— 项目的基础信息和引用的依赖dependencies(本身依赖) devDependencies(开发依赖)

    • src文件夹中的main.js中的new的vue实例就是整个项目的入口,el中的#app监听对象区域(也可以在实例末尾 .$mount("#app") ),router是路由,component是组件,template是模板( 也可以在实例内部 render:h=>h(App) )

    • src 文件夹中的assets文件夹放的也是静态资源,不过更偏向于组件的静态资源

    • 在src中新建一个views文件夹当作页面文件夹,新建 页面名.vue,内容和引用格式大概如下

    <template>
     <div>
      <h1>里面是页面的内容</h1>
      <nav-footer>组件</nav-footer>
      </div>
    </template>
    
    <script>
    import 'css文件地址'
    import 组件名 from '组件地址xx/xx/xx.vue'
    export default {
      data(){
        return {
        }
      },
      components:{
         组件名(上面引用的时候要小写NavFooter=><nav-footer></nav-footer>)
       },
     methods: {
        jump: function() {
         // this.$router.push({ path: "/cart?goodsId=123" // });
         this.$router.go(-2);
        }
      }
    }
    </script>
    

    然后在router中的index.js中渲染出来

    import Goodlist from './../views/页面名'
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/good',
          name: 'Goodlist',
          component: Goodlist
        }
      ]
    })
    
    

    其实配置主要就是build的webpack.base.conf.js和config里面的配置文件 其他就是一些辅助工具

    四、Vue基础语法介绍

    .vue文件中template下面必须有一个根元素<div></div>

    模板语法

    · Mustache语法:{{ msg }}
    · Html赋值:v-html=""
    · 绑定属性:v-bind:id=""
    · 使用表达式:{{ ok ? 'YES' : 'NO'}}
    · 文本赋值:v-text=""
    · 指令:v-if=""
    · 过滤器:{{ message | capitalize}} 和 v-bind:id="rawId | formatId"

    Class和Style绑定

    · 对象语法:v-bind:class="{ active:isActive , 'text-danger' : hasError}"
    · 数组语法:<div v-bind:class="[ activeClass , errorClass]" > data : { activeClass : 'active' , errorClass:'text-danger' }
    · style绑定-对象语法:v-bind:style="{ color : activeColor , fontSize : fontSize + 'px' }"

    条件渲染

    · v-if
    · v-else
    · v-else-if
    · v-show
    · v-clock //会隐藏

    vue事件处理器

    · v-on:click="greet"或者@click="greet"
    · v-on:click.stop(阻止按钮默认事件<a>) 、 v-on:click.prevent(点击后失效)、 v-on:click.self(给绑定事件的本身绑定事件)、 v-on:click.once(绑定事件只生效一次)
    · v-on:keyup.enter ( 修饰符 .tab .delete捕获删除和退格键 .esc .spave .up .down .left .right) (搜索回车判断等等)

    vue组件

    • 全局组件和局部组件
    • 父子组件通讯-数据传递 parent--->child(Pass Props) child--->parent(Emit Events)
    • Slot插槽
      在组件中添加
    <solt name="插槽名"></slot>
    

    在页面中引用的组件中使用插槽

    <nav-footer>
    <span slot="插槽名">想要插入的内容</span>
    </nav-footer>
    

    关于Vue指令的详细介绍

    来源一个简书的万字介绍

    4.️1 v-text

    说明: 文本数据渲染
    用法:v-text = "Vue实例中的数据" => 简写 {{Vue实例中的数据}}

    相当于JavaScript中的innerText

    4.️1.️2 v-text指令 和 {{ }}插值表达式 的区别

    • v-text 会直接替换元素中的所有内容
    • {{ }} 只会替换插值表达式中的占位符

    4.️2 v-html

    说明: HTML渲染数据
    用法:v-html = "Vue实例中的数据"
    会解析html结构 渲染至页面

    相当于JavaScript中的innerHTML

    4.️2.️1 v-html指令 和 v-text指令的区别

    • v-html 会将数据解析成html 渲染至页面
    • v-text 只会输出成文本(字符串形式)

    注意: 在网站上动态渲染任意的 HTML 是非常危险的!!! 因为容易导致 XSS 攻击 只在可信内容上使用 v-html 绝对不要用在用户通过(提交)的内容上使用

    4.️3 v-on

    说明: 事件绑定(绑定事件监听器)
    用法: v-on:事件名 = "事件处理函数" => 简写 @事件名 = "事件处理函数"

    4.️3.️1 详细用法

    • @事件名.修饰符 = "事件处理函数"
    • 逻辑比较少的可以直接写在行内
    • 逻辑较多的写到 methods 中 注意: 操作Vue实例上的数据要跟上 this
    • 可以通过实参传递($event) 获取事件参数e
    1. $event.target获取当前事件触发的DOM元素
    2. $event.path[0](el.path[0])也可以获取当前事件触发的DOM元素 path数组中有从触发事件源的元素的所有上一级元素 直到window
    3. 实参不传递(没有任何参数) 默认在形参中第一个就是事件参数
      实参传递 就必须传递$event 来获取获取事件参数

    4.️3.️2 事件修饰符

    • .stop
      阻止事件冒泡
    • .prevent
      阻止事件默认行为
    • .once
      只触发一次回调
    • .native
      监听组件根元素的原生事件
      很重要!有些第三方组件可能内部并没有设置原生的事件 就可以通过.native来触发事件
    面试问及

    之前在使用饿了么UI的时候给一个组件添加一个原生的事件
    但是一直触发不了
    后面查阅文档发现这个组件内部并没有注册我使用的原生事件
    事件修饰符.native就可以直接监听并触发组件的原生事件

    • .capture
      添加事件侦听器时使用 capture 模式
    • .{keyCode | keyAlias}
      只当事件是从特定键触发时才触发回调
    • .left
      (2.2.0版本) 只当点击鼠标左键时才触发
    • .right
      (2.2.0版本) 只当点击鼠标右键时才触发
    • .middle
      (2.2.0版本) 只当点击鼠标中键时才触发
    • .self
      只当事件使用侦听器绑定的元素本身触发时才触发回调
    • .passive
      (2.3.0版本)以{ passive:true } 模式添加侦听器

    4.️4 v-bind

    说明: 属性绑定(行内属性)
    用法: v-bind:属性名="Vue实例中的数据" => 简写 :属性名="Vue实例中的数据"
    当Vue实例中的数据改变之后 页面会同步更新

    4.️4.1 属性绑定修饰符

    • .prop
      被用于绑定 DOM 属性 (property)
    • .camel
      (2.1.0+) 将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持)
    • .sync
      (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器

    4.️4.2 对象的方式绑定class

    • :class = "{'red' : isRed}"

    isRed = true 就有red这个类
    isRed = false 就没有red这个类
    isRed 在 Vue 实例data中声明

    • 默认的class 和 :class(绑定的class) 一起使用不会冲突 后面的会作为追加或者移除来解析

    class = "red" :class = "{'yellow' : isYellow}"

    4.️4.3 对象的方式绑定style

    • :style = "{fontSize : mySize + 'px'}"
    • 样式名需要使用驼峰命名法
    • 后面的mySize需要在Vue实例data中定义

    4.️5 v-model

    说明: 双向数据绑定
    用法:v-model = "Vue实例中的数据"

    4.️5.️1 双向

    • 视图层
    • 数据层
      数据能够自动的从内存中显示到页面上去

    4.️5.️2 双向绑定修饰符

    v.lazy
    懒载入 当表单属性失去光标或按下回车键后 再将页面中的数据和Vue实例中的数据双向绑定
    v.trim
    输入的数据首位空格过滤

    • .number
      输入字符串转为有效的数字

    注意: v-model 只能设置给from表单属性

    4.️6 v-for

    说明: 循环渲染
    用法: v-for = "(item,index) in items" :key = "index"

    items是源数据数组
    item是被迭代的数组元素的别名
    index是被迭代的数组元素的下标(索引)

    4.️6.️1 :key

    • 数据唯一标识绑定
    • v-for默认行为试着不改变整体 而是替换元素 迫使其重新排序的元素需要提供一个key(用户删除数据后 数据需重新排列序号 就可以使用key来实现)
    • 数据实现重用和重新排序现有的元素
    • s值最好为字符串或数值类型(唯一的)

    4.️6.️2 遍历数组注意点

    • Vue本身只是监视了Vue实例Data中数组的改变(监视内存地址) 没有监视数组内部数据的改变
    • (变异方法)Vue重写了数组中的一系列改变数组内部数据的方法(先调用原生的方法 再更新页面) 所以实现了使用数组提供的方法 数组内部改变 界面自动改变

    push()
    pop()
    shift()
    unshift()
    splice()
    sort()
    reverse()
    ...

    this.arr[index] = 新值
    `

    这种修改数组中的元素是无法实现数据改变后页面会同步改变(只会修改data中的数据 但是页面不会同步改变)

    splice()的增删改
    增 this.arr.splice(index,0,新值)
    删 this.arr.splice(index,1)
    改 this.arr.splice(index,1,新值)
    

    4.️7 v-if,v-else,v-else-if

    说明: 条件(表达式或布尔值)判断渲染
    用法:
    v-if = "表达式或布尔值"
    v-else-if = "表达式或布尔值"
    v-else

    4.️7.️1 注意

    v-if 和 v-else-if 后面必须跟表达式或布尔值
    v-else-if 和 v-else 不能独立使用 必须跟在 v-if 后面

    4.️8 v-show

    说明: 条件渲染
    用法:v-show = "表达式或布尔值"
    根据表达式或布尔值的真假切换元素的display属性

    4.️8.️1 注意

    v-show 不支持 <template>元素 也不支持 v-else

    4.️9 v-if vs v-show

    都是用来判断渲染数据的

    • v-if

    1.有较高的切换性能消耗
    2.惰性渲染 第一次如果条件为false 则不会渲染到页面 需要等后面条件切换后才会进行第一次渲染
    3.条件切换是切换DOM数中这个元素的移除或添加
    4.如果运行时条件很少改变则使用v-if

    • v-show

    1.有较高的初始渲染消耗
    2.初始渲染 不管条件 第一次加载页面的时候都会渲染到页面
    3.条件切换只是切换元素的display属性
    4.如果运行时条件会非常频繁的切换则使用v-show

    4.️️10 v-cloak

    说明: 这个指令保存在这个元素上 直到关联实例结束编译

    4.️️10.️1 详细说明

    插值表达式在网络较满的情况下可能会出现数据闪烁问题
    可以通过给实例(#app)盒子添加一个 v-cloak 指令
    通过这个指令的特性(如页面中还有插值表达式就会存在这个指令 如果页面的插值表达式都被替换成数据 就会自动移除这个标签)
    配合css [v-cloak]{display:none|opacity:0}来解决数据闪烁的问题
    某些元素只需要解析一次 后续不需要更新 就可以使用这个指令 提升性能

    五、vueRouter的介绍

    什么是前端路由

    路由是根据不同的url地址去展示不同的内容或页面
    前端路由就是把不同的路由对应不同的内容或者页面的任务交给前端来做,之前是通过服务端根据url的不同返回不同的页面实现的

    什么时候使用前端路由

    在单页面应用,大部分应用结构步变,只改变部分内容的使用

    前端路由有什么优点和缺点

    优点:用户体验好,不需要每次都从服务端全部获取,快速展现给用户
    缺点:不利于SEO(网站优化), 使用浏览器的前进后退的时候会重新发送请求,没有合理的利用缓存

    vue-router

    · vue-router用来构建SPA
    · <router-link></router-link>或者this.$router.push({path:"})
    · <router-view></router-view>

    实例

    1.动态路由匹配

    什么是动态路由

    我们经常需要将具有给定模式的路线映射到同一个组件。例如,我们可能有一个User应该为所有用户呈现但具有不同用户ID的组件。在vue-router我们可以在路径中使用动态段以实现(来自官方例子):

    const User = {
      template: '<div>User</div>'
    }
    
    const router = new VueRouter({
      routes: [
        // dynamic segments start with a colon
        { path: '/user/:id', component: User }
      ]
    })
    

    现在,网址喜欢/user/foo和/user/bar将映射到相同的路由。

    动态段由冒号表示:。匹配路径时,动态段的值将this.$route.params在每个组件中公开。因此,我们可以通过更新User模板来呈现当前用户ID :

    const User = {
      template: '<div>User {{ $route.params.id }}</div>'
    }
    

    可以在同一路线中拥有多个动态细分,它们将映射到相应的字段$route.params。例子:

    pattern matched path $route.params
    /user/:username /user/evan { username: 'evan' }
    /user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: '123' }

    下面是一个引用的例子
    index.js中

    import Vue from 'vue'
    import Router from 'vue-router'
    import Goodlist from './../views/Goodlist'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/good/:goodsId',
          name: 'Goodlist',
          component: Goodlist
        }
      ]
    })
    

    Goodlist.vue中引入

        <span>{{$route.params.goodsId}}</span>
    

    那么就可以获取到请求地址中的路径部分

    2.嵌套路由

    什么是嵌套路由

    就是路由里面嵌套路由
    在主路由下面有两个子路由,点击之后会在主路由的页面显示子路由的东西

    下面是一个例子:
    在新建的views文件夹中分别创建Image.vue文件和Title.vue文件
    在div标签中写入对他们的描述
    在index.js文件中引入子路由

    import Vue from 'vue'
    import Router from 'vue-router'
    import Goodlist from './../views/Goodlist'
    import Title from '@/views/Title'
    import Image from '@/views/Image'
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/good',
          name: 'Goodlist',
          component: Goodlist,
          children: [
            {
              path: 'title', // 不能加杠,子路由
              name: 'title',
              component: Title
            },
            {
              path: 'img', // 不能加杠,子路由
              name: 'img',
              component: Image
            }
          ]
        }
      ]
    })
    

    在上面的Goodlist文件中引入

    <template>
      <div>
        这个是列表
        <span>{{$route.params.goodsId}}</span>
        <router-link to="/good/title">显示标题</router-link>
        <router-link to="/good/img">显示图片</router-link>
        <div>
          <router-view></router-view>
        </div>
      </div>
    </template>
    

    3.编程式路由

    什么是编程式路由

    通过js来实现页面的跳转

    陈述 编程
    <router-link :to="..."> router.push(...)

    参数可以是字符串路径或位置描述符对象。例子:
    $router.push("name")
    $router.push(path:"name")
    $router.push({path:"name?a=123"}) 或者 $router.push({path:"name",query:{a:123}})
    $router.go //此方法采用单个整数作为参数,指示在历史堆栈中前进或后退的步数,类似于window.history.go(n)。
    注意:params如果path提供了a,则会被忽略,但不是这种情况query,如上例所示。相反,您需要提供name路由或path使用任何参数手动指定整个:

    const userId = '123'
    router.push({ name: 'user', params: { userId } }) // -> /user/123
    router.push({ path: `/user/${userId}` }) // -> /user/123
    // This will NOT work
    router.push({ path: '/user', params: { userId } }) // -> /user
    

    注意:如果目标与当前路由相同且只有params正在更改(例如,从一个配置文件转到另一个配置文件/users/1- > /users/2),则必须使用beforeRouteUpdate以对更改做出反应(例如,获取用户信息)。

    例子:
    在views文件夹中新建一个Cart.vue的文件,并且在div中说明这是一个购物车界面
    在index.js文件中引入主路由

    import Vue from 'vue'
    import Router from 'vue-router'
    import Goodlist from './../views/Goodlist'
    import cart from '@/views/Cart'
    Vue.use(Router)
    export default new Router({
      routes: [
        {
          path: '/good',
          name: 'Goodlist',
          component: Goodlist
        },
        {
          path: '/cart',
          component: cart
        }
      ]
    })
    

    重点在这里,在Goodlist文件中引入jump方法

    <template>
      <div>
        这个是列表
        <router-link to="/cart">跳转到购物车页面</router-link>
        <button @click="jump">button</button>
      </div>
    </template>
    
    <script>
    export default {
      methods: {
        jump: function() {
          // this.$router.push({ path: "/cart?goodsId=123" }); 在cart.vue中加入    <span>{{$route.query.goodsId}}</span>
          this.$router.go(-2);
        }
      }
    };
    </script>
    

    4.命名路由和命名视图

    什么是命名路由和命名视图

    给路由定义不同的名字,根据名字进行匹配
    给不同的router-view定义名字,通过名字进行对应组件的渲染

    例子:
    在index.js文件夹中将父子路由合并为命名视图

    routes: [
        // {
        //   path: '/good',
        //   name: 'Goodlist',
        //   component: Goodlist,
        //   children: [
        //     {
        //       path: 'title', // 不能加杠,子路由
        //       name: 'title',
        //       component: Title
        //     },
        //     {
        //       path: 'img', // 不能加杠,子路由
        //       name: 'img',
        //       component: Image
        //     }
    
        //   ]
        // },
    
        //命名视图写法
        {
          path: '/',
          name: 'Goodslist',
          components: {
            default: Goodlist,
            title: Title,
            img: Image
          }
    
        },
        {
          path: '/cart', // 不能加杠,子路由
          component: cart
        }
      ]
    

    在app.vue中引入

        <router-view name="title"></router-view>
        <router-view  name="img"></router-view>
    

    六、Vue-Resource基础

    vue-resource全攻略

    vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。另外,vue-resource还提供了非常有用的inteceptor功能,使用inteceptor可以在请求前和请求后附加一些行为,比如使用inteceptor在ajax请求时显示loading界面。

    特征

    • 支持Promise API和URI模板
    • 支持请求和响应的拦截器
    • 支持最新的Firefox,Chrome,Safari,Opera和IE9 +
    • 支持Vue 1.0和Vue 2.0
    • 紧凑尺寸14KB(压缩5.3KB)

    安装

    $ yarn add vue-resource
    $ npm install vue-resource
    

    提供的API

    vue-resource的请求API是按照REST风格设计的,它提供了7种请求API:

    • get(url , [options])
    • head(url , [options])
    • delete(url , [options])
    • jsonp(url , [options])
    • post(url , [body] , [options])
    • put(url , [body] , [options])
    • patch(url , [body] , [options])

    除了jsonp以外,另外6种的API名称是标准的HTTP方法。当服务端使用REST API时,客户端的编码风格和服务端的编码风格近乎一致,这可以减少前端和后端开发人员的沟通成本。

    options对象

    发送请求时的options选项对象包含以下属性:

    参数 类型 描述
    url string 请求的URL
    method string 请求的HTTP方法,例如:'GET', 'POST'或其他HTTP方法
    body Object, FormData string request body
    params Object 请求的URL参数对象
    headers Object request header
    timeout number 单位为毫秒的请求超时时间 (0 表示无超时时间)
    before function(request) 请求发送前的处理函数,类似于jQuery的beforeSend函数
    progress function(event) ProgressEvent回调处理函数
    credentials boolean 表示跨域请求时是否需要使用凭证
    emulateHTTP boolean 发送PUT, PATCH, DELETE请求时以HTTP POST的方式发送,并设置请求头的X-HTTP-Method-Override
    emulateJSON boolean 将request body以application/x-www-form-urlencoded content type发送

    全局拦截器interceptors

    Vue.http.interceptors.push((request, next) => {
            // ...
            // 请求发送前的处理逻辑
            // ...
        next((response) => {
            // ...
            // 请求发送后的处理逻辑
            // ...
            // 根据请求的状态,response参数会返回给successCallback或errorCallback
            return response
        })
    })
    
    来自于上面链接里面的图片

    在response返回给successCallback或errorCallback之前,你可以修改response中的内容,或做一些处理。
    例如,响应的状态码如果是404,你可以显示友好的404界面。

    七、模块化开发中AMD、CMD、CommonJs 和 ES6的对比

    什么是AMD、CMD、CommonJs

    • AMD是RequireJS在推广过程中对于模块定义的规范化产出,RequireJS全称是异步模块定义
    define( [ ' package/lib' ] , function(lib){
    function foo(){
     lib.log("hello world!"); 
    }
    return {
     foo:foo
    };
    });
    
    • CMD是SeaJS(淘宝团队)在推广过程中对于模块定义的规范化产出,SeaJS全称是同步模块定义
    // 所有模块都通过define来定义,即用即返回,所以是同步概念
    define(function(require , exports , module) {
    // 通过require来引入依赖
    let $ = require('jquery');
    ley Spinning = require('./spinning');
    
    • CommonJS规范 - module.exports (node服务端使用的规范)
    exports.area = function (r) {
    return Math.PI * r * r ;
    
    • ES6特性 export/import
    export default {
      props:["num"],
    data() {
     return{
     }
    },
    methods:{
     increment(){
     this.$emit("incre");
     import('./../util')
    },
    decrement() {
     this.$emit("decre");
     }
    }
    }
    

    八、前端渲染访问后台回来的数据

    图片懒加载vue-lazyload
    图片分页插件vue-infinite-scroll

    相关文章

      网友评论

          本文标题:Vue学习日记

          本文链接:https://www.haomeiwen.com/subject/wpxfrctx.html