Vue 学习 第六篇 axios

axios

一、使用 axios

vue为了开发方便,为我们提供了vue全家桶:vue, vuex, vue-router, vue-resource.

  在ES5开发中,我们使用vue-resource发送异步请求,但是在ES6中,作者不再维护vue-resource,而是建议我们使用axios框架发送异步请求

注意:axios不是vue家族的插件,因此不能用vue.use方法来安装。

axios的使用方式与jquery类似,提供了一些简便方法:

  get(url, config) 发送get请求

    url表示请求地址,

    config表示配置项(我们可以定义parmas,headers等)

  post(url, data, config) 发送post请求

    url表示请求地址,

    data:表示携带的数据,

    config:表示配置项(我们可以定义parmas,headers等)

注意:不论是get请求还是post请求,都可以携带query数据,query数据可以在两个位置添加

  1 在url上添加query数据。

  2 在config配置中的params属性中传递。

axios实现了promise规范,因此,通过then方法监听结果

  第一个参数表示成功时候的回调函数:参数表示请求对象,其中data属性表示返回的数据

    当多次使用then方法的时候,前一个then方法的返回值,将作为后一个then方法的参数。

  第二个参数表示失败时候的回调函数,也可以通过catch方法监听失败

axios提交的数据,默认使用的是json格式。

  我们可以通过修改headers中的Content-Type字段,来模拟表单提交。

  模拟表单: application/x-www-form-urlencoded

二、安装 axios

  axios不是vue家族的插件,因此不能通过Vue.use方法来安装

  所谓的安装就是让每一个组件可以获取,使用更方便。

  所有的组件都继承了Vue类,如果Vue的原型具有axios对象,那么每一个组件(包括vue实例)都可以获取axios了。

  所以对于非vue家族的插件我们可以通过拓展其原型的方式来安装。
  工作中,为了语义化,我们常常将其命名为 $http.

webpack.cofig.js 运行指令 webpack -w



module.exports={
    // 模式
    mode:'development',
    // 解决方法
    resolve:{
        alias:{
            'vue$':'vue/dist/vue.js'
        },
        extensions:['.js','.jsx','.css']
    },
    // 入口文件
    entry:{
        '00':'./modules/00.js',
        '01':'./modules/01.js',
        '02':'./modules/02.js',
        '03':'./modules/03.js',
        '04':'./modules/04.js',
        '05':'./modules/05.js',
        '06':'./modules/06.js',
        '07':'./modules/07.js',
        '08':'./modules/08.js',
        '09':'./modules/09.js',
    },

    // 发布
    output:{
        // 文件位置
        filename:'./[name].js'
    },

    // 编译 模块
    module:{
        // 记载及
        rules:[
             // css
             {
                test:/\.css$/,
                use:['style-loader','css-loader']
            },
            // less
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            // scss 
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    },

    // 配置服务器
    devServer:{
        // 端口号
        port:8081,
        // 自动打开浏览器
        open:true,
        // 做跨域请求代理
        proxy:{
            // 08.js 中的 get 请求地址
            '/data/test':{
                // 目标地址
                target:'https://c.y.qq.com/splcloud/fcgi-bin/gethotkey.fcg',
                // 修改地址
                pathRewrite:{
                    '^/data/test':''
                },
                // 不校验 https
                secure:false
            }
        }

    }
}

2.1 axios 模拟 get 请求

01 axios 模拟 get 请求.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <hr>
        <home></home>
    </div>

    <script src="/dist/01.js"></script>
</body>
</html>

01 .js



import Vue from 'vue';

// 利用 axios  请求接口数据
import axios from 'axios';

let Home = Vue.extend({
    template:`
        <div>
            <h6>子组件通过 get 获取的数据 ---  {{msg}}</h6>
        </div>
    `,
    data(){
        return{
            msg:""
        }
    },
    // 创建完成
    created(){
        // 发送请求
        axios.get("/data/demo.json?color=red",{
            // 传递 query 的第二种方式
            params:{
                num:100
            }
        })
        // then 方法监听失败和成功
        // .then(
        //     // 成功
        //     res => console.log(res),
        //     // 失败
        //     err => console.log('err',err)
        // )

        // 监听失败
        // .catch(err=>console.log(err,"err"))

        // 多次订阅 then 方法
        // .then(res => res.data)
        // .then(data =>console.log(data))

        // 工作中,订阅一次就够了,常常解构再使用
        .then(({ data })=>{
            console.log(data,"解构的数据");

            // 存储数据
            this.msg = data.title;
        })
    }
})

let app = new Vue({
    el:"#app",
    data:{
        msg:"hello page"
    },
    components:{
        'home':Home
    }
})

根目录下的 app.js 运行指令 : nodemon app.js


// 引入 express
let express = require('express');

// 引入 ejs 
let ejs = require('ejs');

// 创建应用
let app = express();

// 更改 ejs 默认拓展名
app.engine('.html',ejs.__express);

// 静态化
app.use('/dist/',express.static('./dist/'));

// 将自定义的 json 数据进行静态化
app.use('/data/',express.static('./data/'));

// 定义 post 请求
app.post('/demo',(req,res)=>{
    res.json({ msg:'你好 DaZhaXie' })
})

// 配置路由
// app.get('*',(req,res)=>{
//     // 渲染模板
//     // 默认是 views  所以这里需要跳出

//     // 定义子路由的显示
//     // res.render('../03 定义子路由.html')

//     // 定义   子路由导航+过渡+滚动条
//     // res.render('../04 路由导航+过渡+滚动条.html')

//     // 实现路由的守卫
//     // res.render('../05 路由守卫.html')

//     // 实现 axios
//     // res.render("../06 axios.html")
// })

app.get('/',(req,res)=>{
    // axios  get 请求
    res.render("../01 axios  get 请求.html")

    // axios post 请求
    // res.render("../07 axios post 请求.html")
})

// 启动服务
app.listen(3000);

效果图
在这里插入图片描述

2.2 axios 模拟 post 请求

02 axios post 请求.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <div id="app">
        <h1>{{msg}}</h1>
        <hr>
        <home></home>
    </div>
    <script src="/dist/02.js"></script>
</body>
</html>

02 .js


import Vue  from 'vue';

import axios from 'axios';

// 如何安装  非 vue 家族的插件
// 安装 axios
// Vue.prototype.dzx = axios;
// 为了语义化,将名字定义成 $http
Vue.prototype.$http = axios

let Home = Vue.extend({
    template:`
        <div>
            <p>子组件 axios 的 post 请求 ---- {{msg}}</p>
        </div>
    `,
    data(){
        return{
            msg:''
        }
    },

   created(){
       console.log(this,this.$http);
    // 发送 post 请求传递数据
    // axios.
    // 直接使用
    this.$http.post('/demo?num=100',{  color:'green'},{
        // 传递 query 数据
        params:{
            msg:'hello  YCHH'
        },
        // 模拟表单传递数据的格式
        headers:{
            'Content-Type':'application/x-www-form-urlencoded;charset=utf-8'
        }
    })

    // 订阅消息  返回数据
    .then(({ data })=>{
        console.log(data,"返回的data 数据");
        this.msg = data.msg
    })
   }
})

let app = new Vue({
    el:"#app",
    data:{
        msg:"hello page",
    },
    components:{
        'home':Home
    }
})

app.js


// 引入 express
let express = require('express');

// 引入 ejs 
let ejs = require('ejs');

// 创建应用
let app = express();

// 更改 ejs 默认拓展名
app.engine('.html',ejs.__express);

// 静态化
app.use('/dist/',express.static('./dist/'));

// 将自定义的 json 数据进行静态化
app.use('/data/',express.static('./data/'));

// 定义 post 请求
app.post('/demo',(req,res)=>{
    res.json({ msg:'你好 DaZhaXie' })
})

// 配置路由
// app.get('*',(req,res)=>{
//     // 渲染模板
//     // 默认是 views  所以这里需要跳出

//     // 定义子路由的显示
//     // res.render('../03 定义子路由.html')

//     // 定义   子路由导航+过渡+滚动条
//     // res.render('../04 路由导航+过渡+滚动条.html')

//     // 实现路由的守卫
//     // res.render('../05 路由守卫.html')

//     // 实现 axios
//     // res.render("../06 axios.html")
// })

app.get('/',(req,res)=>{
    // axios  get 请求
    // res.render("../06 axios  get 请求.html")

    // axios post 请求
    res.render("../02 axios post 请求.html")
})

// 启动服务
app.listen(3000);

效果图
在这里插入图片描述

三、跨域请求代理

  让我们在本地开发中可以使用线上的数据。webpack-dev-server支持跨域请求代理技术

  我们通过devServer配置项,定义webpack-dev-server的配置

    port定义端口,

    host定义域名,

    open是否自动打开浏览器

    proxy定义跨域请求代理

      key 表示代理的请求

      value 表示代理的配置对象

        target 表示目标地址

         pathRewrite 表示是否重写路径

        secure 是否对https协议校验。

再前提 要安装好 webpack 的全家桶
在这里插入图片描述

前提 修改 webpack.config.js 文件

开启两个终端 运行 一个 :webpack -w 一个 webpack-dev-server

运行 webpak-dev-server 的 时候也要看好 webpack 的端口号



module.exports={
    // 模式
    mode:'development',
    // 解决方法
    resolve:{
        alias:{
            'vue$':'vue/dist/vue.js'
        },
        extensions:['.js','.jsx','.css']
    },
    // 入口文件
    entry:{
        '00':'./modules/00.js',
        '01':'./modules/01.js',
        '02':'./modules/02.js',
        '03':'./modules/03.js',
        '04':'./modules/04.js',
        '05':'./modules/05.js',
        '06':'./modules/06.js',
        '07':'./modules/07.js',
        '08':'./modules/08.js',
        '09':'./modules/09.js',
    },

    // 发布
    output:{
        // 文件位置
        filename:'./[name].js'
    },

    // 编译 模块
    module:{
        // 记载及
        rules:[
             // css
             {
                test:/\.css$/,
                use:['style-loader','css-loader']
            },
            // less
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            // scss 
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    },

    // 配置服务器
    devServer:{
        // 端口号
        port:8081,
        // 自动打开浏览器
        open:true,
        // 做跨域请求代理
        proxy:{
            // 08.js 中的 get 请求地址
            '/data/test':{
                // 目标地址
                target:'https://c.y.qq.com/splcloud/fcgi-bin/gethotkey.fcg',
                // 修改地址
                pathRewrite:{
                    '^/data/test':''
                },
                // 不校验 https
                secure:false
            }
        }

    }
}

03 跨域请求代理.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <hr>
        <home></home>
    </div>
    <script src="./dist/08.js"></script>
</body>
</html>

08 .js


import Vue from 'vue';

// 引入 axios
import axios from 'axios';

// 将 axios 安装到 vue 原型 方便使用
Vue.prototype.$http = axios;

let Home = Vue.extend({
    template: `
        <div>
            <h6>home ---- {{msg}}</h6>
        </div>
    `,
    data() {
        return {
            msg: ''
        }
    },
    created() {
        // 请求数据
        this.$http.get('/data/test', {
            // query 数据   此数据是携带 网站中的  query 数据
            params: {
                cv: 4747474,
                ct: 24,
                format: 'json',
                inCharset: 'utf - 8',
                outCharset: 'utf - 8',
                notice: 0,
                platform: 'yqq.json',
                needNewCode: 1,
                uin: 0,
                g_tk_new_20200303: 5381,
                g_tk: 5381,
            }
        })
            // 订阅消息  存储数据
            .then(({ data }) => {
                // 打印跨域请求代理的数据是否返回
                console.log(data, "跨域请求代理");
                this.msg = data.data.hotkey[0].k
            })
    }
})

let app = new Vue({
    el: "#app",

    data: {
        msg: "hello page"
    },
    components: {
        'home': Home
    }
})

默认打开 的 效果图
在这里插入图片描述

四、单文件组件

4.1 使用单文件组件

在vue中,组件包含模板,样式和脚本,但是我们定义组件的时候

  我们将模板写在了html文件中

  我们将样式写在了css | less | scss文件中

  我们将脚本写在js | es文件中

vue为了简化维护组件的成本,建议我们将这三个部分放在同一个文件中。

  通过template元素定义模板,最外层根元素只能有且只有一个

  通过style元素定义样式

  通过script元素定义脚本,我们要使用ES Module规范。只定义组件对象即可(Vue.extend参数对象)

  将文件的拓展名定义成.vue,这就是单文件组件。规范:将组件文件名称的首字母大写。

3.2 编译

浏览器不识别.vue文件,因此我们要将vue文件编译成js文件。

  我们通过/.vue$/匹配vue文件

  通过vue-loader加载机编译vue文件

单文件组件 + 编译 中的文件目录显示
在这里插入图片描述
webpack.config.js 文件

let { VueLoaderPlugin } = require('vue-loader');


module.exports={
    mode:'development',

    resolve:{
        alias:{
            vue$:'vue/dist/vue.js'
        },
        extensions:['.js','.jsx','.vue'],
    },
    entry:{
        'main':'./modules/main.js'
    },

    output:{
        filename:'./main.js'
    },

    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:'vue-loader'
            },
            {
                test:/\.css$/,
                use:['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    },
    // 功能在 plugins 中配置
    plugins:[
        // 使用 vue-loader
        new VueLoaderPlugin()
    ]
}

单文件组件.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>hello page --- {{msg}}</h1>
        <hr>
        <home></home>
    </div>

    <script src="./dist/main.js"></script>
    
</body>
</html>

./modules/main.js


import Vue from 'vue';

import Home from './Home';


let app = new Vue({
    el:"#app",

    data:{
        msg:"大闸蟹"
    },
    components:{
        'home':Home
    }
})

./modules/Home.vue 组件

<template>
    <div>
        <h6>home --- {{msg}}</h6>
        <hr>
        <demo :msg="msg" num="200"></demo>
    </div>
</template>


<style scoped>
h6{
    color: pink;
}
</style>

<script>
import Demo from './demo';
export default{
    components:{
        'demo':Demo
    },
    data(){
        return{
            msg:'hello home'
        }
    }
}
</script>

./modules/Demo.vue

<template>
    <div>
        <p>demo home --- {{msg}} --- {{num}}</p>
    </div>
</template>

<script>
export default{
    props:['msg','num']
}
</script>

效果图展示
![在这里插入图片描述](https://img-blog.csdnimg.cn/3d95b449e53c4b35b967f06fe71dfc3a.jpeg

3.3 ShadowDOM scoped

在组件中,我们定义的样式会污染其它的组件,我们可以通过shadowDOM技术来解决。

为style标签设置scoped属性,

  此时当前组件内部的元素会添加属性选择器,

  添加的样式也会设置属性选择器

shadowDOM样式:只对当前组件生效,对其它的组件无效。

注意:子组件只在容器元素上设置属性选择器,内部的元素没有被添加、

3.4 CSS 预编译

vue单文件组件内置了css预编译语言的解析器,我们可以直接使用这些语言。

  通过lang属性来设置

    lang=”less” 使用less

    lang=”scss” 使用scss

  注意:在4.0中配置中,要定义less|sass加载机。

webpack.config.js 中定义的加载机

  module:{
        rules:[
            {
                test:/\.vue$/,
                loader:'vue-loader'
            },
            {
                test:/\.css$/,
                use:['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    },

3.5 函数组件

我们在子组件中,为了接收父组件的数据,要使用props属性接收

vue为了简化这一过程,提供了函数组件:

  在模板中,设置functional属性即使一个函数组件

  此时我们就可以直接通过**“props.属性”**语法获取数据。

./modules/Demo.vue

<template functional>
    <div>
        <p>demo home --- {{props.msg}} --- {{props.num}}</p>
        {{props}}
    </div>
</template>

3.6 异步组件

我们将所有的资源都打包在一起会导致文件很大,浏览器加载很慢,影响用户体验。

  vue为了减小文件体积,可以使用异步组件的技术。我们需要什么组件,加载什么组件,

首次不需要加载的组件就不需要打包在一起了。有两种异步组件的形式

  第一种:在函数的返回值中,返回Promise对象 (异步创建)

    在Promise方法中,执行异步操作,操作结束之后返回组件

  第二种:在函数的返回值中,返回通过import方法异步引入组件(异步加载)

    为了使用import方法。我们要使用:babel-plugin-syntax-dynamic-import,babel的插件在

plugins中配置

  注意:4.0改动:默认支持异步引入(import方法)4.0默认向dist目录下发布,因此要设置

publicPath:表示引入静态资源相对位置。

异步组件的相关文件目录

webpack.config.js

let { VueLoaderPlugin } = require('vue-loader');


module.exports={
    mode:'development',

    resolve:{
        alias:{
            vue$:'vue/dist/vue.js'
        },
        extensions:['.js','.jsx','.vue'],
    },
    entry:{
        'main':'./modules/main.js'
    },

    output:{
        // 发布位置
        filename:'./main.js',

        // 修改引入的静态资源相对位置
        publicPath:'./dist/'
    },

    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:'vue-loader'
            },
            {
                test:/\.css$/,
                use:['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    },
    // 功能在 plugins 中配置
    plugins:[
        // 使用 vue-loader
        new VueLoaderPlugin()
    ]
}

异步组件.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>hello page --- {{msg}}</h1>
        <hr>
        <home></home>
    </div>

    <script src="./dist/main.js"></script>
    
</body>
</html>

./modules/main.js


import Vue from 'vue';

// 引入组件
// import Home from './Home';

// 三秒之后创建  home
// let Home = () => new Promise((resolve,reject)=>{
//     // 异步操作
//     setTimeout(()=>{
//         resolve({
//             template:`
//                 <div>
//                     <h4>3 秒之后创建的 home 组件</h4>
//                 </div>
//             `
//         })
//     },3000)
// })


// 异步组件加载
// 此时的 import 是一个方法
let Home = () => import('./Home')

let app = new Vue({
    el:"#app",

    data:{
        msg:"大闸蟹"
    },
    components:{
        'home':Home
    }
})

./modules/Home.vue

<template>
    <div>
        <h6>home --- {{msg}}</h6>
        <hr>
        <demo :msg="msg" num="200"></demo>
    </div>
</template>


<style scoped>
h6{
    color: pink;
}
</style>

<script>
import Demo from './demo';
export default{
    components:{
        'demo':Demo
    },
    data(){
        return{
            msg:'hello home'
        }
    }
}
</script>

./modules/Demo.vue

<template functional>
    <div>
        <p>demo home --- {{props.msg}} --- {{props.num}}</p>
        {{props}}
    </div>
</template>

效果图
在这里插入图片描述

3.7 拆分应用程序组件

  我们目前定义的vue实例化对象既包含模板,样式,脚本,也包含注册store, router等功能。因此vue实例化对象做了很多的事情。为了让vue实例化对象职责更加的单一,我们要将实例化对象中的模板,样式,脚本单独拆分出来,作为应用程序组件。这样实例化对象中,就只剩下注册store,router等功能了

  1 我们将应用程序组件定义成App.vue,在内部,通过template定义模板,通过style定义样式,通过script定义脚本。

  2 为了在实例化对象中渲染应用程序组件,vue提供了一个render方法,参数是一个渲染方法,可以用来渲染应用程序。

  3 为了让应用程序上树(渲染到页面中),vue提供了$mount方法,用来上树。参数表示css选择器。会将该选择器对应的元素作为容器元素。

  以后只需要在vue实例化对象中,注册路由,注册store等,实现一些功能即可。

注意:拆分的应用程序组件App.vue要注意:模板的根元素要设置id属性,与模板的id同值、
在这里插入图片描述

webpack.config.js

let { VueLoaderPlugin } = require('vue-loader');


module.exports={
    mode:'development',

    resolve:{
        alias:{
            vue$:'vue/dist/vue.js'
        },
        extensions:['.js','.jsx','.vue'],
    },
    entry:{
        'main':'./modules/main.js'
    },

    output:{
        // 发布位置
        filename:'./main.js',

        // 修改引入的静态资源相对位置
        publicPath:'./dist/'
    },

    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:'vue-loader'
            },
            {
                test:/\.css$/,
                use:['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    },
    // 功能在 plugins 中配置
    plugins:[
        // 使用 vue-loader
        new VueLoaderPlugin()
    ]
}

拆分应用程序.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="./dist/main.js"></script>
    
</body>
</html>

./modules/main.js


import Vue from 'vue';

import App from './App';
let app = new Vue({
    // 渲染
    // render:function(h){
    //     return h(App)
    // }

    // render:(h)=>{
    //     return h(App)
    // }

    // 简化
    render: h => h(App)
// 上树
}).$mount('#app')

./modules/App.vue

<template>
<!-- 容器元素属性与页面中的容器元素属性要一致 -->
    <div id="app">
        <h1>hello page --- {{msg}}</h1>
        <hr>
        <home></home>
    </div>
</template>

<style>
</style>

<script>
// 引入组件
import Home from './Home';

export default{
    el:"#app",

    data(){
        return{
             msg:"大闸蟹"
        }
    },
    components:{
        'home':Home
    }
}

</script>

./modules/Home.vue

<template>
    <div>
        <h6>home --- {{msg}}</h6>
        <hr>
        <demo :msg="msg" num="200"></demo>
    </div>
</template>


<style scoped>
h6{
    color: pink;
}
</style>

<script>
import Demo from './demo';
export default{
    components:{
        'demo':Demo
    },
    data(){
        return{
            msg:'hello home'
        }
    }
}
</script>

./modules/Demo.vue

<template functional>
    <div>
        <p>demo home --- {{props.msg}} --- {{props.num}}</p>
        {{props}}
    </div>
</template>

效果图
在这里插入图片描述

3.8 混合

混合就是对组件的模板,样式,数据,方法等相关功能的复用。

vue支持两种混合:全局混合,局部混合

全局混合

  全局混合会对所有的组件生效。通过Vue.mixin方法定义,参数就是继承的数据和方法等

局部混合
  局部混合只能对当前组件生效。

  在组件中通过mixins属性,实现对组件,数据,方法的继承

    是一个数组,每一个成员表示一个继承的对象,可以组件,可以是对象等。

注意:

如果多个数据之间出现同名的属性数据

  如果是模型中的数据和方法,后面的覆盖前面的。

  如果是生命周期方法,会暴露多个。并按照先后顺序依次执行。

我们继承之后,还可以重写被继承的数据,使用的时候,会优先使用重写的数据。

与组件不相关的数据和方法不会被组件继承。
在这里插入图片描述

webpack.config.js

let { VueLoaderPlugin } = require('vue-loader');

module.exports={
    mode:'development',

    resolve:{
        alias:{
            vue$:'vue/dist/vue.js'
        },
        extensions:['.js','.jsx','.vue'],
    },
    entry:{
        'main':'./modules/main.js'
    },

    output:{
        // 发布位置
        filename:'./main.js',

        // 修改引入的静态资源相对位置
        publicPath:'./dist/'
    },

    module:{
        rules:[
            {
                test:/\.vue$/,
                loader:'vue-loader'
            },
            {
                test:/\.css$/,
                use:['style-loader','css-loader']
            },
            {
                test:/\.less$/,
                use:['style-loader','css-loader','less-loader']
            },
            {
                test:/\.scss$/,
                use:['style-loader','css-loader','sass-loader']
            }
        ]
    },
    // 功能在 plugins 中配置
    plugins:[
        // 使用 vue-loader
        new VueLoaderPlugin()
    ]
}

混合继承.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="./dist/main.js"></script>
</body>
</html>

./modules/main.js


import Vue from 'vue';

import App from './App';

// 全局混合
Vue.mixin({
    // 周期方法
    created(){
        console.log('global',111,this);
    },
    // 数据
    data(){
        return{
            msg:'mixin message'
        }
    },
    dazhaxie:'hello'
})



new Vue({
    // 简化
    render: h => h(App)
// 上树
}).$mount('#app')

./modules/App.vue

<template>
<!-- 容器元素属性与页面中的容器元素属性要一致 -->
    <div id="app">
        <h1>hello page --- {{msg}}</h1>
        <hr>
        <home></home>
    </div>
</template>

<style>
</style>

<script>
// 引入组件
import Home from './Home';

export default{
    data(){
        return{
            //  msg:"大闸蟹"
        }
    },
    components:{
        'home':Home
    },
    created(){
        console.log('app created',this.dazhaxie);
    }
}

</script>

./modules/Home.vue


<script>
import Dzx from './Dzx';
export default{
    //局部混合
    mixins:[
        Dzx,
        {
            created(){
                console.log("局部继承方法");
            },
            data(){
                return{
                    msg:'局部继承的  msg'
                }
            }
        }
    ],
    data(){
        return{
            msg:'hello home'
        }
    },
    created(){
        console.log("hello created");
    }
}
</script>

./modules/Dzx.vue

<template>
<div>
    <h6>Dzx ---- {{msg}}</h6>
</div>
</template>

<style>
h6{
    color: blue;
}
</style>

<script>
export default{
    data(){
        return{
            msg:"波澄湖"
        }
    }
}
</script>

效果图
在这里插入图片描述

3.9 插件

vue允许我们自定义插件,实现对vue拓展的功能的复用。

我们封装好插件,就可以在不同的项目中,复用这些功能了。

定义插件

  插件就是一个函数或者包含install方法的对象

    第一个参数表示Vue类

    从第二个参数开始表示使用插件的时候,传递给插件的数据。
使用插件

  我们通过Vue.use方法来安装插件。

    第一个参数表示插件

    从第二个参数开始表示传递给插件的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大闸蟹~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值