イオンフレームワークから市場(よく並べ替え)パート1
100518 ワード
編集者
ようこそ戻る、貼り付けのおかげで、この部分は、エディタに正直にそのエディタよりも多くのVueに焦点を当て、我々はいくつかのコンポーネントを設定し、論理的なルーティング、ローカルストレージとポストの要求を実装する単純なサーバーに.
注:この部分のコードがたくさんあるので、私は記事の一番下にファイルに従ってすべてのコードを投稿します
ヘッダーコンポーネント
コンポーネントの下にヘッダーを作成します.VUE、このコンポーネントは、基本的にアプリケーションのメインウィンドウに表示されるものを決定します.Vue
三つのタグを作る
<template>
</template>
<script>
export default{
name: "Header"
}
</script>
インポートヘッダー.アプリにVue.Vueと削除アプリ.Vue
<template>
<Header/>
</template>
<script>
import Header from "./components/Header.vue";
export default{
name: "App",
components: {
Header
}
}
</script>
<style scoped>
.container{
padding: .4em 1em;
}
</style>
これはどのように新しいアプリです.Vueはセットアップです、エディタは消えるべきです、そして、現在、我々は空のウインドウを持っています.現在、ヘッダーはappの子です.Vueとルーティングにも責任があり、親コンポーネントと通信する方法が必要です.
App.vue
Header.vue
これはアプリケーションの子としてヘッダーがどのように見えるかです.vue、emitは、子要素が親にシグナルを送ることができ、親がシグナルをキャッチすることができます.我々は家、エディタ、およびジョブボードを持っているヘッダーでは、我々はアプリに信号を送信するためにこれらの3つのヘッダーのいずれかをクリックして欲しい.ボタンをクリックしたので、アプリをクリックした.Vueは関連するコンポーネントを表示します.
しかし、VUEから直接エディタコンポーネントを表示したくない.アプリケーションは、テンプレートを削除するように、テンプレートを削除するようにテンプレートを管理する必要がありますので、エディタは、管理コンポーネントの子、最終的には、このように構造が表示されます
App.vue
Header.vue
Home.vue
EditorManage.vue
Editor.vue
他の2つのコンポーネントのホームを作成し、コンポーネントフォルダ内で管理(EditorManager)、我々はすでにエディタを持っています.VUE我々はコンポーネントを管理するから移動します.ヘッダに戻る
<template>
<div class="header">
<div>
<h1>Logo</h1>
</div>
<nav>
<ul>
<!-- emitting a signal called Header, with a prop -->
<li @click="$emit('Header', 'Home')" >Home</li>
<li @click="$emit('Header', 'Editor')">Editor</li>
<li>Job Board</li>
</ul>
</nav>
</div>
</template>
<script>
export default {
name: "Header"
}
</script>
今のところ、我々は空のコンポーネントであり、この記事のための私達の焦点を管理するセットアップホームemitがちょうど関数であるのを見ることができるように、最初の変数「ヘッダー」はシグナルの名前です、そして、親コンポーネントはそれが火であるときはいつでも、この名前を使って信号を捕えます.
シグナル名が通常のパラメータに続くと、この場合、文字列を渡します
"$emit('Header', 'Home')"
私たちは基本的な色をコンポーネントにスタイルを使用します、ちょうど私たちが何をしているかを見ることができるように、私が以前のポストで言及したように、私はCSSをそれほど説明しません.ヘッダ用のCSS
<template>
....
</template>
<script>
export default {
name: "Header"
}
</script>
//css
<style scoped>
.header {
display:flex;
justify-content: space-between;
color: white;
background-color: black;
margin-bottom: 2em;
}
.header h1 {
padding-left: 1em;
}
.header nav ul {
display: flex;
margin: 1em 3em;
}
.header nav ul li {
padding: 1em 2em;
list-style: none;
}
li:hover{
cursor: pointer;
}
</style>
これは基本的なスタイルをシグナルのキャッチとハンドリング
アプリで.Vueはヘッダー信号を処理します、それは非常に簡単です、あなたはPropのような発射成分の信号の名前を通過して、定義して、信号を処理するために機能を割り当てます、あるいは、信号が発射されるとき、実行するために
@name-of-the-signal = "handlingFunction"
アプリで.Vue<template>
<!-- handling the signal fired by heard, which executes navigate() -->
<Header @Header="navigate"/>
</template>
vueはdataを使ってdataを返します.data ()はdataを使ってオブジェクトを返します.このデータはコンポーネントの状態として考え、コンポーネントのどこかにアクセスできます.Paramルートをナビゲート(ルート)関数に渡すと、ルートはEMIT関数で渡された値と等しくなります.
</template>
<script>
import Header from "./components/Header.vue";
export default {
name: "App",
components: {
Header
},
methods: {
navigate(route){
this.display = route
}
},
data(){
return{
// has a default value of Home, so on enter the app always show the home component
display: "Home"
}
}
};
</script>
ホームをインポートし、アプリケーションにコンポーネントを管理します.Vue
<script>
import Header from "./components/Header.vue";
import Home from "./components/Home.vue";
import Manage from "./components/EditorManager.vue";
export default {
name: "App",
components: {
Header,
Home,
Manage
},
...
};
</script>
表示varを更新するたびに、テンプレートで条件付きルーティングを設定しましょう.ユーザーがナビゲートしているという意味で、コンポーネントは更新されますアプリで.Vue
<template>
<div class="container">
<!-- header is always rendered -->
<Header @Header="navigate"/>
<!-- Manage will render if the display var === string Editor -->
<div v-if="display === 'Editor'">
<Manage/>
</div>
<!-- so does home, this is called conditional rendering, v-if same as if -->
<div v-if="display === 'Home'">
<Home/>
</div>
</div>
</template>
私たちは、アプリ.Vueは完了です.あなたは今“ルート”、または明示的に論理的にレンダリングする必要があります
コンポーネントの管理
で編集します.Vue
デフォルトの設定
<template>
<div>
</div>
</template>
<script>
export default{
name: "Manage"
}
</script>
<style scoped>
</style>
まず、新しいテンプレートを追加する方法を必要とする、我々は、フローティングアクションボタン(Fab)を使用して、右下の場所、OnClickそれは、タイトルと字幕のサブタイトルを埋めるためにモーダルを開きます保存、また、それは同じボタンを閉じて同じボタンを開きます.最初にモーダルコンポーネントを作成し、ファイルaddtempを呼び出して、テンプレートを追加し、コンポーネント自体を追加し、エディタの管理者にインポートし、以下のようにクラスモードでdivの内部で宣言すると、以下に示すように、data ()関数が必要です
<template>
<div class="modal" v-if="showModal">
<!-- addTemplate is a signal coming from the Add component -->
<Add @addTemplate="add"/>
</div>
</template>
<script>
import Add from "./AddTemp.vue"
//import the editor also
import Ed from "./Editor.vue"
export default{
name: "Manage",
components: {
Add,
Ed
}
}
</script>
data ()
...
export default{
name: "Manage",
components:{
...
},
data(){
return{
showModal: false,
}
},
}
のモードを切り替えるには、ボタンを作成してみましょう
<template>
<div>
<div class="fab" @click="toggleModal">
// show add when modal is closed
<label v-if="!showModal">
add
</label>
//show close when modal is open
<label v-if="showModal">
close
</label>
</div>
</div>
<div class="modal" v-if="showModal">
....
</div>
</template>
<script>
....
</script>
<style scoped>
/*place the fab bottom right and make it black */
.fab{
position: absolute;
padding: 1em;
background: black;
color: white;
bottom: 0;
right: 0;
margin: 1em;
border-radius: 30px;
/* right: 100%; */
}
/* expand the fab on hover */
.fab:hover {
transition : transform 200ms ease-out;
transform: scale(1.1, 1.2)
}
/* styles the modal, center it, give a box-shadow */
.modal {
position: absolute;
top: 25%;
width: 50%;
transform: translateX(50%);
display: flex;
justify-content: center;
box-shadow: 15px 15px 53px rgb(243, 244, 246);
border-radius: .5em;
max-height: 30em;
background: lightblue;
}
</style>
のロジックを追加しましょう
<script>
export default{
...,
methods: {
toggleModal(){
//make showModal the opposite of itself
//this will toggle the modal
this.showModal = !this.showModal
},
}
}
</script>
ここでaddtempファイルを開き、デフォルトのタグで入力します.テンプレートは、タイトルと字幕を受け入れる簡単なフォーム
<template>
<div>
<h4>Add Template</h4>
<div class="form">
<label>Title</label>
<input v-model="title"/>
<hr>
<label>SubTitle</label>
<input v-model="SubTitle"/>
// submit the form by emitting a signal (the signal will be emitted in the addTemplate() function)
<button @click="addTemplate()">Add</button>
</div>
</div>
</template>
V - Modelは、制御された要素と呼ぶものを作成します.単純に、ある状態にバインドされた要素を変更すると、コンポーネントが変更されます.入力では、data ()関数で定義するtitleとsubtitleをバインドします.
<script>
export default{
name: "Add",
data(){
//state(bound to the input elements)
return {
title: "",
SubTitle: ""
}
}
</script>
データを準備し、管理するためにシグナリングテンプレートを保存することができます
<script>
export default{
name: "Add",
data(){
...
},
methods: {
addTemplate(){
// get the form data
const temp = {
title: this.title,
SubTitle: this.SubTitle
}
//signal and give EditorManager the temp data
this.$emit("addTemplate", temp)
},
}
</script>
<style scoped>
.form{
width: 100%;
display: grid;
gap: .5em;
}
.form input{
border: 2px solid black;
width: 100%;
height: 22px;
}
.form button{
margin: 1em;
}
</style>
エディタマネージャーのシグナルとtempデータの取り扱い
<script>
...
//we will define these methods shortly
import {persist} from "../utillity/localPersist"
import {getTemps} from "../utillity/localPersist"
export default{
name: "Manage",
...,
methods: {
add(template){
console.log(template)
// creating a numeric id
template.id = this.templates.length + 1;
// adding the new template to the existing ones
this.templates = [...this.templates, template]
// we will define shortly persist the data to localstorage(browser store)
persist(this.templates)
},
}
}
</script>
ユーティリティでlocalpersistファイルを作成し、次の機能を追加します
// persist data
export function persist(templates){
try {
// persist templates with key templates, and we are stringifying the templates because localstorage can only store strings
localStorage.setItem("templates", JSON.stringify(templates))
} catch (error) {
console.log(error)
}
}
// get template data
export function getTemps(){
// get string data and parsing back to object
return JSON.parse(localStorage.getItem("templates"))
}
テンプレートデータを永続化するには、作成したメソッドを使用して保存したテンプレートを取得できます.エディタで
export default{
name: "Manage",
data(){
...,
templates: []
},
methods: {
....
//way to delete templates
del(id) {
// del a template given an id
this.templates.splice(id-1, 1)
// save the new data
persist(this.templates)
},
}
created(){
// if not undefined || null
if(getTemps()){
// asigning templates to templates[]
this.templates = getTemps();
}
}
テンプレートとセットアップ、必要なボタンを視覚化しましょう編集長
<template>
<div>
<div class="templates">
<!--looping over templates -->
<!--:key - unique -->
<div v-for="template in templates" :key="template.title" class="template">
<div class="temp__text">
<h2>{{template.title}}</h2>
<h3>{{template.SubTitle}}</h3>
</div>
// each template controls
<div class="actions">
// will not implement in this article
<button @click="edit">Edit</button>
<button @click="del(template.id)">Del</button>
// open Ed to create the specified template
<button @click="openEditor(template)">Editor</button>
</div>
</div>
</div>
<div class="fab">
....
</div>
</div>
<div class="modal" ..>
....
</div>
</template>
テンプレート用のCSS
.template {
display: grid;
grid-template-columns: 50% 50%;
color: lightblue;
}
.temp__text {
display: flex;
padding: .5em;
justify-content: space-around;
}
.actions{
display:flex;
align-items: center;
}
.actions button {
padding: .5em 1em;
/* height: 1.5em; */
margin-left: 1em;
background: black;
color: white;
border-radius: 15px;
}
.actions button:hover {
transition: tranform 200ms ease-out;
transform: scale(1.1, 1.2);
}
エディタを開くセットアップ
<template>
//v-if="!showEditor" === show the templates only when editor is closed
<div v-if="!showEditor">
<div class="templates">
....
</div>
<div class="fab">
...
</div>
</div>
<div class="modal" v-if="showModal">
...
</div>
<div v-if="showEditor">
// showing editor, passing a boud props :data(which is the selected template)
//@back signals back(when clicking a back button on Ed to close the Editor)
<Ed @back="closeEd()" :data="temp"/>
</div>
</template>
<script>
export default{
...,
data(){
return {
...,
showEditor: false,
temp: undefined,
}
},
methods: {
...,
openEditor(template){
// if the modal is opened close it
if(this.showModal){
this.toggleModal()
}
// the :data prop passed to Ed
this.temp = template;
// show the editor
this.showEditor = true;
},
// on signal back button on Ed close the editor
closeEd(){
window.editor = undefined;
this.showEditor = false;
},
}
}
これはすべて新しいコンポーネントのためです.ホームコンポーネントについては、あなたが好きなものを作ることができる、私のためのWebアプリを使用する方法については簡単なチュートリアルです
エディタで.Vue少し変わった
まず最初に、追加されます:クラスEditorToolsとUPDATE小道具のdivの下の後ろのボタンは、タイプオブジェクト(選択されたテンプレートである)の支柱データを取るために
<template>
<div class="editorTools">
..
</div>
<!--emit signal back which closes editor, back to manager -->
<button @click="$emit('back')" >Back</button>
<!-- make the data prop text of h1 element(for now)-->
<h1>{{ data }}</h1>
</template>
<script>
export default{
...,
props:{
data: Object
},
methods: {
save: function(){
window.editor.save().then((data)=> {
// publishing the data to the server
let newB = {
id: this.data.id,
title: this.data.title,
subtitle: this.data.SubTitle,
data
}
// stringify
let strData = JSON.stringify(newB)
console.log(strData)
console.log(newB)
// posting to the local our simple save the published data
fetch(`http://localhost:3000/temp/new/${strData}`, {method: "POST"}).then(res => {
console.log(res.text().then(data => console.log(data)))
})
})
}
}
}
</script>
そして、それは今のところ、しかし、1つの最後のことに気づいた場合は、イメージを失敗してエディタを公開すると、ブラウザが許可されていないので、Base 64文字列が長いので、我々はイオンの前に、次の記事で解決するために、私はまだもう少しそれについて研究し、効率的な方法を見つける必要があります.今のところは、テキストであり、それを発行するテンプレートを書くことができるため、ローカルサーバーが対応します.
私はローカルサーバーにいくつかの変更を行いました.
const express = require("express")
const jsonServer = require("json-server")
const app = express()
let Templates = {}
const router = jsonServer.router("db.json")
const middlewares = jsonServer.defaults()
const server = jsonServer.create()
server.use(middlewares)
server.get('/home', (req, res) => {
res.jsonp({ user: 'tj' });
})
server.get("/temp/:id", (req, res)=> {
let {id} = req.params
let getted = Templates[id]
console.log(getted)
res.jsonp({data: getted})
})
server.post("/temp/new/:data", (req, res)=> {
let {data} = req.params
data = JSON.parse(data)
Templates[data.id] = data
console.log(Templates)
console.log(data.data.blocks[0].data.img)
res.status(200).jsonp(Templates);
} )
// router.render = (req, res) => {
// res.jsonp({
// body: res.locals.data
// })
// }
server.use(router)
server.use(jsonServer.bodyParser)
server.use((req, res, next) => {
if (req.method === 'POST') {
req.body.createdAt = Date.now()
}
// Continue to JSON Server router
next()
})
server.listen(3000, ()=> {
console.log(`listening on port ${3000}`)
})
すべてのコードアプリ.Vue
<template>
<div class="container">
<Header @Header="navigate"/>
<div v-if="display === 'Editor'">
<!-- <Ed msg="Editor" /> -->
<Manage/>
</div>
<div v-if="display === 'Home'">
<Home/>
</div>
</div>
</template>
<script>
// import Ed from "./components/Editor.vue";
import Header from "./components/Header.vue";
import Home from "./components/Home.vue";
import Manage from "./components/EditorManager.vue";
export default {
name: "App",
components: {
Header,
Home,
Manage
},
methods: {
navigate(route){
this.display = route
}
},
data(){
return{
display: "Home"
}
}
};
</script>
<style scoped>
.container{
padding: .4em 1em;
}
</style>
ヘッダ.Vue
<template>
<div class="header">
<div>
<h1>Logo</h1>
</div>
<nav>
<ul>
<li @click="$emit('Header', 'Home')" >Home</li>
<li @click="$emit('Header', 'Editor')">Editor</li>
<li>Job Board</li>
</ul>
</nav>
</div>
</template>
<script>
export default {
name: "Header"
}
</script>
<style scoped>
.header {
display:flex;
justify-content: space-between;
color: white;
background-color: black;
margin-bottom: 2em;
}
.header h1 {
padding-left: 1em;
}
.header nav ul {
display: flex;
margin: 1em 3em;
}
.header nav ul li {
padding: 1em 2em;
list-style: none;
}
li:hover{
cursor: pointer;
}
</style>
エディトマネージャー.Vue
<template>
<div v-if="!showEditor">
<div class="templates">
<div v-for="template in templates" :key="template.title" class="template">
<div class="temp__text">
<h2>{{template.title}}</h2>
<h3>{{template.SubTitle}}</h3>
</div>
<div class="actions">
<button @click="edit">Edit</button>
<button @click="del(template.id)">Del</button>
<button @click="openEditor(template)">Editor</button>
</div>
</div>
</div>
<div class="fab" @click="toggleModal">
<label v-if="!showModal">
add
</label>
<label v-if="showModal">
close
</label>
</div>
</div>
<div class="modal" v-if="showModal">
<Add @addTemplate="add"/>
</div>
<div v-if="showEditor">
<Ed @back="closeEd()" :data="temp"/>
</div>
</template>
<script>
import Add from "./AddTemp.vue"
import Ed from "./Editor.vue"
import {persist} from "../utillity/localPersist"
import {getTemps} from "../utillity/localPersist"
export default {
name: "Manage",
components: {
Add,
Ed
},
data(){
return{
showModal: false,
showEditor: false,
temp: undefined,
templates: []
}
},
methods:{
toggleModal(){
this.showModal = !this.showModal
},
closeEd(){
window.editor = undefined;
this.showEditor = false;
},
add(template){
console.log(template)
template.id = this.templates.length + 1;
this.templates = [...this.templates, template]
persist(this.templates)
this.templates.forEach(val => {
console.log(val.title)
})
},
del(id) {
this.templates.splice(id-1, 1)
persist(this.templates)
},
edit(){
},
openEditor(template){
if(this.showModal){
this.toggleModal()
}
this.temp = template;
this.showEditor = true;
}
},
created(){
console.log(getTemps())
if(getTemps()){
console.log("not und")
this.templates = getTemps();
}
}
}
</script>
<style scoped>
.fab{
position: absolute;
padding: 1em;
background: black;
color: white;
bottom: 0;
right: 0;
margin: 1em;
border-radius: 30px;
/* right: 100%; */
}
.fab:hover {
transition : transform 200ms ease-out;
transform: scale(1.1, 1.2)
}
.modal {
position: absolute;
top: 25%;
width: 50%;
transform: translateX(50%);
display: flex;
justify-content: center;
box-shadow: 15px 15px 53px rgb(243, 244, 246);
border-radius: .5em;
max-height: 30em;
background: lightblue;
}
.template {
display: grid;
grid-template-columns: 50% 50%;
color: lightblue;
}
.temp__text {
display: flex;
padding: .5em;
justify-content: space-around;
}
.actions{
display:flex;
align-items: center;
}
.actions button {
padding: .5em 1em;
/* height: 1.5em; */
margin-left: 1em;
background: black;
color: white;
border-radius: 15px;
}
.actions button:hover {
transition: tranform 200ms ease-out;
transform: scale(1.1, 1.2);
}
.templates{
}
</style>
addtemp .Vue
<template>
<div>
<h4>Add Template</h4>
<div class="form">
<label >Title</label>
<input v-model="title"/>
<hr>
<label>SubTitle</label>
<input v-model="SubTitle"/>
<button @click="addTemplate()">Add</button>
</div>
</div>
</template>
<script>
export default {
name: "Add",
props: {
},
data(){
return {
title: "",
SubTitle: ""
}
},
methods: {
addTemplate(){
const temp = {
title: this.title,
SubTitle: this.SubTitle
}
this.$emit("addTemplate", temp)
},
}
}
</script>
<style scoped>
.form{
width: 100%;
display: grid;
gap: .5em;
}
.form input{
border: 2px solid black;
width: 100%;
height: 22px;
}
.form button{
margin: 1em;
}
</style>
それは今のところ、読書のおかげです.次に、サーバーの問題を修正しますが、私はあなた自身でそれを修正することをお勧めしますし、イオンの部分を実装します
質問やHiは、最良の方法を言うにはTwitterです:
Reference
この問題について(イオンフレームワークから市場(よく並べ替え)パート1), 我々は、より多くの情報をここで見つけました https://dev.to/sfundomhlungu/from-the-ionic-framework-to-market-well-sort-of-part-3-26ppテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol