Vue2(七):脚手架、ref属性、props配置项、mixin混入、插件、scoped样式

一、配置脚手架

Vue CLI(Vue Command Line Interface)Vue脚手架,Vue官方提供的标准化开发工具(开发平台)

安装node.js(安装保姆级别教程

第一步:输入命令npm config set registry=http://registry.npm.taobao.org 配置镜像站,全局安装@vue/cil ,命令行输入npm install -g @vue/cli。命令行输入vue,不报错及安装成功

第二步:切到要创建项目的目录,然后使用命令创建项目

vue create name

然后进入新建的name项目文件目录中,输入命令:npm run serve
得到的第一个url即是你的内置服务器,第二个是同局域网的其他人可以使用

在这里插入图片描述

脚手架配置完毕
如果要停止工程:连按两次Ctrl+C即可。

二、分析脚手架结构

├── node_modules 
├── public
│   ├── favicon.ico: 页签图标
│   └── index.html: 主页面
├── src
│   ├── assets: 存放静态资源
│   │   └── logo.png
│   │── component: 存放组件
│   │   └── HelloWorld.vue
│   │── App.vue: 汇总所有组件
│   │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件 
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

三、render函数

如果使用ES6的模块化引入Vue,那么默认引入的是vue.runtime.esm.js,其中esm是ES6 module简写

1.来看下main.js文件

该文件是整个项目的入口文件

//引入Vue
import Vue from 'vue'
//引入App组件,它是所有组件的父组件
import App from './App.vue'

//创建Vue实例对象:vm
new Vue({
  el: '#app',
  //render的中文意思是渲染
  render: h => h(App),
})

1.vue.js与vue.runtime.xxx.js的区别

(1)vue.js是完整版的Vue,包含:核心功能+模板解析器
(2)vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。为什么其他的.vue文件里写template标签就行呢?那是因为template写的是标签,而且在组件里,鱿鱼西专门儿又搞了个库去专门解析组件里的模板

2.render函数是干啥的?

render中文意思是渲染,render函数其实就扮演了vue中解析template模板的那块儿代码,把组件的内容解析一下子,渲染到页面上。我理解的感觉render就是个钩子(可能不是),当需要解析模板渲染页面时拿过来用一下,返回组件里的东西们,然后放到页面上。

(1)写个正常的renderi函数:

 render: function (createElement) {
    // console.log(typeof createElement);  //createElement是一个函数
    return createElement(App);
  }

(2)render函数写成箭头函数:

render: h => h(app)

这个render函数理解的感觉不是很透彻,后面再回来看看

3.为什么要引入残缺的vue呢?

vue.js是完整版的Vue,由核心和模板解析器组成。但是模板解析器占用的内存太大(占三分之一vue),开发完成后并不需要模板解析器。(模板解析器就像雇的贴瓷砖的工人,工人干完活儿就可以离开了,瓷砖就是那个Vue核心,就一直在那待着了)

四、脚手架的默认配置

vue.config.js配置文件

1、使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
2、使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

五、ref属性,顺便看看main.js和App.vue长啥样

被用来给元素或子组件注册引用信息(id的替代者)
应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
使用方式:

1、打标识:<h1 ref="xxx">.....</h1><School ref="xxx"></School>
2、获取:this.$refs.xxx

看看代码就明白了:

1.main.js

// 引入Vue
import Vue from 'vue';
// 引入App
import App from './App.vue';

Vue.config.productionTip = false;

// 创建一个Vue实例
new Vue({
    el: '#app',
    render: h => h(App)
});

2.MySchool
关于起名这块,想想非单文件组件,那里边我们写的时候,const School2 = Vue.extend({…}),然后下边components:{School1: School2}; 其实呢在单文件组件里,相当于是组件里写name:‘School2’,import School1,Vue开发者工具显示的是School2,但我们在代码里使用的是School1这个名字。

<template>
    <div>
        <h2>学校名称:{{ name }}</h2>
        <h2>学校地址:{{ address }}</h2>
    </div>
</template>

<script>
import Vue from 'vue';
const MySchool = Vue.extend({
    // 如果组件没写名字,那么就用的import后面起的名字
    data() {
        return {
            name: '前端',
            address: '杭州'
        }
    }
})
export default MySchool
</script>

3.App.vue

<template>
    <div>
        <h1 v-text="msg" ref="title"></h1>
        <button @click="showDom" ref="btn">点我输出上方的DOM元素</button>
        <MySchool111 ref="school" id="school"></MySchool111>
    </div>
</template>

<script>
// 如果组件没写名字,那么就用的import后面起的名字
import MySchool111 from './compoments/MySchool.vue';

export default {
    name: 'Appppp',  //这里如果写名字,开发者工具里看的就是这个名字
    components: {
        MySchool111
    },
    data() {
        return {
            msg: '从蓬莱写到仙台,哥们儿代码信手拈来'
        }
    },
    methods: {
        showDom() {
            // console.log(document.getElementById('title')); //这种写法拿不到组件
            console.log(this.$refs.title); //拿到h1真实DOM元素标签
            console.log(this.$refs.btn); //拿到button真实DOM元素标签
            console.log(this.$refs.school); //拿到组件的实例(MySchool的vc)

            //如果这么写,拿到的是组件template中的内容,相当于给根的div加了个id="school"
            console.log(document.getElementById('school'));
        }
    },
}
</script>

六、props配置项

功能:让组件接收外部传过来的数据。
props这个配置项就类似微信转账,App那边的标签里传过来,这边得接一下子

1.传递数据:

方式:在App.vue(或者父组件)中的组件标签中写属性:

<template>
    <div>
        <!-- 加个单项数据绑定,引号里面就不是字符串了,就是表达式了 -->
        <Student name="李四" sex="女" :age="20"></Student>
        <Student name="王五" sex="男" :age="20 + 1" />
        <!-- <Student name="zzy" sex="男" age="20" /> -->
    </div>
</template>

2.接收数据:

(1)简单接收,用的比较多
props: ['name', 'age', 'sex']
(2)限制类型接收

接收的同时对数据进行类型限制

props: {
    name: String,
    age: Number,
    sex: String
}
(3)限制类型、限制必要性、指定默认值

接收时同时对数据:进行类型校验+默认值指定+必要性限制

props: {
        name: {
            type: String,   //name的类型是字符串
            required: true  //name是必须填的
        },
        age: {
            type: Number, //age的类型时数值
            default: 99  //age可以不填,不填就是99
        },
        sex: {
            type: String,   //sex的类型是字符串
            required: true  //sex是必须填的
        }
    }

3.几个注意点

1、在传递数据的时候如果想实现正确收取数值数据,并且不想把props写那么复杂,可以加个v-bind:age="18",这样的话引号里边就不会是字符串了,而是当成js表达式执行,返回的结果就是数值

2、props中的内容优先级最高,先接这里边的数据放vc里,再去读data里的数据,若data中数据有重复则优先使用props中的数据,不会覆盖

3、props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告(能修改成功但是不建议改)。

组件是可复用的,假设该子组件被复用了n次,当某一个组件意外地更改了其接受到的props数据 ----> 意味着,同时更改了父组件中相对应的属性值 ----> 意外地更改其它(n-1)个子组件中的 props数据,引起混乱。(我当前组件就想用最新的值,但是其他组件就想保存原始值,这不就乱套了吗)所以我们不应该在子组件中直接更改其props数据!。(其实有时候可以改,那就是props传过来的值是不一样的,是通过v-for遍历出来的,组件的数据不会相互影响,这种情况我觉得可以改)

若业务需求确实需要修改,那么请复制props的内容到data中一份(data中新建个名字),然后去修改data中的数据,同时把data中的东西呈现到页面上去,具体看下边的代码

4.子组件Student.vue代码

这里提醒一下,data中尽量不要用this

<template>
    <div>
        <h1>{{ msg }}</h1>
        <h2>学生名称:{{ name }}</h2>
        <h2>学生性别:{{ sex }}</h2>
        <!-- 实现年龄+1 要加v-bind把引号里的东西变成js表达式,否则是字符串+1-->
        <!-- <h2>学生年龄:{{ age*1+1 }}</h2> 强制类型转换一下-->
        <h2>学生年龄age:{{ age + 1 }}</h2>
        <h2>学生年龄myAge:{{ myAge + 1 }}</h2>
        <button @click="updateAge">尝试修改收到的年龄</button>
    </div>
</template>

<script>
export default {
    name: 'Student',
    data() {
        return {
            msg: '从蓬莱写到仙台,哥们儿代码信手拈来',
            //想要修改age,就要用一个新的变量myAge来接收传进来的值
            //然后页面显示myAge就能实现修改,props里的东西是只读的
            myAge: this.age
            // name: 'zzy',
            // age: 18,
            // sex: '男'
        }
    },
    methods: {
        updateAge() {
            // this.age++;  //会报错但是能改但是不建议改
            this.myAge++;
        }
    },
    //props这个配置项就类似微信转账,App那边的标签里传过来,这边得接一下子
    //props中的内容优先级最高,先接这边的数据放vc里,再去读data,若有重复不会覆盖
    props: ['name', 'age', 'sex']
}
</script>

七、mixin(混入)

功能:可以把多个组件共用的配置提取成一个混入对象

使用方式:

1.第一步定义混合:

定义在另一个js文件中,这里定义在mixin.js中

export const hunhe1 = {
    methods: {
        showName() {
            alert(this.name);
        }
    },
    mounted() {
        console.log('混合里的mounted优先调用');
    }
}

2.第二步使用混合:

全局混入:Vue.mixin(xxx),全局混合不用引入,自动就搞到所有东西上了
​局部混入:mixins:['xxx']

1、先在组件中引入

import { hunhe1 } from '../mixin'

2、在组件中使用mixins: [hunhe1]

<template>
    <div>
        <h2 @click='showName'>学校名称:{{ name }}</h2>
        <h2>学校地址:{{ address }}</h2>
    </div>
</template>

<script>
//引入一个混合
import { hunhe1 } from '../mixin'
export default {
    name: 'School',
    data() {
        return {
            name: '前端',
            address: '杭州'
        }
    },
    mixins: [hunhe1],
    mounted() {
        console.log('组件里单独写mounted比mixin中的mounted后调用')
    }
}
</script>

注意:
1、混合里的mounted优先调用,组件里单独写mounted比mixin中的mounted后调用
2、组件里原来有的数据,在混合中写不会覆盖原数据;组件里原来没有的数据,混合中写会添加过去和原数据合并

八、插件

1.插件是干啥的?

功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。

2.定义插件

可以在另一个js中配置插件,然后通过import引入到main.js中
看看下面的代码,复习复习之前的知识

const plusobj = {
    install(Vue, x, y, z) {
        console.log(Vue);  //第一个参数是Vue构造函数
        console.log(x, y, z); //后面的参数是使用者传进来的东西123

        //1.定义一个全局过滤器
        Vue.filter('mySlice', function (val) {
            return val.slice(0, 4);  //返回值别忘了
        });

        //2.定义一个全局自定义指令,元素默认获取焦点
        Vue.directive('fbind', {
            bind(el, binding) {
                el.value = binding.value;
            },
            inserted(el) {
                el.focus();
            },
            update(el, binding) {
                el.value = binding.value;
            }
        })

        //3.定义一个全局混合,不用引入就能给所有的vm和vc
        Vue.mixin({
            data() {
                return {
                    x: 1,
                    y: 2
                }
            }
        })

        //4.给Vue的原型对象添加实例方法,vm和vc都能用
        Vue.prototype.hello = () => { alert('hello!') }
    }
}

export default plusobj;

3.使用插件Vue.use()

use的作用就是帮忙调用插件对象中的install方法,而且还可以传一些参数给install函数。

//在main.js中引入插件并起个名儿
import plugins from './plugins';
//使用插件,要在new Vue之前使用
Vue.use(plugins, 1, 2, 3);

九、scoped样式

作用:让样式在局部生效,防止冲突。
写法:<style scoped>

指定使用 less写法:<style lang="less">,不写默认css

备注:
查看webpack所有版本 当前项目文件目录>npm view webpack versions
安装less版本7当前项目文件目录>npm i less-loader@7
alert(‘hello!’) }
}
}

export default plusobj;


### 3.使用插件`Vue.use()`

use的作用就是帮忙调用插件对象中的install方法,而且还可以传一些参数给install函数。

```js
//在main.js中引入插件并起个名儿
import plugins from './plugins';
//使用插件,要在new Vue之前使用
Vue.use(plugins, 1, 2, 3);

九、scoped样式

作用:让样式在局部生效,防止冲突。
写法:<style scoped>

指定使用 less写法:<style lang="less">,不写默认css

备注:
查看webpack所有版本 当前项目文件目录>npm view webpack versions
安装less版本7当前项目文件目录>npm i less-loader@7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值