Create by jsliang on 2018-11-8 13:34:30
Recently revised in 2019-1-12 19:23:17
Привет друзья, если вы считаете, что эта статья неплохая, не забудьте датьstar, ВашstarЭто моя мотивация учиться!Адрес GitHub
【2019-08-16】Привет друзья, потому чтоjsliangБиблиотека документации подверглась рефакторингу, некоторые ссылки на эту статью могут быть битыми, иjsliangУ меня нет сил поддерживать старые статьи на стороне Nuggets, извините за это. Для тех, кому нужно получать последние статьи, щелкните адрес GitHub выше и перейдите в библиотеку документов, чтобы просмотреть скорректированные статьи.
Рекомендуется пройти目录и использовать返回目录Кнопка для лучшего чтения.
каталог
В чем разница между передней частью, которая не подбрасывается, и соленой рыбой~
два текста
иметь благодарность:Официальная документация Vue
Vue (произносится как /vjuː/, похоже на view) — это прогрессивный фреймворк для создания пользовательских интерфейсов. В отличие от других крупных фреймворков, Vue разработан так, чтобы его можно было применять слой за слоем снизу вверх. Основная библиотека Vue ориентирована только на уровень представления, который не только прост в использовании, но и легко интегрируется со сторонними библиотеками или существующими проектами. С другой стороны, в сочетании с современными наборами инструментов и различными вспомогательными библиотеками Vue также полностью способен работать со сложными одностраничными приложениями.
Учебная версия:v2.5.21
Время написания:2019-1-10
Если версия слишком сильно меняется или время, когда друзья видят эту статью и не обновляют ее в течение длительного времени, друзья, пожалуйста, проверьте официальную документацию Vue, чтобы узнать последнюю версию Vue.
2.1 Первое знакомство с Vue
Итак, как подбрасывает Vue?
Без лишних слов, давайте посмотрим непосредственно на реализацию кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: '#app',
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<div>
<p>Hello World</p>
</div>
`
})
</script>
</body>
</html>
Теперь давайте разберем код для запуска:
- Сначала создайте пустой файл шаблона html для ссылки на Vue через CDN:
Vue обычно делится на две версии:
Версия для разработчиков: в разработке есть удобные подсказки об ошибках.
Рабочая версия: версия, используемая для онлайн-развертывания, пакет кода относительно небольшой.
фрагмент кода index.html
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
- Затем мы пишем точку монтирования, которая представляет собой DOM, в котором в конечном итоге будет работать наш Vue:
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
- Наконец, мы передаем новый объект экземпляра Vue нашему идентификатору как
appУзел DOM для работы:
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容。
// 最外层必须有一层包裹,例如 <div>
template: `
<div>
<p>Hello World</p>
</div>
`
})
Таким образом, мы, наконец, показываем простую ссылку на Vue, вам не кажется, что это очень просто:
2.2 Монтировать данные - данные
Если бы Vue был толькоtemplateЭтот шаблон загружается, далее он мало чем отличается от jQuery, воспользуемся Vue'sdataЧтобы отобразить данные:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: '#app',
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<div>
<p>{{ text }}</p>
</div>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
text: 'Hello World!'
}
}
})
</script>
</body>
</html>
Здесь мы видим, что мыtemplateдобавил один<p>ярлык, через{{ text }}форма, которая вводитtextизdataданные:
<p>{{ text }}</p>
Тогда мы<scirpt>определено вtextКонтент, позволяющий отображать данные:
data() {
return {
// template 中要使用的数据
text: 'Hello World!'
}
}
Таким образом, мы знаем, что можем не только передать шаблонtemplateоказывать<div>теги, мы также можем преобразовать данные или переменные, определенные в js, оперируяdataТем самым изменив содержимое в файле html.
2.3 Дальнейшая оптимизация эл.
существует2.1Главы и2.2глава, мы используемelСпособ таков:
el: '#app',
ДолженelВ форме монтирования во внутреннем рабочем механизме Vue он будет искать в соответствии с переданным вами значением:
- Если входящий
#app, то он оценивает поискidдляappузел; - Если входящий
.app, то ищетclassдляappузел; - Если имя узла передается в
div, затем он ищет имя узла...
Каждому должно быть ясно, что такой суд и поиски потребуют времени, а совершать еще один суд — грех.
Так что мы можем:
el: document.getElementById('app'),
Эта операция заставляет Vue напрямую монтировать точку монтирования вidдля лучшей скорости загрузки. вот такelнебольшая оптимизация.
2.4 Интерполяционные выражения — {{ }}
Если у вас есть небольшое впечатление, вы все равно должны помнить, что мы находимся в главе2.2прошедший{{}}Использование этого интерполяционного выражения вdataработать с содержащимися в нем данными.
Далее мы поясним это интерполяционное выражение{{}}Какое дерьмо вы можете сделать:
- Объект: {{ {имя: 'валет'} }}
- Строка {{ 'Привет, мир!' }}
- Логическое значение: {{ isTrue == -1 }}
- Тернарное выражение: {{ isTrue ? 'true' : 'false' }}
Буквального понимания недостаточно, продемонстрируем работу через код:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<div>
<p>{{ text }}</p>
<p>{{ {name: 'jack'} }}</p>
<p>{{ 'Hello World!' }}</p>
<p>{{ isTrue == -1 }}</p>
<p>{{ isTrue ? '真' : '假' }}</p>
</div>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
text: 'Hello World!',
isTrue: true
}
}
})
</script>
</body>
</html>
Отображается в браузере как:
Объяснение кода ключа:
<div>
<!-- 赋值 text 到 <p> 标签中 -->
<p>{{ text }}</p>
<!-- 赋值对象到标签中 -->
<p>{{ {name: 'jack'} }}</p>
<!-- 直接赋值字符串到标签中 -->
<p>{{ 'Hello World!' }}</p>
<!--
直接进行布尔判断,isTrue 在 data 中设置为 true,
而 -1 转为 布尔值 是 false,所以两者不相等
输出值为 false
-->
<p>{{ isTrue == -1 }}</p>
<!-- 运行三元表达式,isTrue 为 true,输出 真 -->
<p>{{ isTrue ? '真' : '假' }}</p>
</div>
С помощью тернарных выражений мы можем сделать некоторые суждения: последний элемент массива, отображается ли он динамически или скрыт и т. д.
2.5 Директивы - v-*
В Vue, если вы просто используете{{}}Этот тип выражения интерполяции не может удовлетворить наше желание манипулировать данными. Итак, Vue начинается сv-if,v-bindи другие формы, обеспечивающие более удобные операции со страницей + данными: инструкции
v-textv-htmlv-ifv-else-ifv-elsev-showv-bindv-onv-modelv-for
Здесь страница используется для отображения всех инструкций.Если вы хотите узнать больше об инструкциях по одной, рекомендуется перейти на официальный сайт для просмотра и изучения:Vue-директивы
Итак, как используются приведенные выше команды? здесь черезindex.htmlИ картинка, демонстрирующая его основное использование:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
<style>
/* 颜色样式:红、绿、蓝 */
.color-red {
color: red;
}
.color-blue {
color: blue;
}
.color-green {
color: green;
}
</style>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<div>
<p>v-text 演示</p>
<p v-text='vTextOrHtml'></p>
<br/>
<p>v-html 演示</p>
<p v-html='vTextOrHtml'></p>
<br/>
<p>v-if -> v-else-if -> v-else 演示</p>
<p v-if='vIf == 1'>Hello v-If</p>
<p v-else-if='vIf == 2'>Hello v-else-if</p>
<p v-else>Hello v-else</p>
<br/>
<p>v-show 演示</p>
<p v-show='isTrue'></p>
<br/>
<p>v-bind:××× -> :××× 演示</p>
<input v-bind:value="vBind" v-bind:class="colorRed" type="text"/>
<input v-bind:other1="other1" :other2="other2" :other3=" 'other3' " value="Hello :属性值" type="text"/><br/>
<br/>
<p>v-on:click -> @click 演示</p>
<button v-on:click=" vBind= 'Hello v-on:click' ">v-on:click - 点击直接改变 vBind 的值</button><br>
<button @click="changevBindValue">v-on:click - 点击通过事件改变 vBind 的值</button><br>
<br/>
<p>v-model 演示</p>
<input v-model="vModel" type="text" />
<p>{{ vModel }}</p>
<br/>
<p>v-for 演示</p>
<ul v-for="(item, index) in vFor" :class="item.classStyle">
<li>{{index+1}}. {{item.name}} - {{item.age}}</li>
</ul>
</div>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
// v-text 及 v-html 使用数据
vTextOrHtml: '<span style="color: red">我是红的</p>',
// v-if 使用数据
vIf: 2,
// v-show 使用数据
isTrue: false,
// v-bind 使用数据
vBind: "Hello v-bind",
// v-bind 通过动态绑定 class 修改样式
colorRed: 'color-red',
// v-bind 的 :属性 的使用形式
other1: 'other1',
// 同上
other2: 'other2',
// v-model 使用数据
vModel: 'Hello v-model',
// v-for 使用数据
vFor: [{
name: '张三', // 姓名
age: 22, // 年龄
classStyle: "color-red" // 样式
},
{
name: '李四',
age: 23,
classStyle: "color-blue"
},
{
name: '王五',
age: 24,
classStyle: "color-green"
}
]
}
}
})
</script>
</body>
</html>
Давайте посмотрим на следующую страницу:
Здесь мы объясняем код следующим образом:
<div>
<!--
1. v-html
这里直接将 vTextOrHtml 中的文本
当成 string 渲染到页面中去
-->
<p v-text='vTextOrHtml'></p>
<br/>
<!--
2. v-html
这里在渲染 vTextOrHtml 的过程中,
如果遇到标签,则对标签页进行渲染
-->
<p v-html='vTextOrHtml'></p>
<br/>
<!--
3. v-if/v-else-if/v-if
判断 data 中 vIf 的值是多少,
这里有三种情况:v-if、v-else-if、v-else。
如果项目中有更多情况,则再添加 v-else-if 即可
-->
<p v-if='vIf == 1'>Hello v-If</p>
<p v-else-if='vIf == 2'>Hello v-else-if</p>
<p v-else>Hello v-else</p>
<br/>
<!--
4. v-show
判断 isTrue 是真还是假,
它不同于 v-if 的方面是:
v-if 如果是假,则在 Element 中没有渲染
v-show 如果是假,则该标签为 display: none
-->
<p v-show='isTrue'></p>
<br/>
<!--
5. v-bind
v-bind 有两种格式:
1. v-bind:value - 全写
2. :value - 简写
我们还可以通过 v-bind:class 来动态赋值
v-bind:other1="other1" 在页面中显示就是:
<input other1="other1" />>
-->
<input v-bind:value="vBind" v-bind:class="colorRed" type="text"/>
<input v-bind:other1="other1" :other2="other2" :other3=" 'other3' " value="Hello :属性值" type="text"/><br/>
<br/>
<!--
6. v-on
v-on:click 有两种格式:
1. v-on:click - 全写
2. @click - 简写
v-on:click 除了可以直接在里面写表达式,还可以填写方法
-->
<button v-on:click=" vBind= 'Hello v-on:click' ">v-on:click - 点击直接改变 vBind 的值</button><br>
<button @click="changevBindValue">v-on:click - 点击通过事件改变 vBind 的值</button><br>
<br/>
<!--
7. v-model
v-model 是双向数据绑定,
在这里,上面 input 的修改
会影响到下面 p 显示的内容
-->
<input v-model="vModel" type="text" />
<p>{{ vModel }}</p>
<br/>
<!--
8. v-for
v-for 循环体遍历输出
-->
<ul v-for="(item, index) in vFor" :class="item.classStyle">
<li>{{index+1}}. {{item.name}} - {{item.age}}</li>
</ul>
</div>
Разница между v-bind и v-model:
- v-bind: синхронизировать данные в Vue со страницей, то есть это значение в основном используется для фронтенда для передачи фиксированных данных в браузер. v-bind может присваивать значения любому свойству и представляет собой односторонний поток данных из Vue на страницу, т.е. Vue -> html.
- v-модель: двусторонняя привязка данных, внешний интерфейс передает данные в браузер, и внешний интерфейс пользователя в браузере может быть обнаружен. v-model может выполнять двустороннюю привязку данных только для элементов со значениями атрибутов (необходимо использовать элементы со значениями атрибутов), т.е. Vue -> html -> Vue
Что касается инструкций Vue, здесь мы сначала имеем полное и простое представление о нем и знаем, как его использовать.
Для тех, кто хочет узнать подробнее, не забудьте зайти в официальную документацию:Vue-документация
2.6 События - методы
в предыдущей главе2.5, мы проходим вbuttonиспользуется вv-on:clickКогда к нему привязан метод события.
Но когда2.5В , мы говорили об использовании метода события в целом, но знаем о нем немного.
Здесь мы извлекаем их, чтобы объяснить:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<button @click="addStyle">添加行内样式</button>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
addStyle(e) {
e.toElement.style.background = "red"
}
}
})
</script>
</body>
</html>
На данный момент эффект клика на странице выглядит следующим образом:
Теперь давайте проанализируем следующую страницу:
-
первый,над
<button>, мы проходим@clickпривязанное к событиюaddStyle:
<button @click="addStyle">添加行内样式</button>
-
тогда, метод записи должен быть написан с
dataтот же уровеньmethodsсередина:
methods: { // 方法
addStyle: function(e) {
e.toElement.style.background = "red"
}
}
-
потом, мы передаем параметр
e, можно получить элемент при клике по нему.Поиском мы находим, что структура каталогов, где находится его стиль, выглядит следующим образом:
- button
- toElement
- style
- background
- наконец, мы напрямую изменяем его фон, когда пользователь нажимает кнопку.
2.7 Компоненты - компоненты
Стучите по доске! Стучите по доске! Стучите по доске!
Компоненты находятся в центре внимания изучения Vue.Производство компонентных страниц SPA или SSR делает нашу разработку более удобной.
2.7.1 Начальные компоненты
В предыдущих главах мы использовалиtemplate: ``в письменной формеhtmlЭтикетка. Однако по мере расширения проекта, если весь код написан наtemplate, то нам становится сложно модифицировать. Итак, мы должны найти способ разделить его, например, разделить страницу наheader,content,footerтри части. Таким образом, нам нужно изменитьnav, нужно толькоheaderЕго можно изменить в .
структура страницы
- app
- header
- content
- footer
Такое мышление, вVueВоплощаются в виде компонентов (компонентов, которые объединяются). Затем вVue, что нужно сделать, чтобы лучше разделить компоненты?
первый, обводим логику:
В предыдущей главе, в определении Vue, мы сначалаtemplateПодключен к идентификатору какappна узле. потомtemplateДелится на три блока:header,content,footer.
Здесь мы будем
#appизtemplateназывается родительским компонентом,headerКогда это называется подкомпонентом, это похоже на троих сыновей от отца.
потом, мы пытаемся начать сnew VueИзвлеките один компонент из:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 声明入口组件
var App = {
template: `<h1>我是入口组件</h1>`
}
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: '<app/>',
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
app: App
}
})
</script>
</body>
</html>
На данный момент страница выглядит так:
тогда, мы анализируем трилогию, проведенную под:
- существует
componentопределяется и извлекаетсяApp - существует
new Vueвнешнее определениеApp - существует
templateиспользуется вApp
Таким образом, мы добиваемся разделения отдельных компонентов, иnew VueдаAppродительский компонент,Appдаnew Vueподкомпонент .
наконец, так как выше было достигнуто извлечение одного компонента, теперь мы реализуем извлечение нескольких компонентов:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue学习</title>
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 声明头部组件
var MyHeader = {
template: `<div>我是头部</div>`
};
// 声明内容组件
var MyContent = {
template: `<div>我是躯体</div>`
};
// 声明底部组件
var myFooter = {
template: `<div>我是底部</div>`
}
new Vue({
el: document.getElementById('app'),
components: { // 声明要用的组件们
// key 是组件名,value 是组件对象
'my-header': MyHeader,
'my-content': MyContent,
'my-footer': myFooter
},
template: `
<div>
<my-header/>
<my-content/>
<my-footer/>
</div>
`
})
</script>
</body>
</html>
Таким образом, мы добились разделения компонентов.
Уведомление:templateСуществует только один корневой узел, если корневого узла нет, Vue выдаст вам ошибку.
template: `
<my-header/>
<my-content/>
<my-footer/>
`
Приведенное выше написание неверно, имейте в виду.
Делая это, мы можем снова повеселиться, иmyHeader,myContent,myFooterможет следоватьnew Vueнаписать то же самоеdata,methodsО~
Например:
var MyHeader = {
data() {
return {
// ... 定义数据
}
},
template: `<h1>我是头部</h1>`,
methods: {
// 定义方法
}
};
2.7.2 Связь между родительским и дочерним компонентами
Поскольку предыдущая глава была разделена на компоненты родительской дочерней связи, то здесь наши переговоры более интересны: коммуникации отца и дочерних компонентов.
Между компонентами мыnew VueАналогичен родителю (parent component), у него есть свойdata. Тогда у дочернего компонента тоже будет свойdata.
- Если однажды отец найдет своего сына и захочет сказать ему:
“其实你不是我亲生的,你的姓名是***”.
Затем вVue, что нам нужно сделать, чтобы его сын (субкомпонент) знал, как его фамилия? Давайте посмотрим на код:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 子组件
var Son = {
template: `
<div>我的名字:{{name}}</div>
`,
props: ['name']
}
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<son :name="name"></son>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
name: '皮皮虾'
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
son: Son
}
})
</script>
</body>
</html>
После написания кода мы видим в браузере, браузер показывает:我的名字:皮皮虾, эти большие персонажи.
О, фамилия сына оригинального отца皮. В то же время мы также знаем, что данные в родительском компоненте черезv-bind:***в виде родительского компонентаdata, отправленный дочернему компоненту. А как насчет подкомпонентов, черезpropsОпределение , получает данные отца.
Таким образом, мы добились того, чтобы родительский компонент передал данные дочернему компоненту.
2.7.3 Общие компоненты
Выше мы упомянули:
- App
- my-header
- my-content
- my-footer
существуетAppНа этот компонент мы монтируем три подкомпонента:myHeader,myContent,myFooter.
- Однако, если однажды появится девушка (всего компонентов), и девушку зовут:
beautifulGirl. Тогда не только трое сыновей (дочерние компоненты) хотят преследовать ее, но даже отец (родительский компонент) хочет ее преследовать (достаточно безумно).
Затем вVueКаким образом, чтобы и отец, и сын имели возможность связаться с этой девушкой? (Как родительские и дочерние компоненты могут использовать общие компоненты)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 声明头部组件
var MyHeader = {
template: `
<div>我是头部,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 声明内容组件
var MyContent = {
template: `
<div>我是内容区,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 声明底部组件
var myFooter = {
template: `
<div>我是底部,我想了解<beautiful-girl></beautiful-girl></div>
`
}
// 声明共用组件
Vue.component('beautiful-girl', {
template: `<span>—— 美丽女孩 ——</span>`
})
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<div>
<my-header/>
<my-content/>
<my-footer/>
</div>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
'my-header': MyHeader,
'my-content': MyContent,
'my-footer': myFooter,
}
})
</script>
</body>
</html>
Здесь мы проходимVue.component('组件名',{ })форме зарегистрирован глобальный компонентbeautiful-girl, таким образом, и родительский, и дочерний компоненты могут напрямую вызывать компонент, который отображается в браузере как:
Теперь и отец, и сын могут общаться с красивыми девушками. Отец нашел сыну мачеху или сын нашел свою любовь? Следите за обновлениями...
2.8 Фильтр - фильтр
На работе нам часто нужно фильтровать данные, возвращаемые некоторыми бэкендами. Например: деньги, возвращаемые нашим братом Ява, делятся на баллы, то есть: 1 юань = 100 баллов. Итак, возвращается 2000, что на самом деле составляет 20 юаней. Итак, как во Vue мы фильтруем данные?
2.8.1 Локальная фильтрация
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 声明头部组件
var MyHeader = {
template: `
<div>我是头部,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 声明内容组件
var MyContent = {
template: `
<div>我是内容区,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 声明底部组件
var myFooter = {
template: `
<div>我是底部,我想了解<beautiful-girl></beautiful-girl></div>
`
}
// 声明共用组件
Vue.component('beautiful-girl', {
template: `<span>—— 美丽女孩 ——</span>`
})
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<p>我是钱多多,我有 {{money}} 多一点: ¥{{money | addDot}},跟我混有出息~</p>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
money: 1000000
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
},
// 8. filters - 组件内的过滤器
filters: {
addDot(money) {
return (money / 1000000 + ".000000");
}
}
})
</script>
</body>
</html>
Выше мы проходимfiltersсерединаaddDotметод, данные фильтруются,moneyданные из10000000стал1.000000.
2.8.2 Глобальная фильтрация
Затем, попробовав местныйfiltersПосле преимуществ мы также можем попробовать его метод написания глобального фильтра:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 全局过滤器
Vue.filter('addDot', function(money) {
return (money / 1000000 + ".000000");
})
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<p>我是钱多多,我有 {{money}} 多一点: ¥{{money | addDot}},跟我混有出息~</p>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
money: 1000000
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
},
// 8. filters - 组件内的过滤器
filters: {
}
})
</script>
</body>
</html>
И, наконец, отображается на странице как:
2.9 Данные мониторинга
существуетVue, мы проходимv-modelВыполняется двусторонняя привязка данных, т. е. в<input>Значение, введенное в , в нашемVueданные доступны в;VueДанные, определенные в , также будут немедленно отображены на странице.
Однако в коде, как мы можем получить данные, которые он вводит на лету?
2.9.1 Свойство прослушивания — часы
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<div>
<input type="text" v-model="money" />
<span>{{money}}</span>
</div>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
money: ''
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
},
// 8. filters - 组件内的过滤器
filters: {
},
// 9. watch - 侦听属性
watch: {
// key: data 属性的属性名
money(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
})
</script>
</body>
</html>
Таким образом, когда мы вводим 11 1, браузерConsoleСоответствующий вывод:
2.9.2 Вычисляемые свойства - вычисляемые
Выше мы говорили оwatchконтролироватьdataсерединаnumber,stringи т.д. изменения поля. Однако в Vue, чтобы облегчить наши операции мониторинга, Vue также определяет метод:computed, мы можем пройтиcomputed, следите за нашимиdataВсе данные, определенные в .
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue学习</title>
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: document.getElementById('app'),
template: `
<div>
<input type="text" v-model="number1" />
+
<input type="text" v-model="number2" />
*
<input type="text" v-model="number3" />
=
{{result}}
</div>
`,
data: {
number1: 0,
number2: 0,
number3: 0,
result: '',
},
computed: {
// 如果原值不变,缓存不调函数的优化机制
result: function() {
// 监视对象,写在了函数内部,
// 凡是函数内部有 this. 相关属性,改变都会触发当前函数
let addSum = parseInt(this.number1) + parseInt(this.number2);
let allSum = addSum * this.number3;
return allSum;
}
}
})
</script>
</body>
</html>
Результат показан на GIF-изображении ниже:
2.9.3 Сравнение часов, вычислений и методов
Выше мы задействовали две точки знаний:watchа такжеcomputed.
Затем снова настало время «метафизики», все из которых имеют дело с данными мониторинга Когда мы обычно используем Vue, когда мы его используем?watch, когда использоватьcomputed? Затем, если мы добавляем методы, когда мы снова используем методы?
первый, мы сравниваемcomputedа такжеmethods:
-
computedосновывается наdataОперация, выполняемая при изменении данных. которыйthis.任意数据изменилось, тоcomputedизменяется; и еслиthis.任务数据без изменений, тоcomputedОн будет выполнять свою политику кэширования и не будет обновлять -
methodsОбычно он запускается на основе таких событий, как клики, например, пользователь проходит@click="方法"изменить данные.
потом, мы сравниваемcomputedа такжеwatch:
Если указанный выше разделcomputedметод заменен наwatch:
фрагмент кода index.html
// 9. watch - 侦听属性
watch: {
// key: data 属性的属性名
result(newVal, oldVal) {
console.log(newVal, oldVal);
this.result = this.number1 + this.number2 * this.number3;
}
},
ты найдешь,resultДанные не меняются, потому что этоcomputedУникальные вещи, если вам нужно совместитьcomputedметод заменен наwatch, то вам нужно:
фрагмент кода index.html
// 9. watch - 侦听属性
watch: {
// key: data 属性的属性名
number1(val) {
this.result = parseInt(this.number1) + parseInt(this.number2) * parseInt(this.number3);
},
number2(val) {
this.result = parseInt(this.number1) + parseInt(this.number2) * parseInt(this.number3);
},
number3(val) {
this.result = parseInt(this.number1) + parseInt(this.number2) * parseInt(this.number3);
}
},
Таким образом, друзья должны понять, что,watchЗаполните, если необходимоcomputedфункция, то она должна прослушивать каждое свойство, которое необходимо изменить.
наконец, здесь мы примерно описываемwatchа такжеcomputedразличие:
-
computedАкцент на вычислениях, таких какc = a + b,bОн постоянно меняется от внешнего мира, ведь нужно только показатьc, поэтому используйтеcomputed. а такжеwatchАтрибут подчеркивает действие до и после изменения собственного значения, если его нужно завершитьc = a + b, то вам нужноwatchданныеaа такжеbИзменения, когда два изменяются, выполняются в методеc = a + b. -
watchПреимущества в обработке асинхронных операций или операций с большими накладными расходами.- Выполнение асинхронных операций не может возвращать результаты последовательно, используйте
watch; - Для ресурсоемких операций, чтобы избежать блокировки основного потока, используйте
watch; - Простой и серийно возвращаемый, используйте
computed.
- Выполнение асинхронных операций не может возвращать результаты последовательно, используйте
-
computedЗависит от значения привязки.Если значение каждой операции не меняется, расчет не выполняется, и он имеет функцию кэширования. watch будет прослушивать состояние, которое изменяется до и после, независимо от того, изменится ли значение операции, будет выполнено определенное тело функции, поэтому будут данные (newVal, oldVal).
Если друзья настроены серьезно, то, пожалуйста, ознакомьтесь с официальной документацией:Вычисляемые свойства и слушатели
2.10 Прохождение DOM - слот
В нашей повседневной работе мы будем инкапсулировать некоторые часто используемые функции, такие как боковая панель, верхняя панель навигации и т. д., и мы можем напрямую обращаться к ним, когда захотим их использовать. Итак, что еще нам нужно знать во Vue для реализации такой функциональности?
2.10.1 щелевой однопроходный
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var myLi = {
template: `
<li><slot></slot></li>
`
};
Vue.component('my-li', myLi);
var App = {
template: `
<div>
<ul>
<my-li><button>我是第一行 button 按钮</button></my-li>
<my-li><h3>我是第二行 h3 标签</h3></my-li>
<my-li><a href="javascript:void(0)">我是第三行 a 导航</a></my-li>
<my-li><span>我是第四行 span 标签</span></my-li>
</ul>
</div>
`
};
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<app/>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
app: App
},
// 8. filters - 组件内的过滤器
filters: {
},
// 9. watch - 侦听属性
watch: {
// key: data 属性的属性名
},
// 10. computed - 计算属性
computed: {
// 如果原值不变,computed 会执行缓存,即不调用方法
}
})
</script>
</body>
</html>
Результат показан ниже:
Итак, что мы сделали в приведенном выше коде?
первый, как приведенный выше код и его график результатов, нашnew VueКомпонент монтируется вApp.
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `
<app/>
`
})
потом,ДолженAppЦель состоит в том, чтобы динамически ссылаться наliкомпоненты
var App = {
template: `
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
`
};
тогда, мы определяем глобальноmyLiкомпоненты одновременно через<slot></slot>слот, который позволяет загружать его динамическиdomузел.
var myLi = {
template: `
<li><slot></slot></li>
`
};
Vue.component('my-li', myLi);
наконец,мы вApp, передать это по-другомуdomnode, тем самым динамически генерируяApp.
var App = {
template: `
<div>
<ul>
<my-li><button>我是第一行 button 按钮</button></my-li>
<my-li><h3>我是第二行 h3 标签</h3></my-li>
<my-li><a href="javascript:void(0)">我是第三行 a 导航</a></my-li>
<my-li><span>我是第四行 span 标签</span></my-li>
</ul>
</div>
`
};
Таким образом, у нас есть четкое представление о том, как пройти<slot></slot>загружаться динамическиdomNode лучше помогает нам в разработке Vue.
2.10.2 Именованные слоты
Выше мы говорили об одном слотеslotПрименение. Но что, если компонент хочет сохранить количество слотов в зависимости от того, передал ли родительский компонент переменную или нет?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var mySlot = {
template: `
<ul>
<li>
<slot></slot>
</li>
<li>
<slot name="one"></slot>
</li>
<li>
<slot name="two"></slot>
</li>
<li>
<slot name="three"></slot>
</li>
</ul>
`
};
Vue.component('my-slot', mySlot);
var App = {
template: `
<div>
<my-slot>
<p>Helo World!</p>
<button slot="one">按钮</button>
<a href="javascript:void(0)" slot="two">链接</a>
</my-slot>
</div>
`
};
new Vue({
// 3. el - 挂载目标,即渲染在哪个挂载点
el: document.getElementById('app'),
// 4. template - 模板,即渲染到挂载点的内容
// 最外层必须有一层包裹,例如 <div>
template: `
<app/>
`,
// 5. data - 数据,即在操作中需要用到的数据
// 可以理解为在 jQuery 中 var text = "Hello World!"
// {{ text }} 为数据渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的数据
}
},
// 6. methods - 方法,即我们的页面事件
// 可以理解为在 jQuery 中定义 Function
methods: {
},
// 7. components - 组件名称
components: {
// key 是组件名,value 是组件对象
app: App
},
// 8. filters - 组件内的过滤器
filters: {
},
// 9. watch - 侦听属性
watch: {
// key: data 属性的属性名
},
// 10. computed - 计算属性
computed: {
// 如果原值不变,computed 会执行缓存,即不调用方法
}
})
</script>
</body>
</html>
Схема эффекта выглядит следующим образом:
Давайте проанализируем, что мы сделали в коде:
первый, мы можем узнать из следующего кода, что первыйliизslotбезымянный по умолчаниюslot, поэтому он отображается на странице какpДанные.
var mySlot = {
template: `
<ul>
<li>
<slot></slot>
</li>
</ul>
`
};
var App = {
template: `
<div>
<my-slot>
<p>Helo World!</p>
<button slot="one">按钮</button>
<a href="javascript:void(0)" slot="two">链接</a>
</my-slot>
</div>
`
};
потом, А затем наблюдается подAppкодировать<button slot="one">按钮</button>а также<a href="javascript:void(0)" slot="two">链接</a>, обнаружили, что они использовалиslot="***", в котором говорится, что он указывает требование в компоненте<slot name="***"></slot>код для получения. Таким образом, вторая и третья строки отображаются как кнопки и ссылки.
наконец, с момента последнегоliсередина<slot name="three"></slot>,этоname="three"существуетAppОн не используется в компоненте, поэтому отображается пустым.
2.11 Жизненный цикл компонента Vue
В Vue, когда виртуализироватьdomвизуализировать какdom, или при уничтожении кода есть соответствующие хуки:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- activated
- deactivated
- beforeDestory
- destory
Что касается жизненного цикла, в официальной документации Vue есть соответствующие диаграммы и документы:Официальная документация — жизненный цикл Vue
Далее мы объясним использование этих 5 групп жизненных циклов посредством демонстрации кода.
2.11.1 beforeCreate & created
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var lifeCycle = {
template: `
<div>
我是生命周期组件
</div>
`,
data: function() {
return {
text: 'Hello World!'
}
},
beforeCreate: function() {
// 组件创建之前
console.log(this.text); // [Console] undefined
},
created: function() {
// 组件创建之后
console.log(this.text); // [Console] Hello World!
}
/*
* 使用 lifeCycle 组件,就会触发以上的事件函数(钩子函数)
* created 中可以操作数据,并且可以实现 Vue -> 页面 的影响
* 应用:发起 ajax 请求
*/
}
var App = {
components: {
'life-cycle': lifeCycle
},
template: `
<div>
<life-cycle></life-cycle>
</div>
`
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `
<app/>
`
})
</script>
</body>
</html>
Как вы можете видеть в коде, мыAppпроцитировано вlifeCycleэтот компонент.
Мы передаем функцию ловушкиbeforeCreate(до создания компонента) сcreated(после создания компонента) объединитьconsoleОбнаружено, что эти две функции ловушек предназначены дляdataНапример, один вdataПеред монтированием (beforeCreate), так что печатается:undefined, а другое происходит вdataПосле монтажа выводится следующее:Hello World!.
2.11.2 beforeMount & mounted
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var lifeCycle = {
template: `
<div>
我是生命周期组件
</div>
`,
data: function() {
return {
text: 'Hello World!'
}
},
beforeMount: function() {
// Vue 起作用之前
console.log(document.body.innerHTML);
},
mounted: function() {
// Vue 起作用,装载数据到 DOM 之后
console.log(document.body.innerHTML);
}
}
var App = {
components: {
'life-cycle': lifeCycle
},
template: `
<div>
<life-cycle></life-cycle>
</div>
`
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `
<app/>
`
})
</script>
</body>
</html>
Таким образом, несмотря на их функции, одна выполняется до того, как Vue заработает, а другая — после того, как Vue заработает, после загрузки данных в DOM.
Как мы должны наблюдать его в действии?
Увидев красный прямоугольник на картинке выше, может быть, вы вдруг осознаете: «О,beforeMountэто функция ловушки, которую я загрузил ранее, иmountedЭто функция ловушки после того, как я ее загружу, это DOM после того, как Vue сработает».
2.11.3 beforeUpdate & updated
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var lifeCycle = {
template: `
<div id="update">
<p>我是生命周期组件</p>
<p>{{text}}</p>
<button @click="text = '!dlroW olleH'">点击改变 text</button>
</div>
`,
data: function() {
return {
text: 'Hello World!'
}
},
// 基于数据改变,影响页面
beforeUpdate: function() {
// 改变前
console.log(document.getElementById('update').innerHTML);
},
updated: function() {
// 改变后
console.log(document.getElementById('update').innerHTML);
}
/*
* 在日常工作中,我们可以在事件前后拿到它的 DOM,从而做一些我们想要的操作
*/
}
var App = {
components: {
'life-cycle': lifeCycle
},
template: `
<div>
<life-cycle></life-cycle>
</div>
`
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `
<app/>
`
})
</script>
</body>
</html>
Прежде чем разбирать код, давайте посмотрим на его вывод:
Как можно заметить,beforeUpdateможет получить исходный DOM иupdatedНовый DOM может быть получен.
Они реализованы в приведенном выше коде как: get<button>DOM изменяется до и после события, вызванного кнопкой. Благодаря этому изменению мы можем выполнять в нем некоторые операции, чтобы лучше соответствовать потребностям нашего бизнеса.
- резюме:(
beforeMount&mounted) против (beforeUpdate&updated)
Итак, возникает вопрос,beforeMountЭта группа иbeforeUpdateМожно ли отслеживать изменения DOM, в чем между ними разница?
Ответ, как правило, если нам нужно отслеживать изменения DOM при загрузке страницы, тогда используйтеbeforeMountа такжеmounted; однако, если мы хотим отслеживать действия пользователя (события кликов и т. д.), то нам нужно использоватьbeforeUpdateа такжеupdated, потому что они не похожиbeforeMountа такжеmountedОни будут выполняться только один раз в начале монтирования страницы, их можно выполнять несколько раз в зависимости от действий пользователя.
2.11.4 beforeDestory & destory
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var lifeCycle = {
template: `
<div id="update">
<p>我是生命周期组件</p>
</div>
`,
// 对应父组件 v-if == false 的时候,就产生下面钩子函数,销毁当前组件
beforeDestroy: function() {
// 销毁之前
console.log('实例销毁之前调用。在这一步,实例仍然完全可用。');
},
destroyed: function() {
// 销毁之后
console.log('Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。');
}
}
var App = {
components: {
'life-cycle': lifeCycle
},
data: function() {
return {
isExist: true
}
},
template: `
<div>
<life-cycle v-if="isExist"></life-cycle>
<button @click="isExist = !isExist">点击改变 子组件 状态</button>
</div>
`
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `
<app/>
`
})
</script>
</body>
</html>
Здесь мы нажимаем<button>, в консоли отображается:
Видно, что когда мы нажимаем<button>когда нашisExistСостояние (в первый раз) изменяется наfalse, что вызываетlifeCycleФункция ловушки разрушения выводит на консоль две приведенные выше строки.
Соответственно, еслиisExistстатус становитсяtrue, это вызовет нашbeforeCreateа такжеcreatedЗаинтересованные партнеры могут попробовать эти две функции ловушек, я не буду здесь слишком много демонстрировать.
2.11.5 activated & deactivated
После длительного периода работы мы знаем, что если DOM часто манипулировать, это повлияет на функцию ловушки.beforeCreateа такжеcreatedа такжеbeforeDestoryа такжеdestoryОперация повлияет на нашу производительность. Как мы можем предотвратить частое использование DOM определенной частью кода и контролировать его работу?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var lifeCycle = {
template: `
<div id="update">
<p>我是生命周期组件</p>
</div>
`,
activated: function() {
console.log("组件被激活了");
},
deactivated: function() {
console.log("组件被停用了");
}
}
var App = {
components: {
'life-cycle': lifeCycle
},
data: function() {
return {
isExist: true
}
},
template: `
<div>
<keep-alive>
<life-cycle v-if="isExist"></life-cycle>
</keep-alive>
<button @click="isExist = !isExist">点击改变 子组件 状态</button>
</div>
`
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `
<app/>
`
})
</script>
</body>
</html>
В коде мы передаем<keep-alive></keep-alive>Этот встроенный компонент Vue оборачивает наши дочерние компоненты.
Затем, когда мы переходим на страницу и нажимаем кнопку, она делаетactivatedа такжеdeactivatedЗапуск этих двух функций ловушки:
Видно, что когда мы заходим на страницу, нам сообщает, что компонент активирован. когда мы впервые нажимаем<button>кнопка,isExistстатус сталfalse, то есть компонент деактивирован. Наконец, мы снова щелкнули<button>, то консоль снова печатает组件被激活了.
- Резюме: в этот раз я надеюсь, что вы можете вернуться к началу главы о жизненном цикле и посмотреть на официальную диаграмму анализа жизненного цикла, которая поможет нам лучше понять цикл декларации. Если все еще недостаточно ясно, вы можете нажать кнопку рядом с картинкой, чтобы войти в официальный документ и просмотреть официальный анализ жизненного цикла.【Вернуться к углубленному изучению】
2.12 Получение элементов DOM
В повседневной разработке некоторые мелкие партнеры могут думать об управлении элементами DOM. Если вы используете оригиналdocument.getElementByIdНу может тожеlowИтак, есть ли что-то похожее на jQuery?$("#id")что о?
2.12.1 Получение одного элемента DOM
Без лишних слов, давайте начнем с кода:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var App = {
template: `
<div>
<button ref="btn">按钮</button>
</div>
`,
beforeCreate: function() {
// 这里不能操作数据,只是初始化了事件等……
console.log(this.$refs.btn); // [Console] undefined
},
created: function() {
// 可以操作数据了
console.log(this.$refs.btn); // [Console] undefined
},
beforeMount: function() {
// new Vue 发生装载,替换 <div id="app"></div> 之前
console.log(this.$refs.btn); // [Console] undefined
},
mounted: function() {
// 装载数据之后
console.log(this.$refs.btn.innerHTML); // [Console] 按钮
}
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `<app/>`
})
</script>
</body>
</html>
Давайте сначала посмотрим на следующую страницу:
первый, мы находимся в DOM-части компонента (<button>), напишите ref="btn".
потом, мы обнаруживаем, что только вmountedПосле загрузки данных в этой функции ловушки через объект компонентаthis.$refs.btnМожет получить элемент
так, мы знаем, как легко получить элементы DOM через Vue в некоторых сценариях.
2.12.2 Получение элемента DOM компонента
Выше мы получаем часть одного DOM-узла, если нам нужно получить весь дочерний компонент, то как это сделать?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var tempComponent = {
template: `
<div>我是临时组件</div>
`
}
Vue.component('temp', tempComponent);
var App = {
template: `
<div>
<temp ref="temp" />
</div>
`,
mounted: function() {
// 装载数据之后
console.log(this.$refs.temp.$el);
}
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `<app/>`
})
</script>
</body>
</html>
Не будем спешить сначала разбирать, посмотрим, что напечатает консоль;
Здесь вы можете видеть, что он выводит кучу информации о компоненте, который
-
$children- дочерние компоненты текущего компонента -
$el- узел элемента текущего компонента -
$parent- родительский компонент текущего компонента -
$root- Получатьnew Vueпример
затем найдите элемент$elэто содержимое узла DOM, мы пытаемся распечатать его, чтобы увидеть:
console.log(this.$refs.temp.$el);
Console
<div>我是临时组件</div>
Как видно из консоли,$elвы можете распечатать<button>элемент тоже.
2.12.3 Vue.nextTick()
Конечно, иногда мы манипулируем DOM просто для того, чтобыdataОперация выполняется при изменении данных, при использовании вышеуказанного метода иногда невозможно ее обработать.
Так что нам делать?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 学习</title>
</head>
<body>
<!-- 2. Vue 挂载点 - Vue 的虚拟 DOM 在这里操作到实际渲染 -->
<!-- 简单理解为 jQuery 的拼接字符串(并不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 调用接口 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
var App = {
template: `
<div>
<input v-if="isShow" ref="input" />
</div>
`,
data: function() {
return {
isShow: true
}
},
mounted: function() {
// 希望在 Vue 真正渲染 DOM 到页面之后进行下面操作
this.$nextTick(function() {
this.$refs.input.focus();
})
}
}
new Vue({
el: document.getElementById('app'),
components: {
app: App
},
template: `<app/>`
})
</script>
</body>
</html>
Как и выше, через глобальный API Vue.Vue.nextTick(), мы выполняем отложенный обратный вызов после завершения следующего цикла обновления DOM. Используйте этот метод сразу после изменения данных, чтобы получить обновленную модель DOM.
Мы можем представить этоPromiseПроцесс выполнения получит лучший опыт.
Три реальных боя
Итак, изучив это, мы должны выполнить простое упражнение, чтобы повторить то, что мы узнали:
Четыре резюме
Как и выше, мы запустили базовый Vue, и, возможно, у друзей все еще будет кружиться голова.
Но это не имеет значения, мы по-прежнему будем использовать базовый синтаксис Vue, когда будем объяснять VueRouter и VueCli, как в этом предложении:Десять тысяч футов высоких зданий возвышаются над землей, и фундаменты должны быть подняты сами по себе..
Делай больше практики, делай больше заметок, ты всегда можешь быть опытным, давай~
постскриптум
Если вашему партнеру нужно хранитьjsliang.topЧисто статическая страница, подобная этой илиcompany.jsliang.topДля таких страниц с поддержкой бэкенда Node рекомендуется приобретать облачные серверы для хранения.
Если вы не знаете, как выбрать облачный сервер, вы можете проверитьПодробное введениеили добавитьjsliangQQ:1741020489проконсультируйтесь.
jsliangБиблиотека документацииЛян ЦзюньронгиспользоватьCreative Commons Attribution-NonCommercial-ShareAlike 4.0 Международная лицензияЛицензия.
на основеGitHub.OM/l ЯнДжун Рон…Создание работ выше.
Права на использование, отличные от разрешенных в настоящем Лицензионном соглашении, могут быть получены отCreative Commons.org/licenses/не…получено в.