文章目录
一、配置脚手架
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