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
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 可用字節
vue-app
vue-cli目錄解析
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
-gd加入全局+開發環境+生產環境配置 cnpm install -gd vue-cli 安裝vue-cli
| ||
Npm配置初始化 | npm init -f |
vue-source
Vue中index.html引入靜態資源,默認build目錄下的webpack打包配置,靜態資源必須放在static下
vue靜態資源配置
出現運行失敗問題
注釋eslint規范
eslint
父組件結構圖
子組件結構圖
bootstrap
局部樣式控制
<!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>
// 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 />'
})
<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>
<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>
todoList
么是Vue組件通訊 Vue.js 組件通信是指在 Vue 應用的不同組件之間進行數據交換和狀態同步的過程。由于 Vue 的組件是基于單文件組件(SFCs)的模塊化設計,每個組件都有自己的作用域,因此它們不能直接訪問彼此的數據。為了使組件之間能夠協同工作,Vue 提供了幾種不同的通信方式。以下是 Vue 中常見的組件通信模式:1.父子組件通訊,2.子父組件通訊。
簡單明了的說父子組件通訊,其實就是父組件通過v-bind指令,將值傳給子組件,而子組件使用Vue自帶的defineProps接收父組件傳過來的值。
我們使用命令行創建一個Vue項目之后
npm create vue@latest
在App.vue文件中我們開始實現父子組件通訊,我們在src文件夾下的components文件下,創建第一個子組件child.vue.首先我們需要把子組件引入父組件中,在Js部分我們用import引入
import Child from '@/components/child.vue'
\\或者 import Child from './components/child.vue'
可以看到,這個界面中有一個input輸入框,以及一個列表。我們需要在輸入框中,輸入信息,就會在列表中顯示我們輸入的內容。這里既然是父傳子,我們就在父組件中寫輸入框,在子組件寫列表就好了。在父組件中我們引入了子組件,引入的名稱,就可以當做一個標簽使用,用來展示子組件的內容。
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
<Child :msg="toChild"></Child>
</template>
在input框,我們使用v-model(v-model是Vue.js框架中用于實現表單輸入和其他元素的雙向數據綁定的指令。)進行數據綁定,使用v-model進行雙向綁定,方便我們獲取到輸入框的數據,并把該數據傳給子組件。button按鈕,我們使用@click綁定了一個添加函數add()。<Child :msg="toChild"></Child> 這就是我們將引入的子組件作為標簽使用,可以理解為我們打開了一個門,可以到達子組件。msg是參數名,toChild是參數值,在子組件中我們獲取參數名就好了。 現在我們來思考,Js部分我們需要什么,首先我們使用v-model對value進行了雙向綁定,,也即時說當輸入框中的value值發生了改變,我們Js部分的value也需要改變,反過來也是一樣的,這里我們就需要使用到一個響應式數據的概念,在vue中帶有一個模塊叫做ref可以讓我們把數據變成響應式數據(也有個一reactive,作用是一樣的,但是作用對象不一樣)。然后還有一個值叫作toChild傳給子組件也是一個響應式數據。在函數add()我們需要的時,把輸入框中的數據value傳給子組件,而toChild就是傳給子組件的值,所以我們只需要把value 賦值給toChild就好了
<script setup>
import Child from './components/child.vue'
import { ref } from 'vue'
const value = ref('')
const toChild = ref('')
const add = () => {
toChild.value = value.value
}
</script>
那么子組件child.vue又該如何實現呢,在子組件中我們需要展示列表中的數據,這里我們肯定不是一個li一個li的寫,可以直接只用到v-for(v-for是Vue.js中的一項非常重要的指令,用于在模板中迭代數組、對象或集合。)指令輸出就好了.我們定義一個數組用來存放數據,我們遍歷輸出數組,同時將父組件的值添加到數組中,所以這邊,數組也就會是一個響應式數據了。我們向輸入框中輸入數據,并添加。這個數組就會改變,但是如果我們不對這個數組進行監聽,v-for遍歷的數據是不會更新的,在vue存在一個監聽watch可以對數據的更新進行監聽。
<template>
<div class="child">
<ul>
<li v-for="item in list">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
const list = ref(['html', 'css', 'js'])
const props = defineProps({
msg: ''
})
watch(
() => props.msg,
(newVal, oldVal) => {
list.value.push(newVal)
}
)
</script>
<style lang="css" scoped></style>
這里我們使用defineProps接受父組件傳來的參數.在vue的API文檔是這樣介紹watch的
這樣我們就實現了父子組件通訊。
子父組件通訊那就是反過來的意思唄,子組件將值傳給父組件,例子依舊是這個例子
現在我們在子組件中寫輸入框,父組件寫列表。child2.vue
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const value = ref('')
const emits = defineEmits(['add1']) // 創建一個add事件
const add = () => {
// 將value給到父組件
emits('add1', value.value) // 發布事件
}
</script>
<style lang="css" scoped>
</style>
寫法其實沒有太大差別,重點是defineEmits(在 Vue 3 中,defineEmits 是一個用于定義組件可以觸發的自定義事件的選項。這使得組件的使用者能夠明確地知道哪些事件是可以從這個組件中發出的,從而增強了代碼的可讀性和可維護性。),我們先創建了一個事件'add1',當我們觸發事件'add1'就會把事件發布出去,同時會把參數va;ue.value傳出去,當誰訂閱事件add1,誰就可以拿到參數value.value.父組件App2.vue的寫法也很簡單
<template>
<!-- 訂閱add1事件 -->
<Child @add1="handle"></Child>
<div class="child">
<ul>
<li v-for="item in list">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import Child from '@/components/child2.vue'
import { ref } from 'vue'
const list = ref(['html', 'css', 'js'])
const handle = (event) => {
list.value.push(event)
}
</script>
<style lang="css" scoped>
</style>
我們需要在<Child/>標簽中訂閱這個事件就好了,同時觸發函數handle,這個函數自帶一個形參event,這個形參是指就是事件add1帶過來的參數value.value. 當然實現子父組件通訊也可以使用v-model對父組件的值與子組件的值進行雙向綁定。 寫法跟訂閱事件其實差不多App3.vue
<template>
<Child v-model:list="list"></Child>
<div class="child">
<ul>
<li v-for="item in list">{{ item }}</li>
</ul>
</div>
</template>
<script setup>
import Child from '@/components/child3.vue'
import { ref } from 'vue'
const list = ref(['html', 'css', 'js'])
</script>
<style lang="css" scoped>
</style>
我們借助v-model對數據list雙向綁定,我們在子組件中接收list值,并對它進行數據更新。子組件child3.vue
<template>
<div class="input-group">
<input type="text" v-model="value">
<button @click="add">添加</button>
</div>
</template>
<script setup>
import { ref, defineProps } from 'vue';
const value = ref('')
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
const emits = defineEmits(['update:list'])
const add = () => {
const arr = props.list
arr.push(value.value)
emits('update:list', arr)
}
</script>
<style lang="css" scoped></style>
值得一提的是,在子組件中我們也使用到了defineEmits但是在父組件中,我們并沒有訂閱事件,這是因為,我們的v-model是雙向綁定數據,當子組件中的list的值發生了改變,就會觸發v-model,等同于我們觸發了訂閱。
TML全稱是:超文本標記語言(HyperText Markup Language),學習這種語言主要就是學習各種標簽的使用,今天給大家介紹HTML的基本標簽。
html標簽
*請認真填寫需求信息,我們會在24小時內與您取得聯系。