Vue脚手架
Vue脚手架学习笔记
·
3. Vue脚手架
文章目录
3.1 安装脚手架
切换淘宝镜像
npm config set registry https://registry.npm.taobao.org
安装命令
npm install -g @vue/cli
3.2 render函数
3.3 修改默认设置
3.4 ref属性
-
被用于给元素或子组件注册引用信息 (id 代替者)
-
应用在 html 标签上获取的是真实的 DOM 元素,应用在组件标签上是组件实例对象 (vc)
- 使用方式:
打标识:
<h1 ref="xxx">...</h1>
或<School ref="xxx"></School>
获取:
this.$refs.xxx
3.5 props配置
3.6 mixin混入
功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
-
定义混合
{ data(){...}, methods:{...}, ... }
-
使用混合
- 全局混合:
Vue.mixin(xxx)
- 局部混合:
mixins:['xxx']
- 全局混合:
3.7 plugins
3.8 scoped样式
作用:让样式在局部生效,防止冲突
写法:<style scoped>
3.9 Todo-list案例
- 组件化编程流程
- 拆分静态组件:组件要按照功能点拆分,命名不要与 html 元素冲突
- 实现动态组件:考虑好数据存放位置,数据是一个组件在用,还是一些组件在用:
- 一个组件在用:放在组件自身即可
- 一些组件在用:放在他们共同的父组件上(状态提升)
- 实现交互:从绑定事件开始
- props适用于:
- 父组件 ==> 子组件 通信
- 子组件 ==> 父组件 通信(要求父先给子一个函数)
- 使用
v-model
时要切记:v-model
绑定的值不能是 props 传过来的值,因为 props 是不能够修改的 - props 传过来的若是对象类型的值,修改对象中的属性时 Vue 不会报错,但不推荐这样做
src/App.vue
<template>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<MyHeader :addTodo="addTodo" />
<MyList
:todos="todos"
:changeState="changeState"
:deleteTodo="deleteTodo"
/>
<MyFooter
:allCheck="allCheck"
:getNum="getNum"
:getDoneNum="getDoneNum"
:deleteDone="deleteDone"
/>
</div>
</div>
</div>
</template>
<script>
import MyHeader from './components/MyHeader'
import MyList from './components/MyList'
import MyFooter from './components/MyFooter.vue'
import { nanoid } from 'nanoid'
export default {
name: 'App',
components: { MyHeader, MyList, MyFooter },
data() {
return {
todos:[
{id:'001',title:'抽烟',done:true},
{id:'002',title:'喝酒',done:false},
{id:'003',title:'开车',done:true}
]
}
},
methods: {
addTodo(t){
this.todos.unshift({id:nanoid(), title:t, done:false})
},
changeState(id){
this.todos.forEach((t)=>{
if (t.id === id) {
t.done = !t.done
return
}
})
},
deleteTodo(id){
this.todos = this.todos.filter((t)=>{
return t.id !== id
})
},
allCheck(checked) {
this.todos.forEach((t)=>{
t.done = checked
})
},
getNum(){
return this.todos.length
},
getDoneNum(){
return this.todos.reduce((pre, current)=>pre + (current.done ? 1 : 0), 0)
},
deleteDone(){
this.todos = this.todos.filter((t)=>{
return !t.done
})
}
}
}
</script>
<style>
/*base*/
body {background: #fff;}
.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;
line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
border-radius: 4px;}
.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}
.btn-danger:hover {color: #fff;background-color: #bd362f;}
.btn:focus {outline: none;}
.todo-container {width: 600px;margin: 0 auto;}
.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>
src/MyHeader.vue
<template>
<div class="todo-header">
<input type="text"
placeholder="请输入你的任务名称,按回车键确认"
@keydown.enter="add"
v-model="title"
/>
</div>
</template>
<script>
export default {
name:'MyHeader',
props:['addTodo'],
data(){
return {
title:''
}
},
methods:{
add(e){
const val = e.target.value;
if (! val.trim()) {
alert('输入内容为空')
} else {
this.addTodo(val)
this.title = ''
}
}
}
}
</script>
<style scoped>
/*header*/
.todo-header input {width: 560px;height: 28px;font-size: 14px;
border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;}
.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);}
</style>
src/MyList.vue
<template>
<ul class="todo-main">
<MyItem v-for="todoObj in todos"
:key="todoObj.id"
:todoObj="todoObj"
:changeState="changeState"
:deleteTodo="deleteTodo"
/>
</ul>
</template>
<script>
import MyItem from './MyItem.vue';
export default {
name:'MyList',
props:['todos', 'changeState', 'deleteTodo'],
components:{MyItem}
}
</script>
<style scoped>
/*main*/
.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}
.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;
border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>
src/MyItem.vue
<template>
<li>
<label @click="change(todoObj.id)">
<!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,因为修改了props -->
<!-- <input type="checkbox" v-model="todo.done"/> -->
<input type="checkbox" :checked="todoObj.done" @change="change(todoObj.id)" />
<span>{{todoObj.title}}</span>
</label>
<button class="btn btn-danger" @click="deleteTodoObj(todoObj.id)">删除</button>
</li>
</template>
<script>
export default {
name:'MyItem',
props:['todoObj', 'changeState', 'deleteTodo'],
methods:{
change(id) {
this.changeState(id)
},
deleteTodoObj(id) {
if (id) this.deleteTodo(id)
}
}
}
</script>
<style scoped>
/*item*/
li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;
border-bottom: 1px solid #ddd;}
li label {float: left;cursor: pointer;}
li label li input {vertical-align:middle; margin-right:6px; position:relative;top: -1px;}
li button {float: right;display: none;margin-top: 3px;}
li:before {content: initial;}
li:last-child {border-bottom: none;}
li:hover{background-color: #ddd;}
li:hover button{display: block;}
</style>
src/MyFooter.vue
<template>
<div class="todo-footer" v-show="total">
<label>
<!-- <input type="checkbox" :checked="isAll" @change="checkAll"/> -->
<input type="checkbox" v-model="c" />
</label>
<span>
<span>已完成{{done}}</span> / 全部{{total}}
</span>
<button class="btn btn-danger" @click="deleteDones">清除已完成任务</button>
</div>
</template>
<script>
export default {
name:'MyFooter',
props:['allCheck', 'getNum', 'getDoneNum', 'deleteDone'],
computed:{
total:{
get(){
return this.getNum()
}
},
done:{
get(){
return this.getDoneNum()
},
},
c:{
get(){
return this.total === this.done ? true : false
},
set(value){
this.allCheck(value)
}
}
},
methods:{
deleteDones(){
this.deleteDone()
}
}
}
</script>
<style scoped>
/*footer*/
.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}
.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}
.todo-footer label input {position: relative;top: -1px;vertical-align: middle;
margin-right: 5px;}
.todo-footer button {float: right;margin-top: 5px;}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)