Я кодировал сайт-клон IMDB с django и vue через cdn. Интерфейс vue улучшен с помощью vuetify, а API json rest, созданный инфраструктурой django rest, можно получить, поместить, опубликовать или удалить с помощью ax ios. Нет npm или зависимости и конфигурации webpack. Репозиторий устанавливается как обычное приложение django.
Я загрузил репозиторий с фиктивными данными в github, ссылка ниже. файл needs.txt имеет все версии, связанные с django. vue и vuetify версии 2.x
Причина использования vue состоит в том, чтобы включить интерактивный пользовательский интерфейс. Конечная цель - создать альтернативный интерфейс администратора, используя vue, как обычный старый jquery через cdn.
На данный момент проект работает довольно хорошо. Однако я должен написать весь код компонента vue на всех страницах. Я копирую и вставляю, затем изменяю некоторые связанные с состоянием вещи (данные) и добавляю или удаляю некоторые методы. Эти компоненты меняются в зависимости от полей модели и связи с другими моделями. Основной скелет такой же.
Я испытал миллионы проб и ошибок, но я не смог найти способ взаимодействия многих связанных между страницами компонентов с одним основным компонентом.
Все коды vue существуют в папке шаблонов, а в папке stati c есть файл js.
Я не хочу терять легкость шаблонизации django стиль и интерактивность vue. js.
URL репо: IMDB Clone с django и vue через cdn
здесь некоторые снимки экрана: снимок экрана 1 снимок экрана 2 снимок экрана 3
, и вот пример кода на одной странице:
// templates/vue/movies/movie_list.html
{% extends 'vue/movies/index.html' %} {% load static i18n %} {% block content %}
<ic-movie></ic-movie>
{% endblock %}{% block extrascript %}
<script>
Vue.component("ic-movie", {
delimiters: ["[[", "]]"],
template: `
<div>
{% include 'vue/cp-title.html' %}
<div v-if="dialog.dDialog">
{% include 'vue/movies/movie_form.html' %}
</div>
{% include 'vue/cp-data-table.html' %}
</div>
`,
data() {
return {
table: {
tData: [],
tLoading: true,
tSearch: "",
tHeaders: [{
text: "{% trans 'Title' %}",
value: "name"
},
{
text: "{% trans 'Release Year' %}",
value: "release_year"
},
{
text: "{% trans 'Duration' %}",
value: "duration"
},
{
text: "{% trans 'IMDB Rating' %}",
value: "imdb_rating"
},
{
text: "{% trans 'Actions' %}",
value: "action",
sortable: false
}
],
tTitle: "{% trans 'Movies List' %}",
tItem: "{% trans 'Movie' %}",
tItemUrl: "{% url 'movie_detail' 0 %}".slice(0, -2),
tSelected: []
},
page: {
pData: {},
pTitle: "{% trans 'Movies' %}",
pUrl: "{% url 'movie_list' %}"
// pItemApiUrl: "/api/v1/student/"
},
dialog: {
dDialog: false,
dValid: false,
dEditedSlug: "",
dEditedItem: {
id: "",
name: "",
slug: "",
release_year: "",
duration: "",
imdb_rating: "",
content: "",
source_content: "",
trailer: "",
image: "",
credit_image: "",
genres: [],
crews: [],
inputRules: [v => v.length > 0 || "{% trans 'Field is required' %}"]
},
dDefaultItem: {
id: "",
name: "",
slug: "",
release_year: "",
duration: "",
imdb_rating: "",
content: "",
source_content: "",
trailer: "",
image: "",
credit_image: "",
genres: [],
crews: []
}
},
list: {
lData: [],
lParentData: [],
lCrewData: [],
lGenreData: [],
lPgRatingData: []
},
include: {
titleToolbar: false,
buttonAll: false,
selectParent: false,
selectFromParent: false,
select: false,
titleRatingButton: false,
titleFavButton: false,
titleImageVideo: false,
isMovie: false,
isCeleb: false,
},
delConfirmText: "{% trans 'Are you sure want to remove ' %}",
cudButton: false,
isAdmin: true
};
},
computed: {
formTitle(item) {
return this.dialog.dEditedSlug === "" ?
"{% trans 'New ' %}" + this.table.tItem :
"{% trans 'Edit ' %}" + this.dialog.dEditedItem.name;
},
},
watch: {
dialog(val) {
val || this.close();
}
},
methods: {
initialize() {
window
.icGet("movie")
.then(res => {
this.table.tData = res;
})
.finally((this.table.tLoading = false));
this.getListCrew();
this.getListGenre();
this.getListPgRating();
},
gotoItem(from, item) {
window.icGoto(this.table.tItemUrl, item.slug);
},
addItem(from) {
this.dialog.dDialog = true;
this.dialog.dEditedSlug = "";
},
editItem(from, item) {
this.dialog.dEditedSlug = item.slug;
this.dialog.dEditedItem = Object.assign({}, item);
this.dialog.dDialog = true;
},
deleteItem(from, item) {
if (confirm(this.delConfirmText + item.name + "?")) {
window.icDelete("movie", item.slug);
window.icGoto(this.page.pUrl);
}
},
saveItem() {
if (this.$refs.form.validate()) {
if (this.dialog.dEditedSlug === "") {
window.icPost("movie", this.dialog.dEditedItem);
} else {
window.icPut(
"movie",
this.dialog.dEditedItem,
this.dialog.dEditedSlug
);
}
this.closeDialog();
}
},
closeDialog() {
this.dialog.dDialog = false;
setTimeout(() => {
this.dialog.dEditedItem = Object.assign({}, this.dialog.dDefaultItem);
this.dialog.dEditedSlug = "";
this.dialog.dValid = false;
this.initialize();
}, 300);
},
getListCrew() {
window.icGet("movie", this.page.pItemSlug, "crews").then(res => {
this.list.lCrewData = res;
});
},
getList(item) {
window
.icGet("genre", item, "movies") // !!!
.then(res => {
this.list.lData = res;
});
},
getListGenre(item) {
window.icGet("genre").then(res => {
// !!!
this.list.lGenreData = res;
});
},
getListPgRating(item) {
window
.icGet("pg_rating") // !!!
.then(res => {
this.list.lPgRatingData = res;
});
}
},
created() {
this.initialize();
}
});
</script>
{% endblock %}
URL репо: IMDB Clone с django и vue через cdn