安装和启动:
目录
脚手架文件结构
- ├── 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:包版本控制文件
main.js:该文件是整个项目的入口文件
App.vue:
index.html:
传统情况下js写法:
运行之后:(引入了一个残缺的Vue,没有模板解析器)
实际上在引入的时候,引入的是vue.runtime.esm.js(残缺的vue)
关于不同版本的Vue:
1.vue.js与vue.runtime.xxx.js的区别:
(1).vue.js是完整版的Vue,包含:核心功能+模板解析器。
(2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用
render函数接收到的createElement函数(这个函数可以改名)去指定具体内容。
两种解决方法:
1.使用render函数
2.引入带模板解析器的Vue
当引入残缺版的vue,还想配置具体的内容,就得使用render函数,当然上图写法可以使用箭头函数精简。
此时这里传入两个参数,是因为h1是html里面的内置元素,这个元素里面得写具体的内容,所以得穿第二个参数,但是如果说用的是组件,此时就不需要再写具体的内容,因为内容都在APP这个组件里面(不过在此之前需要import引入app组件)。
多说一句,render函数只需要在main.js中引入一次即可。
vue的默认配置文件隐藏了起来,在命令行使用 vue inspect > output.js 命令打包出来。
注意这种方式只是给你输出出来,让你看一下,并不是修改之后脚手架就变了。
默认配置下哪些东西不能改?
这些东西可以改 配置参考 | Vue CLI (vuejs.org)
在与 package.json同级目录下新建vue.config.js文件,对脚手架进行个性化定制。
不能预留空位,因为配置会将自定义的部分整合到默认配置文件中,要么就写好,要么就不写。
- module.exports = {
- pages: {
- index: {
- // 入口
- entry: 'src/index/main.js'
- }
- },
- // 关闭语法检查
- lineOnSave:false
- }
目录结构:
获取this的vc实例对象
顺着vc触发可以找到dom元素
正式获取
给School组件标签加ref,则获得School组件的vc实例对象
main.js
- //引入Vue
- import Vue from 'vue'
- //引入App
- import App from './App.vue'
- //关闭Vue的生产提示
- Vue.config.productionTip = false
-
- //创建vm
- new Vue({
- el:'#app',
- render: h => h(App)
- })
./components/School.vue
- <template>
- <div class="school">
- <h2>学校名称:{{name}}h2>
- <h2>学校地址:{{address}}h2>
- div>
- template>
-
- <script>
- export default {
- name:'School',
- data() {
- return {
- name:'尚硅谷',
- address:'北京·昌平'
- }
- },
- }
- script>
-
- <style>
- .school{
- background-color: gray;
- }
- style>
App.vue
- <template>
- <div>
- <h1 v-text="msg" ref="title">h1>
- <button ref="btn" @click="showDOM">点我输出上方的DOM元素button>
- <School ref="sch"/>
- div>
- template>
-
- <script>
- //引入School组件
- import School from './components/School'
-
- export default {
- name:'App',
- components:{School},
- data() {
- return {
- msg:'欢迎学习Vue!'
- }
- },
- methods: {
- showDOM(){
- console.log(this.$refs.title) //真实DOM元素
- console.log(this.$refs.btn) //真实DOM元素
- console.log(this.$refs.sch) //School组件的实例对象(vc)
- }
- },
- }
- script>
ref属性
1. 被用来给元素或子组件(eg:App里的School)注册引用信息(id的替代者)
2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3. 使用方式:
1. 打标识:```
.....
``` 或 `````` 2. 获取:```this.$refs.xxx```
目录结构:
定义一个Student.vue,并在App.vue中三次引用。
现在有这么一个需求,已经定义好了一个组件,老王要用和这个一模一样的组件,但是数据不一样,该如何是好?(总不能复制一份)
在App.vue中使用Student标签中设置属性及其属性值。
设置值在另一头也要接收,此时就需要在Student.vue当中使用props,三种方式:
props:['name','age','sex']
接收的同时对数据进行类型限制
- props:{
- name:String,
- age:Number,
- sex:String
- }
- props:{
- name:{
- type:String, //name的类型是字符串
- required:true, //name是必要的
- },
- age:{
- type:Number,
- default:99 //默认值
- },
- sex:{
- type:String,
- required:true
- }
- }
./components/Student.vue
- <template>
- <div>
- <h1>{{msg}}h1>
- <h2>学生姓名:{{name}}h2>
- <h2>学生性别:{{sex}}h2>
- <h2>学生年龄:{{myAge+1}}h2>
- <button @click="updateAge">尝试修改收到的年龄button>
- div>
- template>
-
- <script>
- export default {
- name:'Student',
- data() {
- console.log(this)
- return {
- msg:'我是一个尚硅谷的学生',
- myAge:this.age
- }
- },
- methods: {
- updateAge(){
- this.myAge++
- }
- },
- //简单声明接收
- // props:['name','age','sex']
-
- //接收的同时对数据进行类型限制
- /* props:{
- name:String,
- age:Number,
- sex:String
- } */
-
- //接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
- props:{
- name:{
- type:String, //name的类型是字符串
- required:true, //name是必要的
- },
- age:{
- type:Number,
- default:99 //默认值
- },
- sex:{
- type:String,
- required:true
- }
- }
- }
- script>
App.vue
- <template>
- <div>
- <Student name="李四" sex="女" :age="18"/>
- div>
- template>
-
- <script>
- import Student from './components/Student'
-
- export default {
- name:'App',
- components:{Student}
- }
- script>
main.js
- //引入Vue
- import Vue from 'vue'
- //引入App
- import App from './App.vue'
- //关闭Vue的生产提示
- Vue.config.productionTip = false
-
- //创建vm
- new Vue({
- el:'#app',
- render: h => h(App)
- })
props配置项
1. 功能:让组件接收外部传过来的数据
2. 传递数据:```
``` 3. 接收数据:
1. 第一种方式(只接收):```props:['name'] ```
2. 第二种方式(限制类型):```props:{name:String}```
3. 第三种方式(限制类型、限制必要性、指定默认值):
```js
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
```
> 备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告。
若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
目录结构:
提一个需求,点击按钮弹窗name值:
可以发现红色框里内容是一样的,此时可以将他们都砍掉,使用mixin。
新建一个mixin.js,将共用的配置(例如showName方法)提取成混入对象,并暴露出去
在School.vue和Student.vue中引入并应用,两种方式:全局引入和局部引入
局部引入:
全局引入:(所有的vc和vm都会应用混合的东西)
./components/School.vue
- <template>
- <div>
- <h2 @click="showName">学校名称:{{name}}h2>
- <h2>学校地址:{{address}}h2>
- div>
- template>
-
- <script>
- //引入一个hunhe
- // import {hunhe,hunhe2} from '../mixin'
-
- export default {
- name:'School',
- data() {
- return {
- name:'尚硅谷',
- address:'北京',
- x:666
- }
- },
- // mixins:[hunhe,hunhe2],
- }
- script>
./components/Student.vue
- <template>
- <div>
- <h2 @click="showName">学生姓名:{{name}}h2>
- <h2>学生性别:{{sex}}h2>
- div>
- template>
-
- <script>
- // import {hunhe,hunhe2} from '../mixin'
-
- export default {
- name:'Student',
- data() {
- return {
- name:'张三',
- sex:'男'
- }
- },
- // mixins:[hunhe,hunhe2]
- }
- script>
App.vue
- <template>
- <div>
- <School/>
- <hr>
- <Student/>
- div>
- template>
-
- <script>
- import School from './components/School'
- import Student from './components/Student'
-
- export default {
- name:'App',
- components:{School,Student}
- }
- script>
main.js
- //引入Vue
- import Vue from 'vue'
- //引入App
- import App from './App.vue'
- import {hunhe,hunhe2} from './mixin'
- //关闭Vue的生产提示
- Vue.config.productionTip = false
-
- Vue.mixin(hunhe)
- Vue.mixin(hunhe2)
-
-
- //创建vm
- new Vue({
- el:'#app',
- render: h => h(App)
- })
mixin.js
- export const hunhe = {
- methods: {
- showName(){
- alert(this.name)
- }
- },
- mounted() {
- console.log('你好啊!')
- },
- }
- export const hunhe2 = {
- data() {
- return {
- x:100,
- y:200
- }
- },
- }
mixin(混入)
1. 功能:可以把多个组件共用的配置提取成一个混入对象
2. 使用方式:
第一步定义混合:
```
{
data(){....},
methods:{....}
....
}
```
第二步使用混入:
全局混入:```Vue.mixin(xxx)```
局部混入:```mixins:['xxx'] ```
ps:如果***.vue中当中没有混合中的数据则自动混合其中的数据,如果有数据和混合中重复则以***.vue为准。但如果在混合里面加入生命周期钩子函数,则不以任何人为准,都表达出来,且混合在前。
目录结构:
新建plugins.js,编写install方法并暴露
先应用插件再创建vm
传入参数为Vue构造函数:
a是vm的缔造者,vue的构造函数
有了这个就能做很多事情了
./components/School.vue
- <template>
- <div>
- <h2>学校名称:{{name | mySlice}}h2>
- <h2>学校地址:{{address}}h2>
- <button @click="test">点我测试一个hello方法button>
- div>
- template>
-
- <script>
- export default {
- name:'School',
- data() {
- return {
- name:'尚硅谷atguigu',
- address:'北京',
- }
- },
- methods: {
- test(){
- this.hello()
- }
- },
- }
- script>
./components/Student.vue
- <template>
- <div>
- <h2>学生姓名:{{name}}h2>
- <h2>学生性别:{{sex}}h2>
- <input type="text" v-fbind:value="name">
- div>
- template>
-
- <script>
- export default {
- name:'Student',
- data() {
- return {
- name:'张三',
- sex:'男'
- }
- },
- }
- script>
App.vue
- <template>
- <div>
- <School/>
- <hr>
- <Student/>
- div>
- template>
-
- <script>
- import School from './components/School'
- import Student from './components/Student'
-
- export default {
- name:'App',
- components:{School,Student}
- }
- script>
plugins.js
- export default {
- install(Vue,x,y,z){
- console.log(x,y,z)
- //全局过滤器
- Vue.filter('mySlice',function(value){
- return value.slice(0,4)
- })
-
- //定义全局指令
- Vue.directive('fbind',{
- //指令与元素成功绑定时(一上来)
- bind(element,binding){
- element.value = binding.value
- },
- //指令所在元素被插入页面时
- inserted(element,binding){
- element.focus()
- },
- //指令所在的模板被重新解析时
- update(element,binding){
- element.value = binding.value
- }
- })
-
- //定义混入
- Vue.mixin({
- data() {
- return {
- x:100,
- y:200
- }
- },
- })
-
- //给Vue原型上添加一个方法(vm和vc就都能用了)
- Vue.prototype.hello = ()=>{alert('你好啊')}
- }
- }
main.js
- //引入Vue
- import Vue from 'vue'
- //引入App
- import App from './App.vue'
- //引入插件
- import plugins from './plugins'
- //关闭Vue的生产提示
- Vue.config.productionTip = false
-
- //应用(使用)插件
- Vue.use(plugins,1,2,3)
- //创建vm
- new Vue({
- el:'#app',
- render: h => h(App)
- })
插件
1. 功能:用于增强Vue(游戏外挂)
2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
3. 定义插件:
```js
对象.install = function (Vue, options) {
// 1. 添加全局过滤器
Vue.filter(....)
// 2. 添加全局指令
Vue.directive(....)
// 3. 配置全局混入(合)
Vue.mixin(....)
// 4. 添加实例方法
Vue.prototype.$myMethod = function () {...}
Vue.prototype.$myProperty = xxxx
}
```
4. 使用插件:```Vue.use()```
目录结构:
引入一个问题
给Student和School分别设置样式,恰巧class名相同,都为demo,但是样式颜色不一样
结果和student一样(student背景色设置的为橙色)
为啥?因为在App.vue当中,student是后引入的,它覆盖了前一个。
给style标签添加scoped(作用域)属性,则表示style标签只作用于他当前的template里面。
其实他是给当前这歌div添加了一个特殊的标签属性,且每次都是随机不一样的。
完整代码:
效果:
scoped样式
1. 作用:让样式在局部生效,防止冲突。
2. 写法:```