09 [CLI initializes some knowledge of scaffolding Vue fragments]

09 [CLI initializes some knowledge of scaffolding Vue fragments]

1. Vue CLI initializes scaffolding

1.1 Specific steps

1 If the download is slow, please configure npm Taobao mirror npm config set registry http://registry.npm.taobao.org
2 Global installation @vue/cli npm install -g @vue/cli
3 Switch to the directory where the project was created and use the command to create Project vue create xxx
4 Choose to use vue version
5 Start the project npm run serve
6 Package the project npm run build
7 Pause the project Ctrl+C

Vue scaffolding hides all webpack-related configurations. If you want to view specific webpack configurations, please execute vue inspect > output.js

1.2 Scaffolding file structure

.文件目录
├── 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: 包版本控制文件

Scaffolding demo

components

Just use the School.vue and Student.vue files of the single-file component directly without modification.

app.vue

Introduce these two components, register these two components, and then use them.

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <Student></Student>
    <School></School>
  </div>
</template>

<script>
import School from './components/School.vue'
import Student from './components/Student.vue'

export default {
  name: 'App',
  components: {
    School,
    Student
  }
}
</script>

main.js:

entry file

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

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

Vue.config.productionTip = false

new Vue({
    
    
	el:'#app',
  render: h => h(App),			// render函数完成了这个功能:将App组件放入容器中
})// .$mount('#app')

index.html

<!DOCTYPE html>
<html lang="">
    <head>
        <meta charset="UTF-8">
      
        <!-- 针对IE浏览器的特殊配置,含义是让IE浏览器以最高渲染级别渲染页面 -->
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
      
        <!-- 开启移动端的理想端口 -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
      
        <!-- 配置页签图标 <%= BASE_URL %>是public所在路径,使用绝对路径 -->
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
      
        <!-- 配置网页标题 -->
        <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
      
      	<!-- 当浏览器不支持js时,noscript中的元素就会被渲染 -->
      	<noscript>
      		<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    		</noscript>
          
        <!-- 容器 -->
        <div id="app"></div>
    </body>
</html>

1.3render function

Insert a little knowledge:

There is no need to add './' when using import to import third-party libraries

Import what we wrote ourselves:

import App from './App.vue'

Import third-party

import Vue from 'vue'

'./'The reason why there is no need to add from 'vue' is that the third-party library node_modules has been configured for us.

We import the third-party library through import, and determine which file we are importing in the package.json file of the third-party library

image-20220630173839543

The file we want to import is determined by module.

Remarks: This is ESMthe file imported by default, the file in the path in the CommonJSdefault importmian

Back to the render function

It was written like this before:

import App from './App.vue'

new Vue({
    
    
	el:'#root',
	template:`<App></App>`,
	components:{
    
    App},
})

If it is written like this, it will cause the following error when running

image-20220630174043948

The error means that the running version of vue is used without a template parser.

From the little knowledge above, we can know that the vue we introduced is not a complete version, but incomplete (in order to reduce the size of vue). So the incomplete vue.js can only run the project through the render function.

Let's analyze the render

// render最原始写的方式
// render是个函数,还能接收到参数a
// 这个 createElement 很关键,是个回调函数
new Vue({
    
    
  render(createElement) {
    
    
      // 这个 createElement 回调函数能创建元素
      // 因为残缺的vue 不能解析 template,所以render就来帮忙解决这个问题
      // createElement 能创建具体的元素
      return createElement('h1', 'hello')
  }
}).$mount('#app')

1.4 About functions of different versions

Come to the difference between different versions of vue

  • The difference between vue.js and vue.runtime.xxx.js:
    • Vue.js is a full version of Vue, including: core functions + template parser.
    • vue.runtime.xxx.js is the running version of Vue, which only includes: core functions; no template parser. esmthat is ES6 module
  • Because vue.runtime.xxx.jsthere is no template parser, the template configuration item cannot be used, and the function renderreceived by the function needs to be used createElementto specify the specific content.

1.5vue.config.js configuration file

vue inspect > output.jsYou can view the default configuration of Vue scaffolding

Can not be modified

vue.config.jsScaffolding can be customized by using it , and package.jsonthe same level directory, see configuration

module.exports = {
    
    
  pages: {
    
    
    index: {
    
    
      entry: 'src/index/main.js' // 入口
    }
  },
  lineOnSave: false	// 关闭语法检查
}

2. Some bits and pieces of vue knowledge

2.1ref attribute

  • Used to register reference information for elements or subcomponents (replacement of id)
  • What the application htmlgets on the label is real DOM元素, and the application on the component label is the component instance objectvc
  • How to use:
    • Mark: <h1 ref="xxx">.....</h1>or<School ref="xxx"></School>
    • Obtain:this.$refs.xxx
<template>
  <div>
    <h1 v-text="msg" ref="title"></h1>
    <button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
    <School ref="sch"/>
  </div>
</template>

<script>
  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>

image-20220630222636601

2.2 props configuration item

  1. Function: Let the component receive data from the outside

  2. Transfer data: <Demo name="xxx" :age="18"/>add: before age here, make 18 in it a number through v-bind

  3. Receive data:

    1. The first way (receive only):props:['name']

    2. Second way (restricted type):props:{name:String, age:Number}

    3. Third way (restrict type, restrict necessity, specify default value)

props:{
    
    
	name:{
    
    
        type:String, //类型
        required:true, //必要性
        default:'老王' //默认值
	}
}

Remarks: props are read-only . The bottom layer of Vue will monitor your modification of props. If you modify props, a warning will be issued. If the business needs really need to be modified, please copy the content of props to a copy of data, and then modify it The data in data.

Vue props pass Array/Object type value, sub-component error solution

image-20220728124344030In fact, you can see the error message, that is, when the value type of Props is Object/Array, if you need to configure defaultthe value (if there is no configuration defaultvalue, this error will not be reported) , then you must use the function to get returnthe defaultvalue instead of Write directly like primitive data typesdefault:xxx

//错误写法
props: {
    
    
	rlist: {
    
    
		type:Array,
		default: [1, 2, 3, 4, 5]
	}
}

Solution

//正确写法
props: {
    
    
	rlist: {
    
    
		type:Array,
		default: function() {
    
    
			return [1, 2, 3, 4, 5]
		}
	}
}
//当然,我们可以使用箭头函数来写,还显得简单很多
props: {
    
    
	rlist: {
    
    
		type:Array,
		default: () => [1, 2, 3, 4, 5]
	}
}

Sample code:

Pass data from parent component to child component

app.vue

<template>
  <div>
    <Student name="李四" sex="" :age="18"/>
    <Student name="王五" sex="" :age="18"/>
  </div>
</template>

<script>
  import Student from './components/Student'

  export default {
      
      
    name:'App',
    components:{
      
       Student }
  }
</script>

School.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: "我是一个bilibili大学的学生",
      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>

2.3 mixin

混入 (mixin) Provides a very flexible way to distribute reusable functionality in Vue components. A mixin object can contain arbitrary component options. When a component uses a mixin, all of the mixin's options will be "mixed in" into the component's own options.

Function: The configuration shared by multiple components can be extracted into a mix-in object

example:

const mixin = {
    
    
    data() {
    
    ....},
    methods: {
    
    ....}
    ....
}

use mixins

  • global mixinsVue.mixin(xxx)
  • Partial mix-inmixins:['xxx']

Partial mix-in

src/mixin.js

export const hunhe = {
    
    
	methods: {
    
    
		showName(){
    
    
			alert(this.name)
		}
	},
	mounted() {
    
    
		console.log('你好啊!')
	},
}

export const hunhe2 = {
    
    
	data() {
    
    
		return {
    
    
			x:100,
			y:200
		}
	},
}

src/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>

src/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>

global mixins

src/main.js

import Vue from 'vue'
import App from './App.vue'
import {
    
    mixin} from './mixin'

Vue.config.productionTip = false
Vue.mixin(hunhe)		// 全局混合引入
Vue.mixin(hunhe2)	// 全局混合

new Vue({
    
    
    el:"#app",
    render: h => h(App)
})

In this way, all components will automatically use these configurations, and global mixing is not recommended

Remark

  1. When components and mixins contain options with the same name, those options will be "merged" in an appropriate manner, with the component taking precedence in the event of a conflict
var mixin = {
    
    
	data: function () {
    
    
		return {
    
    
    		message: 'hello',
            foo: 'abc'
    	}
  	}
}

new Vue({
    
    
  	mixins: [mixin],
  	data () {
    
    
    	return {
    
    
      		message: 'goodbye',
            	bar: 'def'
    	}
    },
  	created () {
    
    
    	console.log(this.$data)
    	// => { message: "goodbye", foo: "abc", bar: "def" }
  	}
})
  1. Lifecycle hooks with the same name will be combined into one array, so all will be called . Also, the hooks of the mixed-in object will be called before the component's own hooks
var mixin = {
    
    
  	created () {
    
    
    	console.log('混入对象的钩子被调用')
  	}
}

new Vue({
    
    
  	mixins: [mixin],
  	created () {
    
    
    	console.log('组件钩子被调用')
  	}
})

// => "混入对象的钩子被调用"
// => "组件钩子被调用"

2.4 plugin plugin

1. Function: used to enhance Vue
2. Essence: an object containing the install method, the first parameter of install is the Vue constructor, and the second and later parameters are the data passed by the plug-in user
3. Define the plug-in (see below src/plugin.js)
4. Use the plugin:Vue.use()

Vue.useAfter execution, installthe method will be called automatically, and all components can use the things defined in it.

src/plugin.js

export default {
    
    
  install(Vue,x,y,z){
    
    
    console.log(x,y,z)
      
    //定义全局指令
    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('你好啊')}
  }
}

src/main.js

import Vue from 'vue'
import App from './App.vue'
import plugins from './plugins'	// 引入插件

Vue.config.productionTip = false

Vue.use(plugins,1,2,3)	// 应用(使用)插件

new Vue({
    
    
	el:'#app',
	render: h => h(App)
})

src/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>

src/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>

2.5scoped

scoped style

  1. Function: Let the style take effect locally to prevent conflicts.
  2. Writing:<style scoped>

Specific case:

<style lang="less" scoped>
	.demo{
      
      
		background-color: pink;
		.lktest{
      
      
			font-size: 40px;
		}
	}
</style>

Guess you like

Origin blog.csdn.net/Instanceztt/article/details/131044846