начиная
Поскольку это самый простой фреймворк для начала работы с интерфейсом, о начале работы с Vue говорить особо нечего.Я помещаю фрагмент кода в список.Если все могут его понять, это означает, что вы можете начать работу.
<template>
<div id="app">
<h1>{{title}}</h1>
<div>
<input type="text" v-model="val">
<button @click="add">添加</button>
<button @click="clear">清空</button>
</div>
<ul>
<li v-for="todo in todos" :key="todo.title" :class="{done:todo.done}">
<input type="checkbox" v-model="todo.done">
{{todo.title}}
</li>
</ul>
<p>{{active}} / {{all}}</p>
</div>
</template>
<script>
export default {
name: "app",
data() {
return {
title: "蜗牛老湿很骚气",
val: "",
todos: []
};
},
mounted() {
const todos = localStorage.getItem("todos");
if (todos) {
this.todos = JSON.parse(todos);
} else {
this.todos = [
{ title: "吃饭", done: true },
{ title: "睡觉", done: false },
{ title: "写代码", done: false }
];
}
},
computed: {
active() {
return this.todos.filter(v => !v.done).length;
},
all() {
return this.todos.length;
}
},
watch: {
todos: {
deep: true,
handler(todos) {
localStorage.setItem("todos", JSON.stringify(todos));
}
}
},
methods: {
clear() {
this.todos = this.todos.filter(v => !v.done);
},
add() {
if (this.val) {
this.todos.push({ title: this.val, done: false });
this.val = "";
}
}
}
};
</script>
<style>
li.done {
color: red;
text-decoration: line-through;
}
</style>
Содержание примерно следующее.После того, как вы ознакомитесь с этим примером, это наш основной текст.Если вам что-то непонятно в приведенном выше коде, перейдите на официальный сайт Vuejs, чтобы просмотреть его.
- Рендеринг переменных
- рендеринг цикла
- рендеринг класса
- вычисляемое свойство
- слушатель
- привязать событие
- Жизненный цикл
составной
Однофайловый компонент Vue. Я думаю, что каждый сталкивался с однофайловым компонентом Vue.Проекты, инициализированные через vue-cli, поддерживаются автоматически.Создайте новый Child1.vue
<template>
<div>Child1</div>
</template>
<script>
export default {
}
</script>
Использовать в приложении
<template>
<div id="app">
<Child1></Child1>
</div>
</template>
<script>
import Child1 from '@/components/Child1'
export default {
name: "app",
components:{Child1}
}
</script>
Здесь возникает первый распространенный вопрос. Если компонентов слишком много, как они общаются и общаются друг с другом? Не стоит недооценивать этот вопрос. Разгневанные интервьюеры, такие как я, часто любят спрашивать. Давайте продемонстрируем Vue. Обычно используемое общение приемники между компонентами
1. Компоненты «родитель-потомок»
Самый простой способ передачи значений между родительским и дочерним компонентами — через пропсы, не будем говорить о коде.
// App
<template>
<div id="app">
<Child1 :title="title1"></Child1>
</div>
</template>
<script>
import Child1 from '@/components/Child1'
export default {
name: "app",
data(){
return {
title1:'我是你爸爸'
}
},
components:{Child1}
}
</script>
// Child1
<template>
<div>
<h2>Child2</h2>
<div>{{title}}</div>
</div>
</template>
<script>
export default {
props:['title']
}
</script>
2. Сын к отцу
Vue предпочитает односторонний поток данных, поэтому дочерний компонент должен уведомить родительский компонент об изменении передаваемых данных и использовать $emit для запуска события, переданного родительским элементом.
<template>
<div id="app">
<h2>Parent</h2>
<h3>{{msg}}</h3>
<Child1 :title="title1" @getmsg="getmsg"></Child1>
</div>
</template>
<script>
import Child1 from '@/components/Child1'
export default {
name: "app",
data(){
return {
msg:'',
title1:'我是你爸爸'
}
},
methods:{
getmsg(msg){
console.log(msg)
this.msg = msg
}
},
components:{Child1}
}
</script>
<style>
div{
border:1px red solid;
padding:20px;
}
</style>
// child1
<template>
<div>
<h2>Child2</h2>
<p>{{title}}</p>
<button @click="toParent">传递到父元素</button>
</div>
</template>
<script>
export default {
props:['title'],
methods:{
toParent(){
this.$emit('getmsg','爸爸,我知道错了')
}
}
}
</script>
3. Компоненты Brother
Компоненты Brother не могут взаимодействовать напрямую, только родительский элемент должен построить мост, и вы можете испытать это на себе.
4. Предки и потомки обеспечивают и внедряют
Пропс передается слой за слоем, а для внука дедушка нормально.Если так написать после пяти-шести слоев вложенности, то почувствуешь себя скульптурой из песка, так что вот немного непопулярный API.provice/inject, похожий на контекст в React, предназначенный для предоставления данных между слоями.
Теперь многие библиотеки с открытым исходным кодом используют этот API для обмена данными между уровнями, например, element-ui.tabsа такжеselect
<script>
import Child1 from '@/components/Child1'
export default {
name: "app",
provide:{
woniu:'我是蜗牛'
},
components:{Child1}
}
</script>
<style>
// 子孙元素
<template>
<div>
<h3>Grandson1</h3>
<p>
祖先元素提供的数据 : {{woniu}}
</p>
</div>
</template>
<script>
export default {
inject:['woniu']
}
</script>
Однако провайдер и инжект не реагируют. Если элемент-потомок хочет уведомить предка, его нужно взломать. В Vue1 есть два метода диспетчеризации и бордкаста, но в vue2 они исключены. Мы можем смоделировать это сами.
Принцип в том, что вы можете пройти это.детей, чтобы получить родительский компонент и дочерний компонент, мы можем немного рекурсивно
5. dispatch
Относительно просто рекурсивно получить $parent
<button @click="dispatch('dispatch','哈喽 我是GrandGrandChild1')">dispatch</button>
methods: {
dispatch(eventName, data) {
let parent = this.$parent
// 查找父元素
while (parent ) {
if (parent) {
// 父元素用$emit触发
parent.$emit(eventName,data)
// 递归查找父元素
parent = parent.$parent
}else{
break
}
}
}
}
Обратите внимание, что он передается только вверх и не влияет на другие элементы.
6. boardcast
Аналогично диспетчеру, рекурсивно заставьте $children транслировать всем дочерним элементам.
<button @click="$boardcast('boardcast','我是Child1')">广播子元素</button>
function boardcast(eventName, data){
this.$children.forEach(child => {
// 子元素触发$emit
child.$emit(eventName, data)
if(child.$children.length){
// 递归调用,通过call修改this指向 child
boardcast.call(child, eventName, data)
}
});
}
{
methods: {
$boardcast(eventName, data) {
boardcast.call(this,eventName,data)
}
}
}
7. Смонтируйте рассылку и транслируйте по всему миру
Когда вы хотите использовать его, это слишком раздражает, чтобы нуждаться в вашей собственной компонентной внутренней отправке теорем и доске объявлений.Мы монтируем его в цепочку прототипов Vue, не очень ли это высоко, найдите main.js
Vue.prototype.$dispatch = function(eventName, data) {
let parent = this.$parent
// 查找父元素
while (parent ) {
if (parent) {
// 父元素用$emit触发
parent.$emit(eventName,data)
// 递归查找父元素
parent = parent.$parent
}else{
break
}
}
}
Vue.prototype.$boardcast = function(eventName, data){
boardcast.call(this,eventName,data)
}
function boardcast(eventName, data){
this.$children.forEach(child => {
// 子元素触发$emit
child.$emit(eventName, data)
if(child.$children.length){
// 递归调用,通过call修改this指向 child
boardcast.call(child, eventName, data)
}
});
}
Таким образом, его можно использовать непосредственно в компоненте без давления.
8. Несвязанный компонент: шина событий
Если два компонента не при чем, мы можем только использовать режим публикации подписки, чтобы сделать это, и смонтировать его на Vue.protytype, давайте попробуем, мы называем этот механизм механизмом шины, который является любимым event-bus
class Bus{
constructor(){
// {
// eventName1:[fn1,fn2],
// eventName2:[fn3,fn4],
// }
this.callbacks = {}
}
$on(name,fn){
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name,args){
if(this.callbacks[name]){
// 存在 遍历所有callback
this.callbacks[name].forEach(cb=> cb(args))
}
}
}
Vue.prototype.$bus = new Bus()
использовать
// 使用
eventBus(){
this.$bus.$emit('event-bus','测试eventBus')
}
// 监听
this.$bus.$on("event-bus",msg=>{
this.msg = '接收event-bus消息:'+ msg
})
По сути, Vue сам по себе является реализацией публикации подписки, давайте поленимся, мы можем удалить класс Bus и создать пустой экземпляр Vue.
Vue.prototype.$bus = new Vue()
9. vuex
Обобщив так много, на самом деле лучшая практика — это vuex, и я напишу статью, чтобы узнать об этом позже.
После прочтения этой статьи компонентная коммуникация Vue должна быть для вас сложной, и поздравляю с прохождением бронзы и официальным выходом на серебряный уровень ордена Vue.