Vue学习总结

由于没有目录的功能,为了更加清晰的学习,我制作了一个目录地址如下:
学习Vue目录 链接地址: https://www.jianshu.com/p/2c9071c0436d
如果想快速、准确、查看、学习内容,那么你就点击上面的链接,查看到整体目录,然后点击查看自己想看的内容。
如果你不想单篇的了解,此篇文章汇总了所有章节的内容

第1章 课程介绍

1-1课程简介
Vue学习总结_第1张图片
学习流程
Vue学习总结_第2张图片
知识点

学习前提:
有一些css、js、es6、webpack、npm等基础知识


Vue学习总结_第3张图片
学习收获

第2章 Vue 起步

2-1 学习方法

多看一下官网api Vue官网
务必把官网的小的demo自己敲一遍加深一下对语法糖的理解

2-2 hello world

那么初步认识一下vue,那么从一个简单的hello world开始吧




    
    Hello world
    


{{content}}

el:'#root' vue实例化的数据只针对 id为root内使用
{{content}} : 获取 vue里面data 里面的数据值

2-3 开发TodoList(v-model、v-for、v-on)



    
    Hello world
    


  • {{item}}

v-on:click="handleClick" 绑定点击事件
v-model="inputValue" 数据双向绑定
v-for="(item,index) in list" 数据循环

2-4 MVVM模式

MVP (Model View Presenter)
Model:接口请求操作
View:页面展示
P:处理数据和页面(大量的dom操作)


Vue学习总结_第4张图片
MVP

MVVM

Vue学习总结_第5张图片
MVVM

而Vue则采用的是mvvm这种模式,它在乎的是数据的变化驱动Ui的变化,不用用户管dom的操作,vue则扮演的是VM的操作,我们的重心是放在了M层也就是数据这一层

2-5 前端组件化

页面有好多部分组成,把页面切成一部分一部分,而拆分出来的部分,就是一个组件

2-6 使用组件改造TodoList

1.全局组件的声明和使用

//Vue创建全局组件的方法
Vue.component('TodoItem', {
    props: ['content'],
    template: '
  • {{content}}
  • ' }); ps: 数据的传递通过v-bind: 来定义传递的属性,后面跟上要传递的值 通过“props”来接受属性,再通过插值表达式来展示{{content}}

    2.Vue局部组件的创建和使用

     //Vue局部组件的创建和使用
    var TodoItem = {
            props: ['content'],
            template: '
  • {{content}}
  • ' }; var app = new Vue({ el: '#root', components: { TodoItem: TodoItem } }) ps: 定义一个变量,值为对象,把属性值和模板作为属性的键值 在Vue实例化中通过components这个参数来调用这个定义好的变量(局部组件)
    2-7 简单的组件间传值

    父组件向子组件传值:
    子组件通过定义一个属性:v-bind:content="item",将item值传给子组件的content
    子组件通过props:['content'] 来接受父组件传过来的值,再通过插值表达式来展示{{content}}
    子组件向父组件传值:
    子组件通过定义一个方法或者一个事件handleItemClick,在方法或者事件中,通过this.$emit(''delete",this.index)方法给给父组件发送一个信号,
    父组件监听这个信号:@delete="handleDeleleItem"
    下面代码演示:

    
    
    
        
        Hello world
        
    
    
    
    2-8 Vue的一些指令简写方法

    v-on:click 等价于 @click //this.emit('delete') 接受也是 @delete
    v-bind:content 等价于 :content

    第3章 Vue 基础精讲

    3-1 Vue实例

    vue实例是根实例,组件也是vue实例,所以说页面是由很多vue实例组成的
    data(): 以destroy():用于销毁vue实例,但是之前的数据和方法并没有被销毁

    var app = new Vue({
      el:'#root',
      data:{
        message:'hello world'
      },
      methods: {
        handleClick(){},
      },
      watch:{
    
      },
      computed:{
    
      }
    })
    
    3-2 Vue实例生命周期
    //生命周期函数就是vue实例在某个时间点自动执行的函数
    var app = new Vue({
            el:'#root',
            data:{
               inputValue:'' 
            },
            beforeCreate: function () {
                console.log('beforeCreate');
            },
            created: function () {
                console.log('created');
            },
            beforeMount: function () {
                console.log(this.$el);
                console.log('beforeMount');
            },
            mounted: function () {
                console.log(this.$el);
                console.log('mounted');
            },
            beforeDestroy: function () {
                //app.$destroy()
                console.log('beforeDestroy');
            },
            destroyed: function () {
                console.log('destroyed');
            },
            beforeUpdate: function () {
                //app.$data.inputValue = 1
                console.log('beforeUpdate')
            },
            updated: function () {
                console.log('updated')
            }
    })
    
    3-3 Vue的模版语法

    插值表达式{{}} : 用{{输入的值}}
    v-指令 写的是js表达式
    v-text 就是innertext 其实就是 {{}}
    v-html 就是innerhtml
    v-指令 后面除了可以写js名称还可以加字符串,插值表达式也可以写字符串

    var app = new Vue({
          el: '#root',
          data: {
              name: 'hello',
              bigName: '

    hello

    ' } }) {{name + ' world'}}
    ps:v-html 会对bigName进行转义,字体变成h1字体大小,而不会出现标签
    3-4 计算属性、方法与侦听器

    计算属性
    computed属性,因为他是属性,所以在用插值表达式取值的时候不用加括号
    computed:内置变量缓存的功能,当data里面age变量更改时,如果不是计算属性内边的变量更改,那么他就不会渲染computed内部的变量

    
    
    
        
        Title
        
    
    
    
    {{fullName}}

    methods方法
    因为是方法,所以插值表达式要用括号取值,
    他不具有缓存变量的功能

    
    
    
        
        Title
        
    
    
    
    {{fullName()}}

    侦听器

    
    
    
        
        侦听器
        
    
    
    
    {{fullName}} {{age}}

    总结:我们可以通过methods、computed、watch来实现fullName显示的问题
    computed和watch都具备缓存的功能
    但是从代码量的编写程度来看,computed属性会更加方便和便捷一些。

    3-5 计算属性的getter和setter

    computed属性当中有两个方法,分别是:get 和 set

    
    
    
        
        getter和setter
        
    
    
    
    
    {{fullName}} {{age}}
    3-6 Vue中的样式绑定

    class的对象绑定

    
    
    
        
        class的对象绑定
        
        
    
    
    
    
    hello world

    class的数组绑定

    
    
    
        
        class的数组绑定
        
        
    
    
    
    hello world

    style对象绑定

    
    
    
        
        style对象绑定
        
    
    
    
    hello world

    style的数组绑定

    
    
    
        
        style数组绑定
        
    
    
    
    hello world
    3-7 条件渲染

    v-if 、v-else-if、v-else

    
    
    
        
        V-if
        
    
    
    
    实例一:v-if

    实例二:v-else
    要是我显示
    要么你显示

    实例三:v-else-if
    A
    B
    C
    其他

    key 管理可复用的元素
    当切换两个input输入框的时候,为了不让input框的输入内容被占用,所以我们通过设置input的key值来解决这个问题

    
    
    

    demo例子:https://codepen.io/sunnyfan/pen/JQjRry

    v-show
    v-show很相似,只要设置值为true则显示

    v-if和v-show的区别

    • v-show不能和v-else 和 v-else-if结合使用
    • v-show 不管是ture还是fasle div元素都会渲染出来(false style的display:none),如果如果有频繁的切换,我们会首选v-show,减少对dom的频繁操作
    3-8 Vue列表渲染

    v-for

  • {{index}}--{{item}}

  • {{key}}-{{item}}-{{index}}
  • 
    
    
        
        列表渲染
        
    
    
    
    • {{index}}--{{item}}
    • {{key}}-{{item}}-{{index}}-

    template可以当一个空标签做为for循环渲染,而这个template不会渲染到dom里面

    为了防止子组件循环渲染出现dom结构不对的情况,我们一般会通过is来给子组件命名

    //html
      //这个地方调用is属性
       
    //js Vue.component('row', { props: ['title'], template: '{{title}}' }); var app = new Vue({ el: '#root', data: { list: [ 'hello', 'world' ] } })
    更改数组值方法有哪些?

    1.变异方法
    push()、 pop()、 shift()、unshift()、splice()、sort()、reverse()
    2.替换数组
    当也可以创建一个新的数组,在通过
    filter()、concat()、slice()
    更改原始数组的值,再把更改后的数组替换旧的数组
    3.set或者$set方法

    Vue.set(app.userInfo,'age',22)
    //或者
    vm.$set(app.userInfo,'age',22)
    

    4.Object.assign()或者_.extend()

    vm.userInfo = Object.assign({},vm.userInfo,{
      sex:'男',
      email:'[email protected]'
    })
    

    ps:不可以通过数组下标去更改数组的值

    var vm = new Vue({
      data: {
        items: ['a', 'b', 'c']
      }
    })
    vm.items[1] = 'x' // 不是响应性的
    vm.items.length = 2 // 不是响应性的
    

    3-9 Vue事件处理

    监听事件、方法处理、内联处理器中的方法

    1.监听事件

    通过v-on指令监听DOM事件,并在触发时运行一些 JavaScript 代码

    
    
    
        
        监听事件
        
    
    
        

    The button above has been clicked {{counter}} times.

    2.事件处理方法

    但是在开发的过程中,有时候直接把 JavaScript 代码写在 v-on 指令中是不可行的。因此 v-on 还可以接收一个需要调用的方法名称

    3.内联处理器中的方法

    除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:

    
    
    
    const app = new Vue({
            el: '#root',
            data: {
                name: 'sunny'
            },
            methods: {
                say: function (val) {
                    console.log(`${this.name} ${val}`)
                }
            }
        })
    

    方法总通过传递参数$event,可以原始的DOM

    
    const app = new Vue({
            el: '#root',
            data: {},
            methods: {
                warning: function (val, event) {
                    if (event) event.preventDefault();
                    console.log(val)
                }
            }
        })
    
    4.事件修饰符

    我们在开发个过程中经常调用一些
    event.preventDefault() //阻止事件的默认行为
    event.stopPropagation() //阻止冒泡的行为

    而vue为了更好的让我们关注业务逻辑代码的编写,它封装了很多v-on修饰符来帮助我们完成上面那些工作。

    • stop //event.stopPropagation()
    • prevent //event.preventDefault()
    • capture
    • self
    • once
    • passive

    第4章 深入理解Vue组件

    4-1 使用组件细节点

    1.is的使用
    当我们写循环组件的时候,经常给
    table中的tr
    select中的option
    ul中的li或者ol中的li
    等等定义组件的时候,我们经常用is来定义组件的名称,为了让浏览器成功的渲染正确的dom结构

    2.在子组件定义data的时候,必须是一个函数,而不能是一个对象,返回一个对象是为了每个子组件都能拥有一个独立的数据存储。这样子组件之间的数据不会互相影响
    而在根组件中,data可以是一个对象。

    3.有时候我们在开发过程中,因为一些业务的需求,少不了对dom的操作,那么我们就可以借助ref来实现

    //实例一
    
    hello world
    //案例二 counter求和
    {{total}}
    4-2父子组件之间的数据传递

    父组件向子组件传值:是通过属性的方式
    子组件向父组件传值:可以通过$emit来触发一个事件

    vue数据传递遵循的是单向数据流,
    所以在下面的案例中我们并没有对content数据直接进行数据的累加,而是把content数据赋值给了number,对number进行数据的累加操作。

    {{total}}
    4-3组件参数校验和非props特性

    1.组件的的参数校验

    2.props特性和非props特性的对比
    props特性:
    父组件传递属性,子组件要接受该属性
    props属性不会显示在dom的标签之中
    非props特性:
    父组件传递属性,子组件没有去接受,而是直接调用
    props属性会显示在dom的标签之中

    4-4给组件绑定原生事件

    通过.native属性来绑定原生事件

    4-5 非父子组件间的传值
    Vue学习总结_第6张图片
    非父子组件间的传值

    1.通过vuex
    2.通过发布订阅模式(Bus/总线/发布订阅模式/观察者模式/)

    4-7作用域插槽

    父组件调用子组件的时候,给子组件传了一个插槽,这个插槽是一个作用域的插槽,这个插槽必须是一个
    那什么时候使用作用插槽呢?
    1.当子组件做循环
    2.或者当子组件的dom结构由外部传递进来,或者有外部决定的时候

    4-8 动态组件和v-once 指令

    第5章 表单

    5-1双向数据绑定 v-model

    你的名字是:{{name}}

    5-2复选框(checkbox)相关的操作

    1)、单个复选框的取反操作
    2)、多个复选框的数组操作

    单个复选框:

    多个复选框:

    选择的值为:{{checkedNames}}

    Vue学习总结_第7张图片
    效果
    5-3单选框(radio)相关的操作

    单个复选框:

    选中的值:{{picked}}

    Vue学习总结_第8张图片
    效果
    5-4选择框(select)相关的操作

    选择框:

    你先则的值是:{{ages}}

    Vue学习总结_第9张图片
    效果
    5-5 表单中一些修饰符的操作(.lazy、.number、.trim)

    .lazy(input事件同步输入看的值,通过lazy转为change事件中同步):

    你输入的文本内容是:{{text}}

    .number(输入文本内容为数字):

    输入的数字是:{{number}}

    .trim(去除输入框两端的空格):

    显示输入的内容:{{trimText}}

    Vue学习总结_第10张图片
    效果

    第6章 动画

    6-1 Vue中的css动画原理

    我们给transition name属性定义的是fade 所以是下面名称:
    fade-enter fade-enter-to fade-enter-active
    fade-leave fade-leave-to fade-leave-active
    如果我们没有给transition定义name属性,用默认的那么就是:
    v-enter v-enter-to v-enter-active
    v-leave v-leave-to v-leave-active

    Vue学习总结_第11张图片
    进场动画原理

    刚开始存在fade-enter和fade-enter-active
    紧接第二帧的时候,fade-enter消失、fade-enter-to 出现
    到最后的时候fade-enter-to消失、fade-enter-active消失

    Vue学习总结_第12张图片
    离开动画原理

    刚开始存在fade-leave和fade-leave-active
    紧接第二帧的时候,fade-leave消失、fade-leave-to 出现
    到最后的时候fade-leave-to消失、fade-leave-active消失

    //css动画效果(css过度动画效果)
    
    
    
    hello world

    ps:
    显示操作
    刚开始fade-enter opacity为0 第二帧fade-enter消失 opacity变为1 这个过程一直在fade-enter-active 监听1秒时间
    隐藏操作
    刚开始fade-leave opacity 默认是1 第二帧 fade-leave消失 fade-leave-to出现 opacity 变为0 这个过程一直在fade-leave-active监听1秒时间后消失

    第7章 路由

    7-1.什么是路由

    路由:就是我们通过不同的 URL 访问不同的内容。

    7-2.Vue 路由的安装
    • cdn
      https://unpkg.com/vue-router/dist/vue-router.js
    • npm
    npm install vue-router
    
    7-3.Vue 路由的简单案例
    
    
    
    
      
      
      
      
      
      路由
      
    
    
    
      

    hello 路由!

    go header go footer

    go header(replace) go footer(append)

    go header(tag)

    go header(exact-active-class) go header(active-class)

    go header(event)

    Vue学习总结_第13张图片
    效果
    7-4.router-link的相关配置

    1)、to 表示路由链接
    当被点击后,内部会立即把to的值传到router.push,所以这个值可以是一个字符串或者是描述目标位置的对象

    
    Home
    
    Home
    
    
    Home
    
    
    Home
    
    
    Home
    
    
    User
    
    
    Register
    

    2)、replace
    设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。

    
    

    3)、tag
    有时候想要 渲染成某种标签,例如

  • 。 于是我们使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航。

    foo

  • foo
  • 4)、active-class
    设置 链接激活时使用的 CSS 类名。可以通过以下代码来替代。

    
    

    Router Link 1 Router Link 2

    注意这里 class 使用 active_class="_active"。

    5)、exact-active-class
    配置当链接被精确匹配的时候应该激活的 class。可以通过以下代码来替代。

    Router Link 1 Router Link 2

    6)、event
    声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。

    Router Link 1
    

    以上代码设置了 event 为 mouseover ,及在鼠标移动到 Router Link 1 上时导航的 HTML 内容会发生改变。
    7)、exact-active-class 和 active-class 的区别
    exact-active-class:路由严格匹配
    active-class:路由模糊匹配
    如果你访问的是:
    /article或者/article/1

    
    

    都会被渲染

    
    

    
    

    只有访问/article/1
    才会被渲染

    
    

    如果是/article,class不会被渲染出来

    
    

    第8章 Vue项目预热

    8-1.NodeJS安装
    //验证node和npm 是否安装 以及安装的版本
    node -v
    npm -v
    

    根据自己电脑是什么系统去安装:NodeJS安装

    8-2.vue脚手架安装
    //电脑全局安装
    npm install --global vue-lci
    
    //a. 实例出一个项目
    vue init webpack vue-travel //vue-travel 名称自己定义
    
    //b. 如果你本地有一个git项目了,你想把这个vue脚手架放入到这个项目中
    vue init webpack git-project //git-project  本地git项目名称
    
    8-3.运行脚手架项目
    cd vue-travel  //or  cd git-project 
    npm run dev //or   npm start
    

    浏览器访问localhost:8080即可

    8-4.如何更改端口号

    项目config文件件,我们打开其目录下的index.js,就是端口号的最终设置的地方:

    dev: {
        // Paths
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        proxyTable: {},
    
        // Various Dev Server settings
        host: 'localhost', // can be overwritten by process.env.HOST
        port: 8081, //在这个地方进行端口号的更改
        autoOpenBrowser: false,
        errorOverlay: true,
        notifyOnErrors: true,
        poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
        .....
    }
    
    8-5.如何通过ip来访问我们的网站呢
    http://localhost:8080
    http://127.0.0.1:8080
    http://自己电脑ip:8080 //如果手机和电脑在同一个网段,手机可以联调项目,查看手机效果
    

    第一种方法修改:package.json文件
    在dev 命令里面添加 --host 0.0.0.0

    "scripts": {
        "dev": "webpack-dev-server --host 0.0.0.0 --inline --progress --config build/webpack.dev.conf.js",
        "start": "npm run dev",
        "lint": "eslint --ext .js,.vue src",
        "build": "node build/build.js"
      },
    

    第二种方法修改:config/index.js文件

    dev: {
        // Paths
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        proxyTable: {},
    
        // Various Dev Server settings
        host: '0.0.0.0', // 修改这个地方 将localhost 改为 0.0.0.0
        port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
        autoOpenBrowser: false,
        errorOverlay: true,
        notifyOnErrors: true,
        poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
        ......
    }
    

    重启 npm run dev 或者npm start

    区别:
    修改package.json 之后的结果(和之前没有什么区别):
    Your application is running here: http://localhost:8080
    修改config/index.js文件 之后的运行结果:
    Your application is running here: http://0.0.0.0:8080

    所以我推荐 方法一(纯粹个人意见)

    8-6.Vue 项目初始化的准备工作

    因为是手机端的vue项目,所以项目index.html 我们要设置一下
    1.禁止缩放

    
    

    2.reset.css

    @charset "utf-8";html{background-color:#fff;color:#000;font-size:12px}
    body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{margin:0;padding:0}
    body,input,textarea,button,select,pre,xmp,tt,code,kbd,samp{line-height:1.5;font-family:tahoma,arial,"Hiragino Sans GB",simsun,sans-serif}
    h1,h2,h3,h4,h5,h6,small,big,input,textarea,button,select{font-size:100%}
    h1,h2,h3,h4,h5,h6{font-family:tahoma,arial,"Hiragino Sans GB","微软雅黑",simsun,sans-serif}
    h1,h2,h3,h4,h5,h6,b,strong{font-weight:normal}
    address,cite,dfn,em,i,optgroup,var{font-style:normal}
    table{border-collapse:collapse;border-spacing:0;text-align:left}
    caption,th{text-align:inherit}
    ul,ol,menu{list-style:none}
    fieldset,img{border:0}
    img,object,input,textarea,button,select{vertical-align:middle}
    article,aside,footer,header,section,nav,figure,figcaption,hgroup,details,menu{display:block}
    audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
    blockquote:before,blockquote:after,q:before,q:after{content:"\0020"}
    textarea{overflow:auto;resize:vertical}
    input,textarea,button,select,a{outline:0 none;border: none;}
    button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
    mark{background-color:transparent}
    a,ins,s,u,del{text-decoration:none}
    sup,sub{vertical-align:baseline}
    html {overflow-x: hidden;height: 100%;font-size: 50px;-webkit-tap-highlight-color: transparent;}
    body {font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;color: #333;font-size: .28em;line-height: 1;-webkit-text-size-adjust: none;}
    hr {height: .02rem;margin: .1rem 0;border: medium none;border-top: .02rem solid #cacaca;}
    a {color: #25a4bb;text-decoration: none;}
    

    在我们项目assets文件下面
    创建styles文件
    在styles文件下面添加reset.css
    最后在项目的main.js引入reset.css

    import './assets/styles/reset.css'
    

    3.border.css
    解决1px边框问题

    @charset "utf-8";
    .border,
    .border-top,
    .border-right,
    .border-bottom,
    .border-left,
    .border-topbottom,
    .border-rightleft,
    .border-topleft,
    .border-rightbottom,
    .border-topright,
    .border-bottomleft {
        position: relative;
    }
    .border::before,
    .border-top::before,
    .border-right::before,
    .border-bottom::before,
    .border-left::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::before,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-topright::after,
    .border-bottomleft::before,
    .border-bottomleft::after {
        content: "\0020";
        overflow: hidden;
        position: absolute;
    }
    /* border
     * 因,边框是由伪元素区域遮盖在父级
     * 故,子级若有交互,需要对子级设置
     * 定位 及 z轴
     */
    .border::before {
        box-sizing: border-box;
        top: 0;
        left: 0;
        height: 100%;
        width: 100%;
        border: 1px solid #eaeaea;
        transform-origin: 0 0;
    }
    .border-top::before,
    .border-bottom::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-topleft::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-bottomleft::before {
        left: 0;
        width: 100%;
        height: 1px;
    }
    .border-right::before,
    .border-left::before,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-topright::after,
    .border-bottomleft::after {
        top: 0;
        width: 1px;
        height: 100%;
    }
    .border-top::before,
    .border-topbottom::before,
    .border-topleft::before,
    .border-topright::before {
        border-top: 1px solid #eaeaea;
        transform-origin: 0 0;
    }
    .border-right::before,
    .border-rightbottom::before,
    .border-rightleft::before,
    .border-topright::after {
        border-right: 1px solid #eaeaea;
        transform-origin: 100% 0;
    }
    .border-bottom::before,
    .border-topbottom::after,
    .border-rightbottom::after,
    .border-bottomleft::before {
        border-bottom: 1px solid #eaeaea;
        transform-origin: 0 100%;
    }
    .border-left::before,
    .border-topleft::after,
    .border-rightleft::after,
    .border-bottomleft::after {
        border-left: 1px solid #eaeaea;
        transform-origin: 0 0;
    }
    .border-top::before,
    .border-topbottom::before,
    .border-topleft::before,
    .border-topright::before {
        top: 0;
    }
    .border-right::before,
    .border-rightleft::after,
    .border-rightbottom::before,
    .border-topright::after {
        right: 0;
    }
    .border-bottom::before,
    .border-topbottom::after,
    .border-rightbottom::after,
    .border-bottomleft::after {
        bottom: 0;
    }
    .border-left::before,
    .border-rightleft::before,
    .border-topleft::after,
    .border-bottomleft::before {
        left: 0;
    }
    @media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
        /* 默认值,无需重置 */
    }
    @media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
        .border::before {
            width: 200%;
            height: 200%;
            transform: scale(.5);
        }
        .border-top::before,
        .border-bottom::before,
        .border-topbottom::before,
        .border-topbottom::after,
        .border-topleft::before,
        .border-rightbottom::after,
        .border-topright::before,
        .border-bottomleft::before {
            transform: scaleY(.5);
        }
        .border-right::before,
        .border-left::before,
        .border-rightleft::before,
        .border-rightleft::after,
        .border-topleft::after,
        .border-rightbottom::before,
        .border-topright::after,
        .border-bottomleft::after {
            transform: scaleX(.5);
        }
    }
    @media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
        .border::before {
            width: 300%;
            height: 300%;
            transform: scale(.33333);
        }
        .border-top::before,
        .border-bottom::before,
        .border-topbottom::before,
        .border-topbottom::after,
        .border-topleft::before,
        .border-rightbottom::after,
        .border-topright::before,
        .border-bottomleft::before {
            transform: scaleY(.33333);
        }
        .border-right::before,
        .border-left::before,
        .border-rightleft::before,
        .border-rightleft::after,
        .border-topleft::after,
        .border-rightbottom::before,
        .border-topright::after,
        .border-bottomleft::after {
            transform: scaleX(.33333);
        }
    }
    

    在main.js文件下面

    import './assets/styles/border.css'
    

    4.fastclick 解决300毫秒点击延迟问题
    在main.js文件下面

    import fastClick from 'fastclick'
    fastClick.attach(document.body)
    

    如果想预览项目整体的效果和配置项git地址:
    https://github.com/fx35792/vue-travel
    5.安装stylus、stylus-loader 第三方依赖

    npm install stylus -S
    npm install stylus-loader -S
    

    那么在vue组件中如何使用呢?

    //1.设置 lang 为 `stylus`
    //2.如果只想样式对当前页面生效,而不污染到全局的其他的样式  可以加 scoped属性
    //3.stylus 语法:支持嵌套,变量引用,省去冒号和花括号等等优点
    
    

    上面我们说道style里面的scope是只对当前页面生效,但是在开发过程中,我们可能需要引入第三方的样式,有时候为了满足Ui的样式变化我们需要style书写覆盖第三方依赖的样式,那么我们改如何操作呢?

    
    
    8-7.Vue 项目如何给长目录定义变量

    在开发过程中我们经常要引入外部文件,比如styles文件、图片文件等等

    ../../../assets/styles/border.css
    

    像上面的例子我们肯定遇到过,如果有一个变量styles能直接代码../../../styles那就好了。
    那在vue-cli的脚手架中应该怎么去配置呢?
    在build/webpack.base.conf.js中

    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
          'styles': resolve('src/assets/styles'), //这是我们添加的变量
        }
      },
    

    配置好以后,我们需要重启一下项目 npm startornpm run dev
    那么上面例子长长的引用我们就可以改写为

    styles/border.css
    

    ps:如果我们在vue组件中引用的话我们需要注意在styles之前加个波浪符~

    @import '~styles/varibles.styl';
    
    8-7.Vue 项目如何引入本地图片呢?

    require

    require('@/assets/images/1.jpg')
    

    import

    //此处的@ 指的是src目录
    import bannerImg1 from '@/assets/images/1.jpg'
    

    alias

    //webpack.base.conf.js
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
          'styles': resolve('src/assets/styles'),
          'images': resolve('src/assets/images'),//配置图片变量路径
        }
      },
    
    //页面调用
    
    
    
    

    第9章 Vue项目开发之首页

    首页制作完的整体效果:


    Vue学习总结_第14张图片
    效果图

    如果你想看首页整体开发效果,直接运行master分支即可:
    https://github.com/fx35792/vue-travel

    如果想看每部分的开发效果:

    • 首页header和swiper我放到一个分支上了都在swiper分支:
      https://github.com/fx35792/vue-travel/tree/swiper
    • 首页iconList开发
      https://github.com/fx35792/vue-travel/tree/index-icons
    • 首页”热门推荐“和”周末去哪“开发
      https://github.com/fx35792/vue-travel/tree/index-recommond
    9-1 Vue项目开发首页之header

    在开发这块的时候,主要是一个布局的设置,还有就是icon图标,这个icon图标用的是阿里iconfont:https://www.iconfont.cn/
    1.创建一个iconfont账号
    2.登录后-->图标管理-->我的图标-->新建项目
    3.去查找UI所需要的图标icon,添加购物车-->添加项目-->选择自己新建的项目
    4.图标全部查找完以后可以把这个项目下载到本地
    第一种方法:如果是下载到本地,放入到项目中的操作

    Vue学习总结_第15张图片
    程序引入字体样式文件

    在main.js引入

    import 'styles/iconfont.css'
    
    //页面上使用的话
    
    

    第二种方法:不下载本地,用阿里iconfont的cdn


    Vue学习总结_第16张图片
    程序引入样式cdn

    在index.html中添加

    ‘’
    
    //页面上使用的话(和方法一是一样的)
    
    

    如果你是线上项目,为了保险起见,推荐使用方法一
    但是如果你平时自己做项目练习,你使用方法二就行

    9-2 Vue项目开发首页之Swiper轮播图

    1.安装https://github.com/surmon-china/vue-awesome-swiper

    npm install vue-awesome-swiper --save
    

    2.如何使用呢?
    因为项目中很多地方可能需要用到swiper,所以我们打算把他放到main.js中

    import VueAwesomeSwiper from 'vue-awesome-swiper'
    import 'swiper/dist/css/swiper.css'
    
    Vue.use(VueAwesomeSwiper)
    

    3.具体代码调用

    //template
    
          
            
          
          
    //js
    9-3 Vue项目开发首页之”热门推荐“和”周末去哪“

    这一小节主要是UI上布局制作,以及data里面模拟一些数据,渲染到页面上。具体细节看
    https://github.com/fx35792/vue-travel/tree/index-recommond
    看代码基本上都可以看明白的,在这咱们就不详细的赘述了

    9-4 Vue项目开发首页之ajax数据请求

    我们通过ajax来实现接口请求的数据,但是呢?在开发过程中,很多时候都是我们前端自己mock数据,通过代理,最后映射到页面上数据的,随后等服务器接口开发好了,我们在把mock数据地址替换为服务器地址即可。
    1.那么如何设置代理呢?
    其实在vue-cli的脚手架中,已经办咱们配置好了设置,只需要你自己配置一下即可:

    //在config文件下面的index.js文件中:
    proxyTable: {
          '/api': {
            target:'http://localhost:8080',//因为数据在我项目本地,所以我配置的localhost,如果是服务器你配置后端伙伴发给你的服务器地址即可
            pathRewrite: {
              '^/api':'/static/mock'  //当你接口请求中,以`/api`开头的时候,会帮我们代理到我们本地的/static/mock目录下面数据文件
            }
          }
        },
    

    2.安装axios

    npm install axios -S
    

    3.在页面上使用

    import axios from 'axios'
    
     mounted () {//一般的异步请求,我们都会放在mounted的生命周期中
        this.getHomeInfo()//这个我们定义了一个方法,而不是直接写,是为了重复使用这个方法
      },
    methods: {
        getHomeInfo () {
         //通过axios请求接口
        //当我们遇到`/api`,代理直接会找到/static/mock/index.js文件
          axios.get('/api/index.json').then(this.getHomeInfoSucc)
        },
        getHomeInfoSucc (res) {
          const result = res.data
          if (result.ret && result.data) {
            const data = result.data
            console.log(data)
            this.city = data.city
            this.swiperList = data.swiperList
            this.iconList = data.iconList
            this.recommendList = data.recommendList
            this.weekendList = data.weekendList
          }
        }
      }
    
    9-4 Vue项目开发首页之父子组件之间的传值

    在制作的首页过程中,我们将首页拆分成了五部分,分别是:
    header、banner轮播、icon轮播、热门推荐、周末去哪
    那么,为了减少http接口请求,后端小伙伴会把五部门的内容都放到一个接口中去,在咱们本地模拟数据中我是放到了static/mock/index.json中的
    所以在Home.vue中

    //Home.vue
    
    
    
    
    
    //Swiper.vue
    
    
    
    
    

    在这里咱们主要讲讲,首页父子组件的传值,咱们拿一个banner轮播图例子来说,其他的四部分咱们就不在这里赘述了。你去github仓库看源码就很容易明白。
    第一步:接口请求拿到数据(axios.get('/api/index.json').then(this.getHomeInfoSucc)//第一步)
    第二步:在data中我们初始化这五部分数据(swiperList: [],.//第二步)
    第三步:把接口拿到的数据依次放入到data初始化的值中( this.swiperList = data.swiperList//第三步)
    第四步:在Home.vue父组件中定义一个属性,来给Swiper.vue子组件传值(:list="swiperList")
    第五步:在Swiper.vue子组件中接受父组件传来的值(props: {
    list: Array //第五步
    })
    第六步:子组件渲染出来父组件传递过来的数据(

    第10章 Vue项目开发之城市

    10-1.city页面路由配置

    1.添加路由配置

    // router/index.js文件
    import City from '@/pages/city/City'
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'Home',
          component: Home
        },
        {
          path: '/city',
          name: 'City',
          component: City
        }
      ]
    })
    

    2.添加相对应的页面
    在pages文件下面添加city文件夹和City.vue文件


    Vue学习总结_第17张图片
    效果图

    3.初始化City.vue页面

    
    
    
    
    
    10-2.city-header部分制作
    //city/City.vue
    
    
    
    
    
    
    //city/components/header.vue
    
    
    
    
    
    
    Vue学习总结_第18张图片
    效果图
    10-3.city-search部分制作

    上面咱们已经完成了头部的制作,这一节咱们来city-search的ui部分制作,随后等咱们把city列表制作完成后,咱们再来制作city-search相关的逻辑部分,代码如下

    //city/components/Search.vue
    
    
    
    
    
    

    city/City.vue,在city的主页面引入我们制作好的city-search模块


    Vue学习总结_第19张图片
    image.png
    10-3 city-list、city-ajax 、city-vuex、city-search-logic 部分的制作
    Vue学习总结_第20张图片
    城市整体效果图

    Ui上面的制作,直接从github下载下来,git checkout 到不同的分支,就能看到代码了,总结嘛,不能能把所有的项目中的代码都展示出来,更多的是展示难点、思路、注意事项等等一些小细节地方。
    city-ajax部分和index-ajax 方式是一样,在这里咱们就不再次赘述了

    知识点1:BetterScroll 的使用,让城市列表可以滚动起来

    //安装better-scroll
    npm install better-scroll -S
    

    在这个使用better-scroll的时候我们需要注意三点

    • dom结构(要符合这种结构)
    • ...
    • ...
    • ...

    你可能感兴趣的:(Vue学习总结)