编程技术文章分享与教程

网站首页 > 技术文章 正文

web前端:vue源码解析,vue-cli父子组件传递模板

hmc789 2024-11-25 12:47:45 技术文章 2 ℃

1.vue-cli安装命令

1.全局安装vue-cli
$ npm install --global vue-cli
2.创建一个基于webpack脚手架的project,cmd进入指定项目目录
[D:\DEV_CODE\html_code\base-vue\vue-cli  进入后cmd]
$ vue init webpack {project-name}

3.进入项目
$ cd {project-name}
4.运行
$ npm run dev

2.Cmd运行记录解析

Microsoft Windows [版本 10.0.18363.1379]
(c) 2019 Microsoft Corporation。保留所有权利。

D:\DEV_CODE\html_code\base-vue\vue-cli>vue init webpack c-todolist

? Project name c-todolist  确认项目名称
? Project description A Vue.js project  确认项目描述
? Author cevent <1540001771@qq.com>  确认作者
? Vue build standalone  标准单机版
? Install vue-router? Yes   是否安装vue-router路由
? Use ESLint to lint your code? Yes  启用ESlint标准
? Pick an ESLint preset Standard
? Set up unit tests No  初始化测试类,全选no
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm  选择安装模式npm(可选yarn)

   vue-cli · Generated "c-todolist".
# Installing project dependencies ...
# ========================
...
added 1376 packages from 715 contributors in 185.663s
38 packages are looking for funding
  run `npm fund` for details
Running eslint --fix to comply with chosen preset rules...
# ========================
> c-todolist@1.0.0 lint D:\DEV_CODE\html_code\base-vue\vue-cli\c-todolist
> eslint --ext .js,.vue src "--fix"
# Project initialization finished!
# ========================

To get started:
  cd c-todolist
  npm run dev
Documentation can be found at https://vuejs-templates.github.io/webpack

D:\DEV_CODE\html_code\base-vue\vue-cli>cd c-todolist  进入项目目录
D:\DEV_CODE\html_code\base-vue\vue-cli\c-todolist>tree  以tree模式查看目录结构
卷 APP_SOFT 的文件夹 PATH 列表
卷序列号为 BCA1-A4B1
D:.
├─build
├─config
├─node_modules
│  ├─.bin
│  ├─@babel
│  │  ├─code-frame
│  │  │  └─lib
│  │  ├─generator
│  │  │  ├─lib
│  │  │  │  ├─generators
│  │  │  │  └─node
│  │  │  └─node_modules
│  │  │      ├─.bin
│  │  │      ├─jsesc
.....

D:\DEV_CODE\html_code\base-vue\vue-cli\c-todolist>dir  查看目录下文件
 驱动器 D 中的卷是 APP_SOFT
 卷的序列号是 BCA1-A4B1

 D:\DEV_CODE\html_code\base-vue\vue-cli\c-todolist 的目录

2021/02/24  13:14    <DIR>          .
2021/02/24  13:14    <DIR>          ..
2021/02/24  13:10               230 .babelrc
2021/02/24  13:10               147 .editorconfig
2021/02/24  13:10                30 .eslintignore
2021/02/24  13:10               791 .eslintrc.js
2021/02/24  13:10               154 .gitignore
2021/02/24  13:10               246 .postcssrc.js
2021/02/24  13:10    <DIR>          build
2021/02/24  13:10    <DIR>          config
2021/02/24  13:10               272 index.html
2021/02/24  13:14    <DIR>          node_modules
2021/02/24  13:14           506,953 package-lock.json
2021/02/24  13:10             2,165 package.json
2021/02/24  13:10               467 README.md
2021/02/24  13:10    <DIR>          src
2021/02/24  13:10    <DIR>          static
              10 个文件        511,455 字节
               7 个目录 64,125,562,880 可用字节




3.npm和cnpm区别、参数及安装

npm(node.js package manager)node.js包管理器,用于node插件管理(安装、卸载、依赖管理)。国外服务器

cnpm:国内阿里团队创建的npm镜像

参数

说明

-g

全局安装(global)

查看全局安装的文件夹位置:npm root -g

C:\Users\asus>npm root -g

C:\Users\asus\AppData\Roaming\npm\node_modules

--save(缩写-S)

安装包信息将加入到依赖productDependencies生产阶段(命令不区分大小写)

--save --dev(缩写-D

安装包信息将加入到依赖devDependencies开发阶段+product生产阶段(命令不区分大小写)

install(缩写i)

安装

全局安装cnpm


指定镜像资源

npm install -gd express --registry=http://registry.npm.taobao.org


安装vue-cli


-》npm install -g vue-cli

-》cnpm install -gd vue-cli

如果 vue init webpack {projectName} 失败,则需要重新安装vue-cli

查看npm注册

C:\Users\asus>npm get registry

http://registry.npm.taobao.org/


避免每次安装都要registry参数,可使用永久设置

npm config set registry http://registry.npm.taobao.org

解决:'cnpm' 不是内部或外部命令。


install -g cnpm --registry=https://registry.npm.taobao.org

C:\Users\asus>npm install -g cnpm --registry=https://registry.npm.taobao.org

npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142

npm WARN deprecated har-validator@5.1.5: this

C:\Users\asus\AppData\Roaming\npm\cnpm -> C:\Users\asus\AppData\Roaming\npm\node_modules\cnpm\bin\cnpm

+ cnpm@6.1.1

added 689 packages from 973 contributors in 35.267s


C:\Users\asus>cnpm -v

cnpm@6.1.1 (C:\Users\asus\AppData\Roaming\npm\node_modules\cnpm\lib\parse_argv.js)

npm@6.14.11 (C:\Users\asus\AppData\Roaming\npm\node_modules\cnpm\node_modules\npm\lib\npm.js)

node@12.14.0 (C:\DevTools\nvm-nodejs\node.exe)

npminstall@3.28.0 (C:\Users\asus\AppData\Roaming\npm\node_modules\cnpm\node_modules\npminstall\lib\index.js)

prefix=C:\Users\asus\AppData\Roaming\npm

win32 x64 10.0.18363

registry=https://r.npm.taobao.org


C:\Users\asus>npm -v

6.13.4


C:\Users\asus>cls 命令清理控制台(清屏)


-gd加入全局+开发环境+生产环境配置

cnpm install -gd vue-cli 安装vue-cli

C:\Users\asus>vue -V 注意大写V

@vue/cli 4.4.6


Npm配置初始化

npm init -f


4.vue源码文件解析


Vue中index.html引入静态资源,默认build目录下的webpack打包配置,静态资源必须放在static下


5.关闭eslint的no-tabs和indent缩进和no-trailing-spaces


注释eslint规范


6.vue父子组件传递



7.安装插件bootstrap目录,注意引入样式需要放在static目录下



8.Index.html入口,引入全局css和js

<!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">
		<!--vue中在index.html页面引入bootstrap失败,必须将css、js放在static,源于-->
		<link rel="stylesheet" href="static/base/css/bootstrap.css" />
		<!--vue中引入需要javascript-->
		<script type="javascript" src="static/base/js/jquery.min.js"></script>
		<script type="javascript" src="static/base/js/bootstrap.js"></script>
		<title>c-todolist</title>
	</head>

	<body>
		<!--这里的app指向main.js中自定义的el名-->
		<!--<div id="app"></div>-->
		<div id="todoList"></div>
		<!-- built files will be auto injected -->
	</body>

</html>

9.Main.js引入todoList页面,作为模板

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
// import App from './App'
import router from './router'
import TodoList from './TodoList'

//  Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
	//  el: '#app',
	//  注册的局部组件:App.vue  components:{App(key):App(value)}, 引如的组件如果key=value,可以直接省略为{App}
	//  components: { App },
	//  模板为App.vue的内容
	//  template: '<App/>'
	el: '#todoList',
	router,
	components: {
		TodoList
	},
	template: '<TodoList />'
})

10.TodoList.vue页面,作为父组件

<template>
	<div id="todoList">
		<h3>TodoList页面{{message}}</h3>
		<div id="todoList-group1" class="input-group input-group-lg">
			<span class="input-group-addon" id="sizing-addon1">Table</span>
			<input type="text" class="form-control" placeholder="输入内容" aria-describedby="sizing-addon1" v-model="inputValue">
			<button class="btn btn-success btn-lg" type="button" @click="add">新增</button>
		</div>
		<div id="todoListinput">
			<table class="table" v-for="(item,index) of list" :key="index" :bindx="index">
				<tr class="active">
					<td >
						<span>{{index}}{{item}}</span>
						<button class="btn btn-primary " type="button"  @click="del(bindx)" >刪除</button>
					</td>
				</tr>
			</table>
		</div>
		
		<div id="todoList-group2" class="input-group input-group-lg">
			<span class="input-group-addon" id="sizing-addon1">组件传递Table</span>
			<input type="text" class="form-control" placeholder="输入内容" aria-describedby="sizing-addon1" v-model="inputValueComp">
			<button class="btn btn-danger btn-lg" type="button" @click="addComp">新增</button>
		</div>
		<div id="todoItemList">
			<!--父组件向子组件传值,需要绑定参数给子组件props
				@parentDel在子组件的方法中,里面包含一个变量,是否父组件的itemIndex传入,然后子组件通过this.@emit("parentDel",this.index)的方法,发送到父组件,这个index在父组件方法中可以定位任意参数
			-->
			<todo-item v-for="(item,index) of compList" :key="index" :itemContent="item" :itemIndex="index" @parentDel="delComp"></todo-item>
		</div>
	</div>

</template>

<script>
	//引入组件:当前目录下./
	import TodoItem from './components/TodoItem';
	export default {

		name: 'todoList',
		/* 当前作为组件,data为函数,需要return定义返回值
		 * data:function(){
		 * 	return{
		 * 	
		 * 	}
		 * }
		 * 这里ES6的语法中可做简化
		 * data(){
		 * 	return{}
		 * }
		 */
		/* 非自定义名称集合:['组件名称','组件名称']
		 * 自定义名称: {'todo-item': TodoItem}
		 */
		components: {
			'todo-item': TodoItem,
		},
		data() {
			return {
				message: "欢迎cevent光临寒舍!",
				inputValue: "",
				list: [],
				//组件参数
				compList:[],
				inputValueComp:"",
			}
		},

		methods: {
			//新增事件
			add() {
				console.log("输入的内容:",this.inputValue);
				//这里的this.list=this.$data.list
				this.list.push(this.inputValue);
				this.inputValue = "";
				console.log(":bindx=index",this.list.item);
			},
			del(bindx){
				console.log("删除的内容:",bindx);
				this.list.splice(bindx,1);
			},
			//todoItem组件新增
			addComp(){
				this.compList.push(this.inputValueComp);
				this.inputValueComp="";
			},
			delComp(compIndex){
				this.compList.splice(compIndex,1);
			}
		}
	}
</script>

<style>
	#todoList {
		font-family: 'Avenir', Helvetica, Arial, sans-serif;
		-webkit-font-smoothing: antialiased;
		-moz-osx-font-smoothing: grayscale;
		text-align: center;
		color: #2c3e50;
		margin-top: 40px;
	}
	
	#todoList-group1 {
		width: 50%;
		top: 50%;
		left: 50%;
		transform: translate3d(-50%, -50%, 0);
		margin-top: 50px;
	}
	
	#todoList-group1 button {
		position: absolute;
		margin: 0 5px;
	}
	
	#todoList-group2 {
		width: 50%;
		top: 50%;
		left: 50%;
		transform: translate3d(-50%, -50%, 0);
		margin-top: 50px;
	}
	
	#todoList-group2 button {
		position: absolute;
		margin: 0 5px;
	}
	
	#todoListinput {
		position: relative;
		height: 46px;
		width: 50%;
		height: 100%;
		top: 0;
		bottom: 0;
		left: 0;
		right: 0;
		margin: auto;
		margin-top: -15px;
		border-radius: 2%;
		line-height: 46px;
		color: white;
		font-size: 20px;
		transition: 1s;
		border: 2px solid silver;
	}
	#todoListinput table{
		margin-bottom: 3px;
	}
	#todoListinput table tr{
		position: relative;
		background: salmon;
		padding: 0;
	}
	#todoListinput table tr td span{
		position: relative;
		float: left;
		left: 20%;
	}
	#todoListinput table tr td button{
		position: relative;
		float: right;
		right: 10%;
		margin-top: 1.5%;
	}
	
	#todoItemList{
		
	}
</style>

11.Components中TodoItem.vue页面,作为子组件

<template>
	<table class="todo-table">
		<tr id="tableTR">
			<td> {{itemContent}} {{itemIndex}} <button type="button" class="btn btn-default" @click="compDel">删除</button></td>
		</tr>
	</table>

</template>

<script>
	export default {
		name: 'TodoItem',
		//接收父组件传值
		props:['itemContent','itemIndex'],
		data() {
			return {
				ceventMsg: '这是一个cevent引用的data',
			}
		},
		methods:{
			/**省略写法
			 * xxx:function(){...}
			 */
			compDel(){
				console.log("子组件传给父组件的index:",this.itemIndex);
				//将index发射到父组件,指定接收的方法为"parentDel",这里父组件选用click时间
				this.$emit("parentDel",this.itemIndex);
			}
		}
	}
</script>

<style>
	.todo-table {
		position: relative;
		width: 50%;
		height: 100%;
		top: 50%;
		left: 50%;
		transform: translate3d(-50%, -50%, 0);
		border:1px solid skyblue;
		border-radius: 8px;
		margin-top: 2px;
	}
	/*覆盖哪一层,在哪一层指定transition*/
	.todo-table:hover #tableTR{
		background: deepskyblue;
		color: #000000;
	}
	
	#tableTR {
		position: relative;
		background: steelblue;
		width: 90%;
		
		
		color: white;
		transition: 1s;
		margin-top: 2px;
	}
	
	#tableTR  td {
		position: relative;
		width: 80%;
		margin: 2px auto;
		font-size: 24px;
		float: left;
	}
	
	#tableTR td button{
		position: relative;
		width: 20%;
		float: right;
		right: -25%;
	}
	
</style>

13.效果图


Tags:

标签列表
最新留言