Vue笔记

Vue

Vue基础

Vue是基于M(数据)V(视图)VM(调度者)这种设计模式开发出来的一个框架

MVC和MVVM之间的区别: MVC是单向通信 MVVM是双向数据绑定

Vue基本的编码步骤

  1. 引入Vue.js框架
<script src='./src/vue.js'></script>
  1. 在script标签部分创建一个Vue实例
var vm = new Vue({
    el:'#app', // 通过选择器找到一个让vm实例监管的区域
    data:{
        // 在data中定义的数据就是整个Vue实例可以用到的数据
        msg:'hello'
    }
})
  1. 在HTML结构部分书写Vue代码
<div id = 'app'>
    {{msg}}
</div>

Vue指令

  • {{}}:插值表达式,用于显示data中定义的数据

  • v-text:用于显示data中定义的普通文本数据

new Vue({
    el:'#app',
    data:{
        msg:'普通文本数据'
    }
})
<p v-text = 'msg'></p>
  • v-html:用于显示data中定义的富文本数据(带有HTML标签的文本)
new Vue({
    el:'#app',
    data:{
        msg:'<p>富文本数据<p/>'
    }
})

<div v-html = 'msg'></div>
  • v-bind:动态的给元素绑定属性
new Vue({
    el:'#app',
    data:{
        url:'http://www.baidu.com/'
    }
})

<a v-bind:href = 'url'>百度</a>
  • v-for:用于循环渲染元素进行显示
<div v-for = '(item,index) in list' :key = 'index'>
    <!-- 数组中的每一项 -->
    {{item}} 
    <!--  当前项的索引 -->
    {{index}}
</div>
  • v-model:用于对表单元素实现双向数据绑定,即模型中数据发生变化可以直接更新视图,视图中数据发生变化也可以影响到模型
<!-- v-model 指令只能用于表单元素和组件 常见于input/textarea/select标签上 -->
<input v-model = 'name'></input>
  • v-on:绑定事件
<button v-on:click = 'clickHandle'></button>
new Vue({
    el:'#app',
    // methods中专门用来定义方法
    methods:{
        clickHandle:function(){
            console.log('点击事件被触发了')
        }
    }
})
  • v-if:控制元素的显示隐藏

通过添加和移除元素控制元素显示隐藏

如果元素初始状态是隐藏的,而且不涉及频繁显示隐藏切换,推荐使用v-if

<div v-if = 'isshow'></div>
new Vue({
    el:'#app',
    data:{
        isshow:true
    }
})
  • v-show:控制元素的显示隐藏

通过给元素设置display:none的样式控制元素显示隐藏

如果元素涉及频繁显示隐藏切换,推荐使用v-show,性能会比v-if好

<div v-show = 'isshow'></div>
new Vue({
    el:'#app',
    data:{
        isshow:true
    }
})

使用样式

使用class样式

  1. 数组
<h1 :class="['red', 'thin']">这是一个邪恶的H1</h1>
  1. 数组中使用三元表达式
<h1 :class="['red', 'thin', isactive?'active':'']">这是一个邪恶的H1</h1>
  1. 数组中嵌套对象
<h1 :class="['red', 'thin', {'active': isactive}]">这是一个邪恶的H1</h1>
  1. 直接使用对象
<h1 :class="{red:true, italic:true, active:true, thin:true}">这是一个邪恶的H1</h1>

使用内联样式

  1. 直接在元素上通过 :style 的形式,书写样式对象
<h1 :style="{color: 'red', 'font-size': '40px'}">这是一个善良的H1</h1>
  1. 将样式对象,定义到 data 中,并直接引用到 :style
  • 在data上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="h1StyleObj">这是一个善良的H1</h1>
  1. :style 中通过数组,引用多个 data 上的样式对象
  • 在data上定义样式:
data: {
        h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
        h1StyleObj2: { fontStyle: 'italic' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="[h1StyleObj, h1StyleObj2]">这是一个善良的H1</h1>

ref获取DOM

通过给元素设置ref属性,然后使用this.$refs.属性值得方式可以获取到DOM

<div ref = 'dv'></div>
<button @click = 'getdv'>获取div元素</button>
new Vue({
    el:'#app',
    methods:{
        getdv(){
            console.log(this.$refs.dv)
        }
    }
})

自定义指令

指令能够帮助开发者操作DOM,当系统指令不能够满足需求时,就可以使用自定义指令进行DOM操作;将操作DOM的方式封装成指令后首先可以重复使用,其次封装成指令的过程是vue内部提供的方法,这些方法在性能上比直接操作DOM元素要高。

Vue.directive('mycolor',{
    // 指令的钩子函数
    inserted(el,binding){
        // el 是指令所在的元素对象
        // bingding是一个对象
        // binding.value // red 指令等号后面表达式的值 也就是变量的值
        // binding.expression // 指令等号后面的表达式  本质就是一个变量
    }
})

new Vue({
    el:'#app',
    data:{
        color:'red'
    }
})
<div v-mycolor = "color"></div>

自定义过滤器

在数据展示之前,对原始数据进行处理并返回处理后的数据进行展示,不改变原始数据

过滤器只能用在插值表达式和属性绑定(v-bind)中

Vue.filter('过滤器名称',function(data,arg){
    // data是原始数据,即管道符前面的数据
    // arg 是使用过滤器时传递的参数
    // 1. 对原始数据进行逻辑处理
    // 2. 处理完成后进行return
    return `处理完的数据`
})
<div>{{原始数据 | 过滤器名称(参数)}}</div>

计算属性computed

用于定义一种可以随着所依赖数据发生变化的属性

new Vue({
    el:'#app',
    // data中定义普通属性
    data:{
        msg:''
    },
    // compluted中定义的函数名就是计算属性 属性的值是该函数的返回值
    // 计算属性的值会随着依赖数据的变化而变化
    // 例如this.msg被修改 则comMsg的值也会重新计算
    compluted:{
        comMsg(){
            return this.msg
        }
    }
})

监听器 watch

监听data中定义的数据的变化

new Vue({
    el:'#app',
    data:{
        msg:'被监听数据',
        obj:{
            name:'zxx'
        }
    },
    watch:{
        msg(newVal,oldVal){
            // 根据数据变化做相关逻辑处理
            // newVal 变化后的值
            // oldVal 变化前的值
        },
        // 当被监听的数据是复杂数据类型时,一般需要用深度监听才可以监听到复杂数据类型内部的数据变化
        obj:{
            handler(newVal,oldVal){
                
            },
            deep:true
        }
    }
})

axios发送请求

axios是一个基于promise的请求库,可以在node环境和浏览器环境中使用。

  1. 引入axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  1. get请求
axios.get('url').then(function(res){
    // res.data即后台返回的数据
    console.log(res.data)
})
  1. post请求
axios.post('url',{
    username:'zxx',
    password:'123456'
}).then(function(res){
    // res.data即后台返回的数据
    console.log(res.data)
})

vue过渡动画

vue中的过渡动画只能作用于使用v-ifv-show控制的元素已经动态组件中

使用css类实现动画

1.使用transition标签将需要实现动画的元素包裹起来

<button @click = 'isshow = !isshow'></button>
<transition>
    <div v-if = 'isshow'>御剑乘风来</div>
</transition>
  1. 使用css类控制动画效果
/* 进入动画就是一个元素从隐藏到显示这个过程需要执行的动画 */

/* 离开动画是一个元素从显示到隐藏这个过程需要执行的动画 */
/* 元素执行进入动画之前的状态 */
.fade-enter {
    transform: translateX(100px)
}
/* 元素执行进入动画的过程中持续添加到元素的状态 */
/* 在这个类中通常都是书写元素需要执行的动画效果 */
.fade-enter-active {
    transition: all 0.2s ease
}
/* 元素执行进入动画结束状态 */
/* 在这个类中通常是用来设置元素执行动画完毕之后的样式 */
.fade-enter-to {
    transform: translateX(0)
}
/* 元素执行离开动画之前需要设定的样式 */
.fade-leave {
    transform: translateX(0)
}
/* 元素执行离开动画的过程中持续添加到元素身上 */
.fade-leave-active {
    transition: all 0.5s ease
}
/* 元素中心离开动画过程中持续添加到元素身上 */
.fade-leave-to {
    transform: translateX(100px)
}

使用animate.css实现动画

1.使用transition标签将需要实现动画的元素包裹起来

<button @click = 'isshow = !isshow'></button>
<transition>
    <div v-if = 'isshow'>御剑乘风来</div>
</transition>
  1. 使用animate.css提供的类名设置动画
<transition 
enter-active-class = 'animate fadeIn'
leave-active-class = 'animate fadeOut'
>
    <div v-if = 'isshow'>御剑乘风来</div>
</transition>

使用动画的钩子函数实现

// 1. 将需要实现动画的元素使用transition标签包裹起来
<transition>
    <div>我是需要过渡动画的元素</div>
</transition>

// 2. 在transition上注册实现动画的钩子函数,入场动画三个,出场动画三个
<transition 
@before-enter = 'beforeEnter'
@enter = 'enter'
@after-enter = 'afterEnter'
@before-leave = 'beforeLeave'
@leave = 'leave'
@after-leave = 'afterLeave'
>
    <div>我是需要过渡动画的元素</div>
</transition>

// 3. 在vue实例的methods中定义钩子函数
new Vue({
    el:'#app',
    data:{},
    methods:{
        // 入场动画初始状态设置
        beforeEnter(){
            // 一般使用JS设置执行动画元素的初始位置和其他样式属性
        },
        // 入场动画持续过程
        enter(el,done){
            // 1. 固定写法 迫使浏览器重绘 刷新动画
            el.offsetWidth
            // 2. 一般设置执行动画元素最终的位置和其他样式属性

            // 3. 固定写法 调用afterEnter函数
            done()
        },
        // 入场动画结束状态
        afterEnter(){
            // 设置动画元素回到初始状态
        },
        // 出场动画初始状态
        beforeLeave(){

        },
        // 出场动画持续状态
        leave(){

        },
        // 出场动画结束状态
        afterLeave(){

        }
    }
})

组件

组件就是对视图的封装,方便重复使用

模块是对功能逻辑的封装

注意:

  1. 定义组件时如果使用的是驼峰命名,那么使用组件时需要将驼峰的大写字母转成小写,并且用-连接两个单词
Vue.component('myCom',{
    template:'<div>我是一个驼峰命名的组件</div>'
})
// 使用
<my-com></my-com>
  1. 组件的template属性中的模版内部如果有多个元素,必须被包含在唯一的一个根元素中
<template>
    <div>
        <p>我是p元素</p>
        <span>我是span元素</span>
    </div>
</template>
  1. 子组件使用components属性进行定义,定义好的子组件只能在父组件的模板中使用
<template id='father'>
    <div>
        <son></son>
    </div>
</template>
// 父组件
Vue.component('father',{
    template:'#father',
    components:{
        // 子组件
        son:{
            template:'<div>我是son组件</div>'
        }
    }
})

组件的三种定义方式

  • vue.extend()定义
// 1. 使用vue.extend()定义组件模板
var dv = Vue.extend({
    template:'<div>我是一个组件</div>'
})

// 2. 使用Vue.component()注册组件
Vue.component('com',dv)

// 3. 在Vue托管区域像使用普通HTML标签一样使用组件
<com></com>

  • vue.component()定义
// 1. 使用Vue.component定义组件
Vue.component('com',{
    template:'<div><p>我是一个组件中的元素</p><span>我也是组件中的元素</span></div>'
})

// 2. 使用组件
<com></com>
  • 使用template标签定义模板
// 1. 使用Vue.component定义组件,并且使用选择器选择模板
Vue.component('com',{
    template:'#temp'
}) 

// 2. 使用template标签定义模板,并且给template标签添加id
<template id='tmpl'>
    <div>
        <p>我是p元素</p>
        <span>我是span元素</span>
    </div>
</template>

// 3. 使用组件
<com></com>

is属性和component实现组件切换

// comname 是哪个组件名,则component就会被渲染成哪个组件
// component 就是一个占位标签 
<component :is='comname'></component>

new Vue({
    el:'#app',
    comname:'login'
})

父子组件传值

父向子传值

// 1. 先在父组件中定义好要传递的数据
new Vue({
    el:'#app'
    data:{
        msg:'我是要传递给子组件的数据'
    },
    components:{
        son:{
            template:'<div>我是子组件{{message}}</div>',
            props:['message']
        }
    }
})

// 2. 在父组件中使用子组件的时候,用绑定属性的方式将父组件中的数据传递给子组件
<div id='app'>
    <son v-bind:message = 'msg'></son>
</div>

// 3. 在子组件中定义一个props属性,该属性是一个数组,数组中定义用于接收传过来的变量。这个变量
// 和第二步绑定的这个属性同名
son:{
    template:'<div>我是子组件</div>',
    props:['message']
}

子向父传值

发布订阅者 设计模式

// 1. 定义好父子组件,定义好子组件需要传递给父组件的数据
new Vue({
    el:'#app'
    components:{
        son:{
            template:'<div>我是子组件{{message}}</div>',
            data:function(){
                return {
                    msg:'传给父组件的数据'
                }
            }
        }
    }
})

// 2. 在子组件中使用this.$emit触发一个自定义的方法名,然后传递数据
// 第一个参数就是自定义的方法名
// 第二个参数就是需要传递给父组件的数据
this.$emit('func',this.msg)

// 3. 在父组件中使用子组件时,绑定一个事件,事件名称和子组件触发的方法名同名
<div id='app'>
    <son @func = 'getmsg'></son>
</div>

// 4. 在父组件的methods中定义一个事件处理函数
methods:{
    getmsg:function(data){
        // data就是子组件传过来的数据
    }
}

非父子组件传值

使用event bus(事件总线):利用一个共享的vue实例对象来进行数据的传递. 同时采用的是 发布-订阅者模式

// componentA  componentB进行数据传递(B->A)

// **定义一个公有的Vue实例,保证两个组件都能够使用,一般在一个单独的js文件中导出一个Vue实例,
然后在componentA和componentB组件中导入该实例进行使用**

export default var vm = new Vue();

// componentB:(B组件时需要传递数据的组件)

// 1. 进行事件的发布(注册)

vm.$emit('事件名称','需要传递的数据')

// 2. 事件的触发(用于发布事件)

send(){
    this.$emit('事件名称','需要传递的数据')
}

// componentA:(A组件是接收数据的组件)

// 1. 订阅事件

vm.$on('事件名称',function(data){
        // 此处的data就是 发布组件中传递过来的数据
})

生命周期钩子函数

回调函数:一个函数被当做参数进行传递的时候,称作这个函数为回调函数

构造函数:一个函数被new 关键字引导执行的时候,称作这个函数为构造函数

钩子函数: 一个应用程序或者框架内部提前定义好的一批函数,这些函数会在特定的时间段自动执行

生命周期: 一个程序会存在初始化 - 运行 - 销毁等阶段,这些阶段统称为该程序的生命周期

new Vue({
    el:'#app',
    data:{},
    methods:{},
    beforeCreated(){},
    // data中的数据和methods中的方法已经初始化完毕会去自动执行created方法
    created(){
        // 用于发生数据请求,也可以初始化一些数据
    },
    beforeMount(){},
    // 真实DOM已经渲染完毕会执行mounted函数
    mounted(){
        // 操作真实DOM
    }
    beforeUpdate(){},
    // data中的发生了变化而且被重新渲染到了界面上时才会执行
    updated(){
        // 数据更新后重新操作DOM
    },
    // 实例销毁之前,实例上面的各种属性和方法都还可以正常访问,通常可以在这里手动回收一些页面没有被释放的变量,比如清楚定时器的操作。
    beforeDestroy(){},
    // 实例已经从内存中被销毁
    destroyed(){}
})

路由

后端路由:监听不同的URI(地址),做不同的请求处理

前端路由:是专门为SPA(单页应用程序)服务,也是监听不同的地址,做页面的切换

基本使用步骤

1. 创建路由对象并配置路由规则
// 1.1 创建组件模板对象
var login = {
    template:'<div>登录</div>'
}
var register = {
    template:'<div>注册</div>'
}
// 1.2 创建路由对象并配置路由规则
var router1 = new VueRouter({
    // routes用来存放路由规则,每个路由规则都是一个对象
    routes:[
        // path: 页面#后面的地址
        // component 需要显示的组件对象
        {path:'/',redirect:'/login'},
        {path:'/login',component:login},
        {path:'/register',component:register}
    ]
})

// 1.3 将创建处理的路由对象和Vue进行绑定
new Vue({
    el:'#app',
    // 将vuerouter对象注册到Vue内部,以保证在托管区域中可以使用VueRouter内部提供的组件以及其他属性和方法
    router:router1
})

2. 使用<router-view>进行占位
<div id='app'>  
    <router-view></router-view>
<div>

3. 使用<router-link>设置跳转路径
<router-link to='/login'>登录</router-link>

路由传参

query传参

// 1. 在跳转路径后面使用查询字符串拼接参数
<router-link to = '/login?name=zs$age=18'>登录</router-link>

// 2. 在路由对应的组件内部使用`this.$route.query`获取参数
this.$route.query.name // zs
this.$route.query.id // 18

params传参

// 1. 更改路由规则用于匹配参数
new VueRouter({
    routes:[
        // :id用于匹配/login/13后面的参数13
        {path:'/login/:id',component:login}
    ]
})
// 2. 在跳转路径后面使用/拼接参数
<router-link to = '/login/13'>登录</router-link>

// 3. 在路由对应组件内部使用`this.$route.params`获取参数
var login = {
    template:'<div>登录组件{{this.$route.params.id}}</div>',
    created(){
        console.log(this.$route.params.id) // 获取到的就是13
    }
}

嵌套路由

// 1. 在父路由内部使用children属性配置子路由规则,子路由规则对象中的path属性不要 '/' 
// 2. 在父路由规则对应的组件模板中添加router-view用于显示子路由规则对应的组件
// 3. 在<router-link>中设置跳转路径(将父路由和子路由的path拼接)

webpack的学习

什么是webpack? 一个基于Node的前端构建工具,可以实现对项目的打包(构建),主要解决文件(模块)之间的依赖,高级代码的转译,文件(模块)的合并和压缩等问题。

基本使用

  • webpack3.~版本安装使用
// 1. 全局安装webpack
npm i webpack@3.10.0 -g

// 2. 使用
webpack 入口文件 输出文件
webpack ./src/main.js ./dist/build.js
  • webpack4.~版本安装使用
// 1. 全局安装webpack
npm i webpack  -g
npm i webpack-cli -g

// 2. 使用
webpack 入口文件 -o 输出文件 --mode development/production
webpack ./src/main.js -o ./dist/build.js --mode development

webpack配置文件使用

webpack4.x不需要定义入口和输出参数,默认src/main.js为入口文件,dist/index.js为输出文件。

但是需要配置模式参数mod

// 1. 在项目根目录新建webpack.config.js,并设置 打包的入口文件 和 输出文件
module.exports = {
    // 入口文件(绝对路径)
    entry: path.join(__dirname,'./src/main.js'),
    // 输出文件
    output: {
        path: path.join(__dirname,'./dist'), // 输出文件目录
        filename: 'build.js' // 输出文件名称
    }
    // mode:"development"  // webpack4.x配置此选项
}

// 2. 执行打包命令
webpack

webpack-dev-server的使用

帮助在项目根目录搭建一个服务器,该服务器可以帮我们托管代码,同时监听所有文件的变化然后自动执行webpack编译命令以及自动刷新浏览器

命令行方式

--hot: 热更新,可以局部更新文件
--open: 自动打开浏览器
--port: 配置端口号
--inline: 刷新浏览器

// 1. 局部安装webpack-dev-server和webpack
npm i webpack-dev-server webpack --save-dev

// 2. 在package.json的scripts节点中添加启动命令
"scripts":{
    "dev":"webpack-dev-server --inline --open --hot--port 8888"
}

// 3. 在项目根目录运行项目
npm run dev

配置文件方式

// 1. 在webpack.config.js配置文件中添加如下配置
devServer:{
    open: true,
    port: 8888,
    hot: true
}

// 2. 如果设置了 hot:true 这个属性,则需要配置热更新插件
// 2.0 引入webpack模块
const webpack = require('webpack')
// 2.1 配置热更新插件
plugins: [
    new webpack.HotModuleReplacementPlugin()
]

// 3. package.json中配置启动命令
"scripts":{
    "dev":"webpack-dev-server"
}

html-webpack-plugin的使用

可以根据指定的HTML模板文件生成一个HTML页面,并且在HTML页面中自动引入打包好的js文件

// 1. 安装html-webpack-plugin
npm i html-webpack-plugin --save-dev

// 2. 在webpack.config.js中的plugins节点中配置插件
// 2.1 导入html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin')
// 2.2 配置插件
plugins:[
    new htmlWebpackPlugin({
        template:path.join(__dirname,'./src/index.html'),// 需要生成的HTML的模板文件
        filename:'index.html' // 生成的HTML文件的名称
    })
]

css-loader处理CSS文件

解析处理文件后缀名为.css的文件

// 1. 安装style-loader css-loader
npm i style-loader css-loader --save-dev

// 2. 在webpack.config.js中的moudle节点中配置解析规则
module:{
    rules:[
        {
            test:/\.css$/,
            use:['style-loader','css-loader']
        }
    ]
}

less-loader处理less文件

解析处理文件后缀名为.less的文件

// 1. 安装less less-loader
npm i less less-loader --save-dev

// 2. 在webpack.config.js中的moudle节点中配置解析规则
module:{
    rules:[
        {
            test:/\.less$/,
            use:['style-loader','css-loader','less-loader']
        }
    ]
}

scss-loader处理scss文件

解析处理文件后缀名为.scss的文件

// 1. 安装node-sass sass-loader
npm i node-sass sass-loader --save-dev

// 2. 在webpack.config.js中的moudle节点中配置解析规则
module:{
    rules:[
        {
            test:/\.scss$/,
            use:['style-loader','css-loader','sass-loader']
        }
    ]
}

url-loader处理图片等资源文件

解析处理项目中引入的图片、字体图标、音视频等资源文件

// 1. 安装file-loader ulr-loader
npm i file-loader ulr-loader --save-dev

// 2. 在webpack.config.js中的moudle节点中配置解析规则
module:{
    rules:[
        {
            test:/\.(png|jpg|gif)/,
            use:'url-loader?limit=20000&name=[hash:8]-[name].[ext]'
            // 当需要打包的文件小于limit的值,会将图片转换成base64字符串在build.js中进行引用
            // 当需要打包的文件大于limit的值,会将图片打包到输出目录中
            //一般比较小的图片才需要被转成base64,所以该值不宜太大

            // name=[hash:8]-[name].[ext]表示将来打包出来的文件名称以8位hash值和原来的名称进行拼接,文件扩展名不变
        }
    ]
}

babel的使用

解析webpack默认不能处理的JS

// 1. 安装babel-core babel-loader babel-plugin-transform-runtime
npm i babel-core babel-loader babel-plugin-transform-runtime --save-dev

// 2. 安装babel-preset-env babel-preset-stage-0
npm i babel-preset-env babel-preset-stage-0 --save-dev

// 3. 在webpack.config.js中的moudle节点中配置解析规则
module:{
    rules:[
        {
            test:/\.js$/,
            use:'babel-loader',
            exclude:/node_modules/ //排除掉node_modules文件夹,让babel-loader不去解析node_modules文件夹中的js文件
        }
    ]
}

// 4. 在项目根目录新建.babelrc文件,书写如下配置
{
    "presets":["env","stage-0"],
    "plugins":["transform-runtime"]
}

webpack中使用Vue

// 1. 安装vue vue-loader vue-template-compiler
npm i vue --save
npm i vue-loader vue-template-compiler --save-dev

// 2. webpack.config.js中配置解析规则
module: {
    rules: [
        {
            test:/\.vue$/,use:'vue-loader'
        }
    ]
}

// 3. 在index.html中加入一个需要Vue托管的区域
<div id="app"></div>

// 4. 新建App.vue组件
<template>
    <div>vue组件</div>
</template>
<script>
export default {

}
</script>
<style>
</style>

// 5. main.js中导入vue的包,渲染App.vue组件
import Vue from 'vue'
import App from './App.vue'

new Vue({
    el:'#app',
    render:c=>c(App) //将App组件渲染到id为app的区域中
})

webpack 中集成vue-router

// 1. 安装vue-router
npm i vue-router --save

// 2. 在main.js中导入vue-router并实例化路由添加路由规则
import VueRouter from 'vue-router'
Vue.use(VueRouter) // 保证在vue的组件中可以使用vue-router提供的组件 如<router-view> <router-link>

const router = new VueRouter({
    routes: [
        {
            path: '/login', component: login
        }
    ]
})

// 3. 将实例化的router绑定到Vue
new Vue({
    el: '#app',
    render: c => c(App),
    router // 将router实例绑定到Vue上 以保证vue实例中可以访问$route $router等属性
})

// 4. 在App.vue中添加路由占位router-view标签
<router-link to = "/login">登录<router-link>
<router-view></router-view>

--save和--save-dev

// 项目开发期间需要安装的依赖
// --save-dev 会将安装的包名以及版本号记录到package.json文件中的devDependencies节点中
npm install webpack --save-dev 等价于 npm install webpack -D

// 项目上线后需要安装的依赖
// --save 会将安装的包名以及版本号记录到package.json文件中的dependencies节点中
npm i webpack --save 等价于 npm i webpack -S

npm i 会将所有在package.json文件中的devDependencies节点和dependencies节点内所有的依赖包全部安装一遍
npm i --save-dev 只会下载devDependencies中的所有依赖包
npm i --save 只会下载dependencies中的所有依赖包

// 为什么安装包的时候要区分 --save 和 --save-dev
// 1. 使项目的阅读更加友好,便于理解项目结构
// 2. 安装对应阶段的包时更加方便

vue-cli脚手架的使用

// 1. 安装vue-cli脚手架
npm i vue-cli -g

// 2. 初始化项目模板
vue init webpack 项目名称
eslint(语法规范化插件) 不要安装  当安装之后只能按照ESLint中规定的语法格式去书写代码
e2e(测试框架) 不要安装
unit test(单元测试框架) 不要安装

// 3. 进入项目安装所有依赖
npm i

// 4. 运行
npm run dev

config/index.js中 17/18行改端口号和自动打开浏览器

Vuex的使用

Vuex是一个状态管理库,或者说是专为Vue应用程序开发设计的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

注:所谓状态,可以理解成项目中各个组件需要用到的数据。

Demo:https://gitee.com/UniverseKing/vuex-study

初始化公共状态

1. 安装vuex
npm i vuex --save

2. 入口文件中实例化Store
import Vuex from 'vuex'
Vue.use(Vuex)
var store = new Vuex.Store({
  // 1. 用于定义状态(公共数据),类似于Vue实例中的data方法
  state:{
      msg:'初始化的数据'
  },
  // 2. 用于修改状态,类似于Vue实例中methods
  mutations:{
      change(state,arg){
          // 更改状态
          state.msg = arg
      }
  },
  // 3. 用于获取数据(获取数据之前可以进行一些操作),类似于Vue实例中的过滤器和计算属性
  // getters 主要会用在跨组件传值
  // getters 中定义的方法内部依赖的数据发生变化会自动重新调用函数计算返回值
  getters:{
      fixmsg(state){
          return `${state.msg}----处理后的数据`
      }
  },
  // 4. actions和mutations都是定义对数据进行操作的方法,mutations中都是同步方法,mutations中定义异步方法
  // Action 提交的是 mutation,而不是直接变更状态。所以需要修改状态还是需要使用mutations中定义的方法

  // 从网络请求回来的数据需要保存到store
  // 发送网络请求的方法可以定义到actions中
  // actions主要用于处理异步方法
  actions:{
      asyncchange(context,arg){
          // 异步方法
          setTimeout(() => {
              context.commit('change',arg)
          }, 3000)
      }
  }
})

3. 注入到Vue实例中
new Vue({
    el:'#app',
    store
})

使用状态

1. 使用state中的数据
JavaScript: this.$store.state.msg
HTML: $store.state.msg

2. 使用getters中的数据
JavaScript: this.$store.getters.fixmsg
HTML: $store.getters.msg

变更状态(修改数据)

状态的变更必须使用mutations中提供的方法进行修改

1. 提交mutations中的变更方法
this.$store.commit('change','我是被修改的数据')

2. 异步提交actions中的变更方法
this.$store.dispatch('asyncchange','我是被异步修改的数据')

使用辅助函数

辅助函数可以直接将state,getters中的数据映射到Vue组件中的计算属性上,可以将mutations,actions中的方法映射到组件中的methods中,然后在组件中就可以直接以属性和方法的方式去使用数据和方法。

import { mapState } from 'vuex'
import { mapGetters } from 'vuex' 
import { mapMutations } from 'vuex'
import { mapActions } from 'vuex'

new Vue({
    computed:mapGetters([
        'count'
    ])
})
// ==>等价于
new Vue({
    computed:{
        count(){
            return this.$store.state['count']
        }
})

更多文章访问个人博客:http://www.lfanliu.top

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

推荐阅读更多精彩内容

  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 2,885评论 1 4
  • VUE介绍 Vue的特点构建用户界面,只关注View层简单易学,简洁、轻量、快速渐进式框架 框架VS库库,是一封装...
    多多酱_DuoDuo_阅读 2,684评论 1 17
  • 准备工作 一、安装脚手架 1、安装vue脚手架,这是构建vue项目的工具-g为全局安装​ npm insta...
    不困于情阅读 2,292评论 0 3
  • 1.功能技术: vue-resource : 后端 Vue-router : 前端 第三方库 : better-s...
    TTTXTTT阅读 752评论 0 2
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,043评论 0 29